学院: 专业: 班级: 姓名: 学号: 审阅老师: 评分:
1 / 21
目录
一、课程设计目的 ................................................................................. 3 二、设计任务 ......................................................................................... 3 三、功能要求与技术指标 ...................................................................... 3 四、数字频率计工作原理概述 .............................................................. 3 五.数字频率计实现方法 ...................................................................... 4 六.结论与误差分析............................................................................ 11 七.VHDL程序: ................................................................................. 12
2 / 21
一、课程设计目的
熟悉EDA工具,掌握用VHDL语言进行数字系统设计的基本方法和流程,提高工程实践能力。
二、设计任务
设计一数字频率计,用VHDL语言描述,用QuartusII工具编译和综合,并在实验板上实现。
三、功能要求与技术指标
1. 基本功能要求
(1) 能够测量出方波的频率,其范围50Hz~50KHz。 (2) 要求测量的频率绝对误差±5Hz。
(3) 将测量出的频率以十进制格式在实验板上的4个数码管上显示。 (4) 测量响应时间小于等于10秒。 以上(1)~(4)基本功能要求均需实现。
2. 发挥部分
(1) 提高测量频率范围,如10Hz~100KHz或更高、更低频率,提高频率
的测量绝对值误差,如达到±1Hz。
(2) 可以设置量程分档显示,如X1档(显示范围1Hz~9999Hz),X10档
(显示范围0.001KHz~9.999KHz),X100档(显示范围0.100KHz~999.9KHz)...可以自定义各档位的范围。量程选择可以通过按键选择,也可以通过程序自动选择量程。
(3) 若是方波能够测量方波的占空比,并通过数码管显示。 以上(1)~(3)发挥功能可选择实现其中的若干项。
四、数字频率计工作原理概述
1. 数字频率计简介
3 / 21
在电子技术中,频率是最基本的参数之一,并且与许多电参量的测量方案、测量结果都有十分密切的关系,因此频率的测量就显得更为重要。而数字频率计是采用数字电路制成的实现对周期性变化信号的频率的测量。
2. 常用频率测量方法:
方案一
采用周期法。通过测量待测信号的周期并求其倒数,需要有标准倍的频率,在待测信号的一个周期内,记录标准频率的周期数,这种方法的计数值会产生最大为±1个脉冲误差,并且测试精度与计数器中记录的数值有关,为了保证测试精度,测周期法仅适用于低频信号的测量。
方案二
采用直接测频法。直接测频法就是在确定的闸门时间内,记录被测信号的脉冲个数。由于闸门时间通常不是待测信号的整数倍,这种方法的计数值也会产生最大为±1个脉冲误差。进一步分析测量准确度:设待测信号脉冲周期为Tx,频率为Fx,当测量时间为T=1s时,测量相对误差为Tx/T=Tx=1/Fx。由此可知直接测频法的测量准确度与信号的频率有关:当待测信号频率较高时,测量准确度也较高,反之测量准确度也较低。
五.数字频率计实现方法
本文采用方案二直接测频法进行设计,具体实施方法如下:
1. 直接测频法:
采用一个标准的基准时钟,在单位闸门时间(1s)里对被测信号的脉冲数进行计数,即为信号的频率。由于闸门时间通常不是待测信号的整数倍,这种方法的计数值也会产生最大为±1个脉冲误差。
进一步分析测量准确度:设待测信号脉冲周期为Tx,频率为Fx,当
测量时间为T=1s时,测量相对误差为Tx/T=Tx=1/Fx。由此可知直接测频
4 / 21
法的测量准确度与信号的频率有关:当待测信号频率较高时,测量准确度也较高,反之测量准确度也较低。
2. 具体设计流程:
1). 基本功能部分:
(1). 原理概述:
1利用FPGA实验板的基准时钟50M分频产生一个1Hz的脉冲方○
波作为闸门信号;
2当待测信号的上升沿到来时,利用四个个十进制计数器(即 ○
最高能记到9999次数)对其上升沿进行计数;
3计数的同时不断把数锁存,并送到数码管显示部分显示; ○
4当1Hz闸门信号的上升沿到来时,对锁存送到显示部分的数 ○
据用十进制显示到四位数码管,一旦显示后就把四个计数器的值清零,计数器重新对待测信号上升沿计数并锁存,直到1Hz闸门信号的下个上升沿到来时在把这次闸门时间内记到的数据送去数码管显示。
○5如此循环,实现对不是固定频率的待测信号的频率每秒更新
1Hz闸门信号 1秒时间宽度 1锁存计数值,并送数码管显示 ○ 一次的功能。
(2)设计原理时序图:
待测信号
清零信号clr 2然后计数器清零clr=1,重新计数 ○ 5 / 21
2). 扩展功能部分: (1). 原理概述:
一、分档显示部分
如图所示显示的频率为25MHZ(25000.000HZ):
1在基本功能的计数部分增加至八个计数器(即最高能记到 ○
99.999999M次数)对待测信号上升沿进行计数;
2对记到的数据按优先级由最高位往低位判断,若第七位有进 ○
位,则表示第八个计数器有计数,故要锁存最高四位计数器 内容并送数码管显示,若为第六位数码管有进位,则显示次 高四位计数器内容,以此类推;
3判断相应的档位的同时给每个档位一个变量赋值,用于判断 ○
小数点的位置 。以KHZ为单位,则四位数码管最高能显示 9999Khz。
4若显示最高四位计数器内容(即是X10000档(10~99.99MHZ)), ○
由于已超出四位数码管显示范围,则可以用按键显示最低四位计数器内容,同时让DS1(千位)数码管小数点亮。
6 / 21
未按键时显示最高四位数字;
按住按键S5显示低四位数字
5若未超出四位数码管显示范围,则按照如下显示小数点: ○
X1000档(1~9999khz)只显示个位小数,
X100档(0.1~999.9khz)只显示十位小数点, X10档(0.01~99.99khz)只显示百位小数点, X10档(0.01~99.99khz)只显示百位小数点, X1档(0.001~9.999khz)只显示千位小数点。 显示效果如下图所示:
7 / 21
显示频率1953.13KHZ
也可按住按键S5显示其余低位
8 / 21
显示频率6.103HZ(误差±1HZ)
显示频率6HZ 二、占空比部分
1利用基准时钟产生一个10MHZ的频率用于标准计数信号; ○
2在1HZ闸门信号上升沿到来时,10MHZ计数信号开始计数, ○
9 / 21
同时在待测信号为高电平时,用七个计数器对10MHZ信 号的上升沿次数计数,低电平时不计数;
3当1HZ闸门信号的下个上升沿到来时,10MHZ计数信号刚 ○
好计数10M次(1s时间),此时取待测信号高电平期间 七个计数器的最高四位的数据锁存并送数码管显示,显 示时数码管DS2(百位)小数点亮,所得结果即为待测信号 的占空比(单位为%),如下图所示:
按下按键 S6显示占空比(50.00%)
(2). 测量占空比设计原理时序图
10 / 21
1Hz闸门信号 1秒时间宽度 3计数器清零clr=1,重新计数 ○待测信号 2高电平时才计数,并送数码管显示 ○标准计数信号10MHZ
1计上升沿次数10M次(1s时间) ○
六. 结论与误差分析
1. 频率测量部分:
(1). 结论:
能测到待测信号的频率范围理论上为1HZ~99.999999MHZ,实际测试时最高只用过25MHZ的频率进行测试,结果相差±1Hz,达到设计要求。
(2). 误差分析:
由于采用直接测频法,1S闸门时间通常不是待测信号的整数倍,因此计数值也产生最大为±1个脉冲误差。设待测信号脉冲周期为Tx,频率为Fx,当测量时间为T=1s时,测量相对误差为Tx/T=Tx=1/Fx。所以,直接测频法的测量准确度与信号的频率有关:当待测信号频率较高时,测量准确度也较高,反之测量准确度也较低。
2. 占空比测量部分:
(1). 结论:
高频时对占空比在5%~95%的待测信号测试误差为±0.5%,最高能测试到25MHZ的占空比;在低频时测量的占空比有较大误差。
11 / 21
(2). 误差分析: 由于1S闸门时间内用10MHZ的基准信号在待测信号的高电平是计数,故误差产生的原因有一下两点:
1待测信号进入闸门的状态随机(可能是高电平,也可能是低电平),所以○
对高频信号,测量到的占空比误差比较小;
对低频信号误差较为明显,若进出闸门的状态同为高电平,则在1S闸门时间内对高电平的状态就有多计数,结果偏高;若进出闸门的状态同为低电平,则在1S闸门时间内对高电平的状态就少计数,结果偏低。
2待测信号进入闸门的状态随机,且1S闸门时间通常不是待测信号的整数○
倍,以10MHZ信号作为基准信号计数10M次上升沿作为待测信号在1S时间内整数个周期的时间,本身只是个近似值,所以对高频时误差较小,低频时有较大误差。
七.VHDL程序:
--********************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all; entity frequency_meter is port(
clk ,d0,d1 :in std_logic; clkx :in std_logic;
wei :out std_logic_vector(3 downto 0); led :out std_logic_vector(7 downto 0) );
end entity frequency_meter;
--********************************************************
Architecture abc of frequency_meter is
signal led1, led2, led3, led4 :std_logic_vector(7 downto 0):=\"11000000\";
signal ge ,shi, bai, qian :integer range 0 to 10:=0; signal clk_1 :std_logic :='1'
signal clk_0, clk_1hz, clk_10m, freq12k : std_logic; signal temp : std_logic_vector(22 downto 0); begin
12 / 21
--**********p0**产生10mHZ频率*****************************
p0 : process(clk) is
variable counter0 :integer :=0; begin
if (clk'event and clk='1' ) then counter0:=counter0+1; if (counter0=25) then clk_0<=not clk_0; counter0:=0; end if; end if;
clk_10m<=clk_0; end process p0;
--************p1**产生1HZ频率*****************************
p1 : process(clk) is
variable counter1 :integer :=0; begin
if (clk'event and clk='1' ) then counter1:=counter1+1;
if (counter1=25000000) then clk_1<=not clk_1; counter1:=0; end if; end if;
clk_1hz<=clk_1; end process p1;
--************p2**分频出12k频率用于数码管位选扫频*********
p2 : process(clk) is begin
if (clk'event and clk='1' ) then temp<=temp+1; end if;
freq12k<=temp(11); --12207Hz end process p2;
--*************p3**主程序(显示,分档,占空比测量)************
p3 : process(clk,clk_1hz,clkx) is
13 / 21
variable counter2,counter3 :integer :=0;
variable aa,bb,cc,dd,ee,ff,gg,hh,za,zb,zc,zd,ze,zf,c,d,e,f:integer range 0 to 10:=0;
variable temp2,temp3,temp4,temp5:integer range 0 to 10:=0; variable dip0,dip1,dip2,dip3,dip4,dip5,dip6,dip7 :integer :=0; variable clr :integer:=0; begin
---------------**p3_1--计数显示**-----------------------------------
if(clkx'event and clkx='1')then aa:=aa+1; if(aa=10)then aa:=0; bb:=bb+1;
if(bb=10)then bb:=0; cc:=cc+1;
if(cc=10)then cc:=0; dd:=dd+1;
if(dd=10)then dd:=0;
temp2:=1;--------temp2 ee:=ee+1; if(ee=10)then ee:=0;
temp3:=1;--------temp3 ff:=ff+1; if(ff=10)then ff:=0;
temp4:=1;--------temp4 gg:=gg+1; if(gg=10)then gg:=0;
temp5:=1;--------temp5 hh:=hh+1; if(hh=10)then hh:=0; end if; end if; end if;
end if; end if;
14 / 21
end if; end if; end if;
-------------------**p3_2--分档显示**-------------------------------
if(d0='0')then----------按键按下显示占空比,否则显示频率---- ge<=c; shi<=d; bai<=e; qian<=f;
dip2:=1;------------只显示百位小数点------- elsif(d0='1')then if(temp5=1)then--------X10000档(~99.999999mhz)----------- -------超出四个数码管显示范围,可以按键显示--- ge<=ee;---------最低四位,同时只显示千位小数点----- shi<=ff; bai<=gg; qian<=hh; dip5:=1;
elsif(temp4=1)then------X1000档(1~9999khz)只显示个位小数点 ge<=dd; shi<=ee; bai<=ff; qian<=gg; dip4:=1;
elsif(temp3=1)then----X100档(0.1~999.9khz)只显示十位小数点 ge<=cc; shi<=dd; bai<=ee; qian<=ff; dip3:=1;
elsif(temp2=1)then----X10档(0.01~99.99khz)只显示百位小数点 ge<=bb; shi<=cc; bai<=dd; qian<=ee; dip2:=1;
else --------X1档(0.001~9.999khz)只显示千位小数点 ge<=aa; shi<=bb; bai<=cc; qian<=dd;
dip1:=1;
15 / 21
end if; end if;
------------------**p3_3--显示低位**--------------------------------
if(d1='0')then
dip6:=1;------小于X10000档的低四位不显示小数点---- if(dip5=1)then ge<=aa; shi<=bb; bai<=cc; qian<=dd;
dip6:=0;------X10000档的高位不显示小数点------- dip7:=1;------X10000档的低位千位显示小数点----- elsif(dip4=1)then ge<=0; shi<=aa; bai<=bb; qian<=cc;
elsif(dip3=1)then ge<=0; shi<=0; bai<=aa; qian<=bb;
elsif(dip2=1)then ge<=0; shi<=0; bai<=0; qian<=aa; else
ge<=0; shi<=0; bai<=0;
qian<=0; end if;
elsif(d1='1')then dip6:=0; dip7:=0;
end if;
end if;
--------------------**p3_4---占空比**-------------------------------
16 / 21
if(clk_10m'event and clk_10m='1')then counter2:=counter2+1;
if(counter2=1000000)then---10mhz频率,计数到1000000为1s-- c:=zc;--------停止检测高电平并锁存高四位计数器值------ d:=zd; e:=ze;
f:=zf; end if; end if;
if(clkx='1')then--------测待测方波高电平------
if(clk_10m'event and clk_10m='1')then counter3:=counter3+1; za:=za+1; if(za=10)then za:=0; zb:=zb+1; if(zb=10)then zb:=0; zc:=zc+1; if(zc=10)then zc:=0; zd:=zd+1; if(zd=10)then zd:=0; ze:=ze+1; if(ze=10)then ze:=0; zf:=zf+1; if(zf=10)then zf:=0; end if; end if; end if; end if; end if; end if; end if; end if;
-------------------**p3_4--数码管显示部分**-------------------------
if(clk_1hz'event and clk_1hz='1')then-----1s显示一次频率-----
-------**小数点显示**------
17 / 21
if(dip7=1)then
led4(7)<='1'; led3(7)<='1'; led2(7)<='1'; led1(7)<='0';
elsif(dip5=1 or dip6=1)then led4(7)<='1'; led3(7)<='1'; led2(7)<='1'; led1(7)<='1'; elsif(dip4=1)then led4(7)<='0'; led3(7)<='1'; led2(7)<='1'; led1(7)<='1'; elsif(dip3=1)then
led4(7)<='1'; led3(7)<='0'; led2(7)<='1'; led1(7)<='1'; elsif(dip2=1)then
led4(7)<='1'; led3(7)<='1'; led2(7)<='0'; led1(7)<='1'; elsif(dip1=1 )then
led4(7)<='1'; led3(7)<='1'; led2(7)<='1'; led1(7)<='0'; end if;
---------**显示数字**---------------- Case qian is
when 0=>led1(6 downto 0)<=\"1000000\"; when 1=>led1(6 downto 0)<=\"1111001\"; when 2=>led1(6 downto 0)<=\"0100100\"; when 3=>led1(6 downto 0)<=\"0110000\"; when 4=>led1(6 downto 0)<=\"0011001\"; when 5=>led1(6 downto 0)<=\"0010010\"; when 6=>led1(6 downto 0)<=\"0000010\"; when 7=>led1(6 downto 0)<=\"1111000\"; when 8=>led1(6 downto 0)<=\"0000000\"; when 9=>led1(6 downto 0)<=\"0010000\";
18 / 21
when others=>led1(6 downto 0)<=\"0000000\"; end case;
case bai is
when 0=>led2(6 downto 0)<=\"1000000\"; when 1=>led2(6 downto 0)<=\"1111001\"; when 2=>led2(6 downto 0)<=\"0100100\"; when 3=>led2(6 downto 0)<=\"0110000\"; when 4=>led2(6 downto 0)<=\"0011001\"; when 5=>led2(6 downto 0)<=\"0010010\"; when 6=>led2(6 downto 0)<=\"0000010\"; when 7=>led2(6 downto 0)<=\"1111000\"; when 8=>led2(6 downto 0)<=\"0000000\"; when 9=>led2(6 downto 0)<=\"0010000\";
when others=>led2(6 downto 0)<=\"0000000\"; end case;
case shi is
when 0=>led3(6 downto 0)<=\"1000000\"; when 1=>led3(6 downto 0)<=\"1111001\"; when 2=>led3(6 downto 0)<=\"0100100\"; when 3=>led3(6 downto 0)<=\"0110000\"; when 4=>led3(6 downto 0)<=\"0011001\"; when 5=>led3(6 downto 0)<=\"0010010\"; when 6=>led3(6 downto 0)<=\"0000010\"; when 7=>led3(6 downto 0)<=\"1111000\"; when 8=>led3(6 downto 0)<=\"0000000\"; when 9=>led3(6 downto 0)<=\"0010000\";
when others=>led3(6 downto 0)<=\"0000000\"; end case;
case ge is
when 0=>led4(6 downto 0)<=\"1000000\"; when 1=>led4(6 downto 0)<=\"1111001\"; when 2=>led4(6 downto 0)<=\"0100100\"; when 3=>led4(6 downto 0)<=\"0110000\"; when 4=>led4(6 downto 0)<=\"0011001\"; when 5=>led4(6 downto 0)<=\"0010010\"; when 6=>led4(6 downto 0)<=\"0000010\"; when 7=>led4(6 downto 0)<=\"1111000\"; when 8=>led4(6 downto 0)<=\"0000000\"; when 9=>led4(6 downto 0)<=\"0010000\";
when others=>led4(6 downto 0)<=\"0000000\"; end case;
19 / 21
clr:=1;---------显示完后清零------ end if;
-----**计数器清零**----- if(clr=1)then
aa:=0; bb:=0; cc:=0; dd:=0; ee:=0; ff:=0; gg:=0; hh:=0;
za:=0; zb:=0; zc:=0; zd:=0; ze:=0; zf:=0;
dip1:=0; dip2:=0; dip3:=0; dip4:=0; dip5:=0;
temp2:=0; temp3:=0; temp4:=0; temp5:=0;
counter2:=0; counter3:=0;
clr:=0;------退出清零---
end if; end process p3;
--*************p4**数码管扫描******************************
p4 : process(clk) is
20 / 21
variable counter4 :integer range 0 to 3:=0; begin
if(freq12k'event and freq12k='1') then counter4:=counter4+1; case counter4 is
when 0 => wei <= \"0111\"; led <= led1; when 1 => wei <= \"1011\"; led <= led2; when 2 => wei <= \"1101\"; led <= led3; when 3 => wei <= \"1110\"; led <= led4; when others => null; end case; end if;
end process p4;
end architecture abc;
21 / 21
因篇幅问题不能全部显示,请点此查看更多更全内容