FPGA频率计.docx

上传人:小飞机 文档编号:3157231 上传时间:2023-03-11 格式:DOCX 页数:7 大小:40.05KB
返回 下载 相关 举报
FPGA频率计.docx_第1页
第1页 / 共7页
FPGA频率计.docx_第2页
第2页 / 共7页
FPGA频率计.docx_第3页
第3页 / 共7页
FPGA频率计.docx_第4页
第4页 / 共7页
FPGA频率计.docx_第5页
第5页 / 共7页
亲,该文档总共7页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《FPGA频率计.docx》由会员分享,可在线阅读,更多相关《FPGA频率计.docx(7页珍藏版)》请在三一办公上搜索。

1、FPGA频率计最近自己拿FPGA弄了一个简易频率计:精度1HZ,可以测试占空比,但是精度只有10%。下面讲解一下,希望对想弄这个的人有一点帮助: 我的硬件说明:EP1C3T144C8N核心板、8位数码管、按键、8位LED、20M晶振 首先说一下测量方波信号频率的原理: 首先一个几位的计数器在方波信号的跳变沿激励下,来一个激励脉冲计数器将加一,但是问题出现了,这个计数器一直加的话不是溢出了?你怎么样通过这个加的数值来确定你的方波频率? 先卖个关子,先来说说这个计数器!计数器肯定是一直在加的,那么你的计数的最高数值就是由你的计数器的位数决定的,比如这里是2的4次方,又回到原来的问题,你的计数器不是

2、有跳变沿就加一吗?那岂不是不同的方波信号频率都是加到了最大值?但是你想到没有,不同的方波信号频率输入的话,你的计数器加到最大值的时间是不同的,这里才是设计理解的关键!那么我们就是通过这个不同的时间来判断的。下面讲解原理: 我们让这个计数器在规定的时间内加,然后设定的时间一到我们把这个加的数值存起来,同时将这个计数器清零。那么我们先假设这个待测输入的方波信号的频率是固定不变的,也就是说在这个设定的时间内,计数器加的数值,也就是检测到的跳变沿的个数,具体假设是下降沿,在理论上是一个固定的值!,因为每次时间一到这个计数器将被清零了。我们为了后面计算的方便,假设我们设定的时间是1秒钟,也就是1HZ,在

3、这个1HZ时钟的控制下面,每秒钟将会把这个计数器清零,那么很显然,这个计数器在这个时间1秒钟内加的数值N就是你测的的方波的频率值!这个就是一个很简单的数学的问题,在相同的1秒钟时间内,clk信号相当于加了一次,signal信号加了N次,那么你的signal信号的频率肯定是这个clk频率的N倍,你的测量的精度显然就是你的设定比较的时钟1HZ咯。这里有人会提出疑问了,那么我把这个清零的控制时钟改为0.5HZ,那你的频率的测量精度会不会是0.5HZ呢?懂了上面的原理后,这个问题留给你自己思考吧。 好了,测量频率基本原理我们讲了,上面举的例子是4位的计数器,那么最大的计数频率就是2的4次方,很显然这个

4、范围太小了,我们需要很多位的计数器!这里就不得不用模块化的设计思想了,把4位的计数器串接起来不就实现多位了!我在实验中做的是一个32位的,也就是2的32次方,大家可以算一下最大测量的理论频率有多大,但是我的只有8位的数码管,最大也就是99999999,姑且算为100MHZ吧,相比较的基准频率设定为1HZ,那么我在实验中就要将这个20M的主晶振20M分频!听起来很恐怖是吧,用FPGA简单的不可思议啦! 频率测量好了,现在还需要测量这个signal方波信号的占空比 。测量占空比我用的是除法器,但是数字电路实现除法器实在是太耗资源了,大家看下编译完成后的报告就知道了!下面讲测量方法的原理: 思路可以

5、采用时基法,和前面测量方波占空比是一样的道理,在clk基准时钟下,对每个signal信号的高电平持续时间和低电平持续时间进行测量,这时你如果检测到待测信号为高电平-低电平,这时你开始对你的1G的基准频率开始计数,存成一个整数比如a。什么时候停呢?那就是待测信号由低电平-高电平的时候,这时a不加了,改成对另外一个整数b开1g的上升沿加1,在待测信号为高电平-低电平时候b停止加一,这时你得到a,b。 a就是待测信号低电平的时长,b就是待测信号高电平的时长。这时你的占空比 = (b/(a+b)*100%。 下面我把每个模块的代码和综合后的图像贴在下面:4位计数器代码: module cnt_10(o

6、ut,cout,en,clr,clk); input en,clr,clk; output 3:0 out; output cout; reg 3:0 out; always (posedge clk or posedge clr) begin if(clr) out =4b0; else if(en) begin end assign cout = (out = 4d9) & en) ? 1b1 : 1b0 ; endmodule 注释:en为使能端,clr为异步清零端,也就是控制时钟1HZ的清零操作接口,这里可能有人会有疑问,为什么是计数到了10就进了一位呢?4位的计数器不是最大可以计数到

7、2的4次方吗?其实这里有一个小技巧,为了数码管显示的方便,这里我们将8个数码管每一个对应一个计数器的数值,那么10进制显示的话就是每一个数码管对应数据的每一个位。 下面是20M的分频电路: module f_div_1(clk,clk0,rst_n); input clk;/输入的20MHZ基准时钟 input rst_n; output clk0;/输出1HZ信号 out = out + 1b1; if(out = 4d9) begin end out = 4b0; end reg clk0; reg clk1; reg 3:0 cnt1; reg 22:0 cnt2; /-/ /20分频电

8、路,主晶振20M,分频为1M always (posedge clk or negedge rst_n) if(!rst_n) cnt1 = 4b0; else if(cnt1 = 4d9) begin cnt1 = 4b0; clk1 = clk1; end else cnt1 = cnt1 + 1b1; /-/ /1M分频电路,输出为1HZ时钟 always (posedge clk1 or negedge rst_n) if(!rst_n) cnt2 = 23b0; else if(cnt2 = 23d499999) begin cnt2 = 23b0; clk0 = clk0; end

9、 else cnt2 = cnt2 + 1b1; endmodule 下面是测量占空比的两个参数a,b: module duty_cycle( clk, rst_n, signal, a2, b2 ); input clk;/输入的基准时钟20M input rst_n; input signal;/signal信号输入端 output 17:0 a2,b2; reg 15:0 a,b,a1,b1;/这里我设置了16位的累加器,也就是说能测量占空/率的范围是300HZ到20M always (posedge clk or negedge rst_n) begin if(!rst_n) begi

10、n a = 16b0; a1 = 16b0; b = 16b0; b1 = 16b0; end else if(signal = 1b1) begin if(a != 16b0)/这里要把相应的寄存器清零的同时把值取出 a1 = a; a = 16b0; b = b + 1b1; end else if(signal = 1b0) begin if(b != 16b0) b1 = b; b = 16b0; a = a + 1b1; end end assign b2 = (b1 * 7d100);/这里我将这个高电平等效时间的b1乘以100 /再送到除法器模块 assign a2 = a1 +

11、 b1; /这里的a2输出的就是整个周期的时间 /那么b2除以a2的数值就是占空比啦 Endmodule 注释:这里可能有同学又会有疑问了,这个为什么要将这个计数器a,b清零呢?很简单嘛,你在这个高电平期间累加的值不可能在下一个高电平期间又是接着加吧,这里就是清零的同时将数值存到别的寄存器。 下面是VHDL语言的18位除法器: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; use ieee.numeric_std.all; ent

12、ity divider_prj is port( b : in std_logic_vector(17 downto 0); a : in std_logic_vector(17 downto 0); shang : out std_logic_vector(6 downto 0) ); end; architecture one of divider_prj is signal tempa,tempb:std_logic_vector(17 downto 0); begin process(a,b) begin tempa = a ; tempb = b ; end process; pro

13、cess(tempa,tempb) variable n:integer; variable temp_a,temp_b : std_logic_vector(35 downto 0); begin temp_a := 000000000000000000 & tempa; temp_b := tempb & 000000000000000000 ; n := 0; while(n= tempb then temp_a := temp_a - temp_b + 1; end if; end loop; shang = temp_a(6 downto 0) ; end process; end;

14、 除法器模块是整个系统中最占资源的部分!为了简便这里我将这个余数部分舍掉了。 好了,具体就是这么多了,说下这个工程的缺点还有我的一些疑问和建议吧: 精度为1HZ,除法器设计不是很好,比较慢,但是这个简易的就够用了。 建议:1、可以同时做几个计数器来捕捉这个signal信号,最后求其平均值,这样精度可以提高;2、同时捕捉上升沿和下降沿的方法,可以同时满足你测频率和占空比的需要。 疑问:我在显示的时候遇到了一个问题,是10进制的显示,但是不知道为什么每次加到了9前面的高位就向前进了一位,也就是从8到9时候,结果9进了一位,显示的是19了!看了显示译码电路和以前做的John计数器一样的,John计数器显示的没有问题,但是这里我硬是没看懂怎么回事,觉得可能是送显示时的时序问题,希望高人看后能指点一下。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号