低频数字相位测量仪.docx
《低频数字相位测量仪.docx》由会员分享,可在线阅读,更多相关《低频数字相位测量仪.docx(23页珍藏版)》请在冰点文库上搜索。
低频数字相位测量仪
一、设计任务和技术要求
1.1设计内容
设计制作一个低频数字相位测量仪,要求使用单片机和FPGA来共同实现,FPGA完成测量时间差,而单片机完成数据的读取、键盘控制和显示等功能。
1.2设计要求
1)频率范围:
20Hz~20kHz。
2)相位测量仪的输入阻抗:
≧100kΩ。
3)允许两路输入正弦信号峰峰值可分别在1~5V变化。
4)相位测量绝对误差≦2°。
5)具有频率测量及数字显示功能。
6)相位差数字显示,分辨力为0.1°。
7)主芯片:
Altera的FLEX10K10。
8)要求扩展键盘和显示接口电路,可以进行键盘控制以及显示等功能。
二、系统设计方案
2.1方案论证
根据系统的设计要求,本系统可分为三大基本组成部分:
1.数据采集电路
数据采集电路主要是运用FPGA/CPLD采集两个同频待测正弦信号的频率和相位差所对应的时间差。
2.数据运算控制电路
数据运算控制电路主要是运用单片机读取FPGA/CPLD采集到的数据,并根据这些数据计算待测正弦信号的频率及两路同频正弦信号之间的相位差。
3.数据显示电路
数据显示电路是通过功能键切换用LCD液晶模块显示出待测信号的频率和相位差。
4.整形电路
由于FPGA对脉冲信号比较敏感,而被测信号是周期相同、相位不同的两路正弦波信号,为了准确地测出两路正弦波信号的相位差及其频率,我们需要对输入波形进行整形,使正弦波变成方波信号,并输入FPGA进行处理。
整个系统的总体原理框图如图2.1所示。
AINSAIN
BINSBIN
图2.1系统原理框图
2.2程序设计框图
图2.2程序设计流程图
三、硬件电路图的设计与分析
3.1FPGA数据采集电路
图3.1数据采集电路
FPGA数据采集电路的功能就是实现将待测正弦信号的周期、相位差变为19位的数字量。
根据系统的总体设计方案,FPGA数据采集电路的输入输出信号有:
CLK——系统工作时钟信号输入端;
A,B——两路被测信号输入端;
EN——单片机发出的传送数据使能信号;
RSEL——单片机发出的传送数据类型信号;
DATA[18..0]——FPGA到单片机的数据输出口。
FPGA数据采集电路测量正弦波信号频率的原理是:
在正弦波信号整形后得到的方波信号的一个周期为T秒的数据采样信号进行计数,其计数结果乘以1/T,就是被测正弦波信号的频率,单位为Hz。
测量正弦波信号周期原理是:
在正弦波信号整形后得到的方波信号的一个周期内对周期为T秒的数据采样信号进行计数,其计数结果乘以T秒,就是被测正弦波信号的周期,单位为秒。
测量两个同频正弦波信号的相位差,关键是要测出两个同频正弦波信号起点之间的时间差△t,若△t测出,则根据△φ=△t×360°/t即可求出相位差△φ,因此其测量原理与测量正弦波信号周期的原理相似。
本设计采用20MHz的高频晶体振荡源,由FPGA内部的分频模块对20MHz信号进行二分频,得到10MHz的数据采样信号,其采样周期为0.1us。
为了实现中低频测量精度的要求,我们可采用10MHz的信号来循环计数被测信号的周期和两个同频正弦波信号的相位差所对应的时间差值,时间单位为0.1us。
也就是说,计数周期和相位差所对应的时间差值的精度是0.1us。
利用被测信号来刷新采样计数,在20Hz时,刷新频率可以精确到10Hz,20kHz时达到10kHz,可以实现高频多测量,低频少测量的效果,时间计数精确可靠,为后面单片机的数据处理提供了稳定、可靠的数据源。
3.2单片机数据运算控制
单片机数据运算控制电路的功能就是负责读取FPGA/CPLD采集到的数据,并根据这些数据计算待测正弦信号的频率及同频正弦信号之间的相位差,同时通过功能键切换,显示出待测信号的频率和相位差。
为了达到系统所要求的精度,在计算时为了保证不丢失数据,我们采用了扩大数据倍数,定点取数的方法。
在计算频率ƒ和相位差△φ时,ƒ和△φ分别扩到了10000000倍和10倍,即ƒ=10000000/t,△φ=360×10×△t/t。
然后定点取数值,在单片机完成的计算中,当t=Tmax=T20kHz,△t→Tmax时,数据位数→20位,因此采用了多字节乘法,保证了数据的计算准确。
单片机数据运算控制电路的软件设计思路是,单片机不断地从FPGA读取信号的周期和a、b信号相位差所对应的时间差,读取数据后进行有关计算,并通过转换后,送出给显示模块,实现频率和相位差的显示。
3.3数据显示电路
整个系统硬件电路中,显示电路用LCD液晶显示,需要单片机提供三个控制管脚,分别是P3.5,P3.6,P3.7。
用两个按键切换频率和相位差数据,分别是P1.6,P1.7。
其中按键部分是用查询去抖的方式完成,LCD显示模块运用串口方式,这样节省了I/O口,三个控制管脚分别控制忙碌状态、串口片选、数据传输口。
如图3.2。
图3.2数据显示电路
四、程序设计与调试
4.1FPGA采集电路设计
FPGA数据采集电路可设计成五个模块,他们分别是:
时钟信号分频模块FPQ,测量控制信号发生模块KZXH,被测信号有关时间检测模块SJJC,数据锁存模块SJSC和输出选择模块SCXZ,整个系统组成框图如图4.1。
1、时钟信号分频模块FPQ的作用是:
将输入的20MHz的信号分频成10MHz的测控基准时钟信号CLKF。
2、测量控制信号发生模块KZXH的作用是:
根据两路被测信号整形后的方波信号CLKAA和CLKBB,产生有关测控信号,包括时间检测使能信号ENA,时间检测清零信号CLRA,锁存频率数据控制信号LOADA,锁存两路被测信号相位差数据控制信号CLB。
3、被测信号频率和相位差数据检测模块SJJC的作用是:
在控制信号ENA和CLRA的控制下,对测控基准时钟信号CLKF进行计数和清零,以便获取有关频率和相位差数据。
4、数据锁存模块SJSC的作用是:
在LOADA的上升沿将频率数据锁存在DATAA中,在CLB的下降沿时将相位差数据锁存在DATAB中。
5、输出选择模块SCXZ的作用是:
根据单片机发出的控制信号数据传送使能信号EN和输出数据类型选择信号RSEL,将被测信号频率数据或相位差数据输出。
图4.1FPGA整个系统框图
4.2单片机程序设计
单片机在获取FPGA的数据时,开始的是一般的读取指令MOV指令,从单片机的P0,P2,P3口分别读入数剧,组合为一个19位的二进制数据,通过控制口线P1.6、P1.7控制FPGA释放数据。
经过多次测试,采用这种方式获得了比较好的效果。
单片机读取FPGA数据的程序流程图如4.2。
单片机从FPGA读取信息后,对信息进行计算,算出信号a的频率,其流程图如4.3。
由于a、b信号是两路同频不同相的正弦波信号,因此经过整形电路后形成频率相同,时间上不重合的两路信号,这样,FPGA可以计数出两路信号的时间差从而可以计算出a、b信号的相位差,其流程图如4.4。
图4.2
图4.3图4.4
最后单片机需要将信号送到输出端显示出来,即单片机通过显示子程序将信息送到显示电路显示出来,程序流程图如4.5
图4.5
4.3结果与分析
1)FPGA数据采集电路波形仿真如图4.6所示
图4.6FPGA波形仿真图
分析:
仿真波形的CLK的周期是0.25us,A、B信号的周期都是5us,CLK经过2分频后,在A、B的一个周期内对CLK的方波脉冲计数应该是10,也就是16进制的0A。
见图中的DATAA恰好是0A,A、B信号是反相的,因此相位差计数应该是整个周期的一半,即图中的DATAB为5。
RSEL、EN为使能控制信号,当EN为高电平时才输出数据,RSEL是控制输出频率和相位差数据的,当其为低电平时输出频率数据,为高电平时输出相位差数据,见图中的DATA为最后的输出信号。
2)单片机部分。
在本系统的设计中,为了达到系统所要求的精度,必须保证数据计算处理时不丢失数据,我们采用了扩大数据倍数,定点取数的方法,在计算频率ƒ和相位差△φ时,ƒ和△φ分别扩大到了10000000倍和10倍,即ƒ=10000000/t,△φ=360×10×△t/t,然后定点取数值,在单片机完成的计算中,当t=Tmax=T20kHz,△t→Tmax时,数据位数→20位,因此采用了多字节乘法,保证了数据的计算准确。
3)测量结果如表4.3
表4.3
序号
A、B实际频率
AB实际相位差
测量频率
测量相位差
1
20HZ
180度
20HZ
179.5度
2
200HZ
180度
198HZ
177.0度
3
2000HZ
90度
1995HZ
88.6度
4
20000HZ
90度
19988HZ
86.2度
分析:
由于整形电路的存在,输入的脉冲是高频信号,难免会产生误差,但本系统用FPGA采集数据,因此误差不大。
4)系统扩展思路
本次设计可以添加一个数字式移相信号发生器,用以产生相位测量仪所需的输入正弦信号,这样,输出频率可以预置。
具体框图如4.8
图4.8数字式移相信号发生器电路图
五、总结
低频数字相位检测仪是一个检测低频信号相位差和频率的系统,主要用FPGA进行数据采集,通过单片机的运算控制,最终在LCD液晶模块上显示结果。
通过这次课程设计,我们收获了许多。
首先,我们对FPGA有了更深的认识,在以前的课程设计中,我们主要采用人工布线的方法进行电子电路设计,这种方法不但麻烦,还容易出错,一旦出现错误特别不容易检查,最后只好重新连线,浪费了很多时间。
而通过这次用VHDL语言进行电路设计,不仅设计起来方便,而且通过波形仿真还可以验证结果是否正确,以及检查在哪出现错误。
最后将程序下载到一个芯片中就可以完成设计内容。
因此使用起来特别方便。
并且对一些高频信号来说误差较小。
其次,在对单片机控制程序的编写我们采用了汇编语言,由于采集的数据比较大,对其运算时用到了多字节乘除法,和BCD码的转换。
其中,我们都采用子程序来编写,这样不但思路清晰,还有利于我们分工合作,节省了很多时间。
不过程序代码很长。
我们发现如果用C语言编程会十分方便,因为许多运算的程序如果用C编写只需要一条语句,而用汇编却用了一个很长的子程序。
所以,通过这次试验我们也体会到了C语言的方便之处,这也是我们将要学习的地方。
最后,键盘和显示部分,由于我们只用到两个键,所以编程时采用查询方式,十分简单。
显示模块是液晶显示,不仅可以显示数字,还可以显示符号和汉字,通过使用这个模块,我们又学到了一个新的模块的用法,同时也增强了学习新东西的能力。
这次实习,我们受益匪浅,并且对本专业更加喜欢,所以我们会在以后的学习中更加努力,争取学到更多的知识。
参考文献
[1]谭会生·EDA技术综合应用实例与分析·西安电子科技大学出版社·2004:
248-265.
[2]潘松·EDA技术实用教程·第二版·科学出版社·2005:
293-298.
附录
一、程序清单
1.单片机程序
DATA2HEQU43H
DATA3EQU44H
DATA33EQU45H
AD0EQU30H
AD1EQU31H
AD2EQU32H
AD3EQU33H
AD4EQU34H
AD5EQU35H
AD6EQU36H
ADAEQU4FH
ADBEQU5FH
ADCEQU4DH
ADEEQU5DH
DSELBITP1.7
DSNBITP1.6
KEY1BITP3.3
KEY2BITP3.4
EBITP3.7
SIDBITP3.6
CSBITP3.5
ORG4000H
LJMPSTART
ORG4100H
START:
LJMPMAIN
MAIN:
NOP
LCALLDU;从FPGA读入频率和相位差分别对应的数据
LCALLZHUN1;调用除法准备周期
LCALLDIVVV;调用除法程序
MOV32H,#0H
MOV33H,4DH
MOV34H,4EH
MOV35H,4FH;32H,33H,34H,35H存放频率数据,32H是高位
LCALLBCDST;将频率数据转化为BCD码,便于显示
MOV67H,3DH
MOV68H,3EH;频率BCD码存放在67H,68H,69H中,67H是高位
MOV69H,3FH
LCALLZHUN2;调用乘法准备周期
LCALLMULLL;调用乘法程序
MOV4AH,5AH
MOV4BH,5BH
MOV4CH,5CH
MOV4DH,5DH
MOV4EH,5EH
MOV4FH,5FH;将进行乘法之后的数据暂存
MOV5FH,DATAL
MOV5EH,DATAH
MOV5DH,DATA3;再取频率初始数据
LCALLDIVVV;调用除法程序
MOV32H,#0
MOV33H,4DH
MOV34H,4EH
MOV35H,4FH;33H,34H,35H存放相位差数据33H是高位
LCALLBCDST;调用BCD码转换程序
MOV70H,3EH
MOV71H,3FH;相位差BCD码存放在70H,71H中,70H是高位
K1:
JNBKEY1,KK1
K2:
JNBKEY2,KK2
LJMPMAIN
KK1:
LCALLDELAY
JNBKEY1,K11
LJMPK2
K11:
LCALLXIAN1
LJMPK2
KK2:
LCALLDELAY
JNBKEY2,KK3;键盘扫描,看两个键是哪个键按下从而
LJMPMAIN切换频率和相位差
KK3:
LCALLXIAN2
LJMPMAIN
DU:
CLRDEN;读数据子程序
CLRDSEL
SETBDEN
MOVA,P0
MOVDATAL,A
MOVA,P2
MOVDATAH,A
SETBDS1
MOVA,P3
ANLA,#00000111B
MOVDATA3,A;读频率数据放到44H,41H,40H中
CLRDEN
SETBDEN
SETBDSEL
MOVA,P0
MOVDATA2L,A
MOVA,P2
MOVDATA2H,A
MOVA,P3
ANLA,#00000111B
MOVDATA33,A;读相位差数据放到45H,43H,42H中
CLRDSEL
CLRDEN
RET
;2NBYTE/NBYTE=NBYTE,HEREN=3IN31H
;(4A,4B,4C,4D,4E,4FH)/(5D,5E,5FH)=(4D,4E,4F)
ZHUN1:
MOV5FH,DATAL;除法准备周期
MOV5EH,DATAH
MOV5DH,DATA3
MOV4FH,#80H
MOV4EH,#96H
MOV4DH,#98H
MOV4CH,#00H
MOV4BH,#00H
MOV4AH,#00H;10000000
RET
NOP
;NBYTESXMBYTES=N+MBYTESHEREN=3;M=3
;(4D,4E,4FH)*(5D,5E,5FH)=(5A--5FH)
ZHUN2:
MOV4DH,DATA33;乘法准备周期
MOV4EH,DATA2H
MOV4FH,DATA2L
MOV5DH,#00H
MOV5EH,#0EH
MOV5FH,#10H;3600
RET
NOP
NOP
NOP
;2NBYTE/NBYTE=NBYTE,HEREN=3IN31H
;(4A,4B,4C,4D,4E,4FH)/(5D,5E,5FH)=(4D,4E,4FH)
SHIL1:
MOVR2,AD0
MOVR0,#ADA
SHIL1B:
CLRC
SHILL:
MOVA,@R0
RLCA
MOV@R0,A
DECR0
DJNZR2,SHILL
RET
SUBMB:
MOVR2,AD0
MOVR0,#ADA
MOVR1,#ADB
SUBMBB:
CLRC
SUBMB1:
MOVA,@R0
SUBBA,@R1
MOV@R0,A
DECR0
DECR1
DJNZR2,SUBMB1
RET
NOP
NOP
NOP
RET
END
2.EDA程序清单
--控制信号模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYKZXHIS
PORT(A:
INSTD_LOGIC;
B:
INSTD_LOGIC;
ENA:
OUTSTD_LOGIC;
CLRA:
OUTSTD_LOGIC;
LOADA:
OUTSTD_LOGIC;
CLB:
OUTSTD_LOGIC);
ENDENTITYKZXH;
ARCHITECTURESJCJOFKZXHIS
SIGNALCLKA,CLKB:
STD_LOGIC;
SIGNALCLA:
STD_LOGIC;
SIGNALCB:
STD_LOGIC;
BEGIN
CLKA<=NOTA;
CLKB<=NOTB;
PROCESS(CLKA)
BEGIN
IFCLKA'EVENTANDCLKA='1'THEN
CLA<=NOTCLA;
ENDIF;
ENA<=CLA;
LOADA<=NOTCLA;
ENDPROCESS;
PROCESS(CLKB)
BEGIN
IFCLKB'EVENTANDCLKB='1'THEN
CB<=NOTCB;
ENDIF;
CLB<=CB;
ENDPROCESS;
PROCESS(CLKA,CLA)
BEGIN
IFCLKA='0'ANDCLA='0'THEN
CLRA<='1';
ELSE
CLRA<='0';
ENDIF;
ENDPROCESS;
ENDARCHITECTURESJCJ;
--分频模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYFPQIS
PORT(CLK:
INSTD_LOGIC;
CLKF:
OUTSTD_LOGIC);
ENDENTITYFPQ;
ARCHITECTURESJCJOFFPQIS
BEGIN
PROCESS(CLK)
VARIABLETEMP:
INTEGERRANGE0TO2;
VARIABLECL:
STD_LOGIC;
BEGIN
IFCLK'EVENTANDCLK='1'THEN
IFTEMP=1THEN
TEMP:
=0;CL:
='1';
ELSE
TEMP:
=TEMP+1;
CL:
='0';
ENDIF;
ENDIF;
CLKF<=CL;
ENDPROCESS;
ENDARCHITECTURESJCJ;
--时间检测模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYSJJCIS
PORT(CLKF:
INSTD_LOGIC;
CLRA:
INSTD_LOGIC;
DA:
OUTSTD_LOGIC_VECTOR(18DOWNTO0));
ENDENTITYSJJC;
ARCHITECTURESJCJOFSJJCIS
BEGIN
PROCESS(ENA,CLRA,CLKF)
VARIABLEDDA:
STD_LOGIC_VECTOR(18DOWNTO0);
BEGIN
IFCLRA='1'THEN
DDA:
=(OTHERS=>'0');
ELSEIFCLKF'EVENTANDCLKF='1'THEN
IFENA='1'THEN
DDA:
=DDA+1;
ENDIF;
ENDIF;
ENDIF;
DA<=DDA;
ENDPROCESS;
ENDARCHITECTURESJCJ;
--时间锁存模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYSJSCIS
PORT(DA:
INSTD_LOGIC_VECTOR(18DOWNTO0);
LOADA:
INSTD_LOGIC;
CLB:
INSTD_LOGIC;
DATAA:
OUTSTD_LOGIC_VECTOR(18DOWNTO0);
DATAB:
OUTSTD_LOGIC_VECTOR(18DOWNTO0));
ENDENTITYSJSC;
ARCHITECTURESJCJOFSJSCIS
BEGIN
PROCESS(CLB)
BEGIN
IFCLB'EVENTANDCLB='1'THEN
DATAB<=DA;
ENDIF;
ENDPROCESS;
PROCESS(LOADA)
BEGIN
IFLOADA'EVENTANDLOADA='1'THEN
DATAA<=DA;
ENDIF;
ENDPROCESS;
ENDARCHITECTURESJCJ;
--输出选择模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
ENTITYSCXZIS
PORT(DATAA:
INSTD_LOGIC_VECTOR(18DOWNTO0);
DATAB:
INSTD_LOGIC_VECTOR(18DOWNTO0);
RSEL:
INSTD_LOGIC;
EN:
INSTD_LOGIC;
DATA:
OUTSTD_LOGIC_VECTOR(18DOWNTO0));
ENDENTITYSCXZ;
ARCHITECTURESJCJOFSCXZIS
BEGIN
PROCESS(EN,RSEL)
BEGIN
IFEN='1'THEN
CASERSELIS
WHEN'0'=>DATA<=DATAA;
WHEN'1'=>DATA<=DATAB;
WHENOTHERS=>NULL;
ENDCASE;
ENDIF;
ENDPROCESS;
ENDARCHITECTURESJCJ;
二、原理图