FPGA|CPLD|ASIC论坛
直播中

暴躁的小码农

12年用户 16经验值
私信 关注
[经验]

FPGA项目——数字频率测量FPGA实现

一    工具:Alter Quartus
       语言:VerilogHDL
  
---------------------------------------------------------------------------------------------------------------
二   相关原理
1  常用的测频方法[1]
①  利用电路的某种频率响应特性来测量频率,如谐振测频法[低频测量,应用较广]、电桥测频法[高频、微波段测量]
②  利用标准频率与测频进行比较来测量,精度取决于标准频率的准确度,如拍频法[低频]、示波器法[低频]、差频法[高频]
③  电子计数测频法[适用于用数字电路实现]:直接测频法[测周期法和测频率法]和等精度测频法
2  频率测量的常用方法
QQ截图20120223144911.jpg
3  等精度测频法原理
2011063021531526.png
2011063021525357.png
等精度测频方法是在直接测频方法的基础上发展起来的。如图1所示,它的闸门时间不是固定的值,而是被测信号周期的整数倍,即与被测信号同步,其实现方式可用图2来说明。图中,预置门控信号是为Tpr 的一个脉冲,CNT1和CNT2是两个可控计数器。标准频率信号从CNT1的时钟输入端CLK输入,其频率为fs 。经整形后的被测信号(频率为fx)从CNT2的时钟输入端CLK输入,当预置门信号为高电平(预置时间开始)时,被测信号的上升沿通过D触发器的Q端同时启动计数器CNT1和CNT2计数。CNT1和CNT2分别对被测信号(频率为fx)和标准频率信号(频率为fs)同时记数。同样,当预置门信号为低电平(预置时间结束)时,随后而至的被测信号的上升沿通过D触发器的输出端,同时关闭计数器的计数。设在一次预置门时间Tpr中计数器对被测信号的计数值为Nx,对标准信号的计数值为Ns。则下式成立:
2011063021535257.gif
由此可推得:
2011063021535940.gif
等精度测频法具有三个特点:
(1)相对测量误差与被测频率的高低无关;
(2)增大Tpr或fs可以增大Ns,减少测量误差,提高测量精度;
(3)测量精度与预置门和标准频率有关,与被测信号的频率无关,在预置门和常规测频闸门时间相同而被测信号频率不同的情况下,等精度测量法的测量精度不变。
一种实现过程[7]
①  预设闸门模块:由标准时钟产生预设闸门信号。如标准时钟100us[10kHz],计数1000次,产生预设闸门信号为100ms
②  实际闸门模块:用被测信号来同步预设闸门模块产生的闸门信号来产生新的实际闸门信号,本质是一个D触发器
③  计数模块:在实际闸门信号有效时,标准时钟和被测信号同时计数,在闸门信号结束时输出计数结果
④  频率计算模块:由公式进行乘法和除法运算
直接计数测频法
测频法原理:在确定的闸门时间Tw内,记录被测信号的变化周期数或脉冲个数Nx,有fx=Nx/Tw  [1]
测周期法原理:需要有标准信号频率fs,在待测信号的一个周期时间Tx内,记录标准频率的周期数Ns,有fx=fs/Ns [1]
最高测量频率为标准信号频率[个人总结]。
测量误差:两种方法都会产生±1个字的误差。最大误差为1/N,N为周期个数。[1]
直接计数测频法缺点:整个测频范围内的测频精度是不同的。如闸门时间是1s时,测量100MHz的信号可达到10-8的测量精度,但测量10Hz的信号只能达到10-1的测量精度。[3]
参考信号:测频法需要得到一个标准的脉宽,测周期法需要一个标准时钟。实际上标准的脉宽必须从一个标准时钟分频得到,而一般,标准始终是从外部晶振分频得到。[1]
测量时间:当计数周期为106个时,计数时间为1s[个人总结]
-------------------------------------------------------------------------------------------------------------------------------------------------
三 实现
除法运算的Verilog实现(累加比较法)
  1. module mydiv(clk, dataa, datab, start, datac);
  2.   input clk;
  3. input [7:0] dataa;//被除数
  4. input [7:0] datab;//除数
  5. input start;//开始新的运算
  6. output [7:0] datac;//商

  7. reg [7:0] datac;
  8. reg [7:0] cbuf;
  9. reg [7:0] temp;

  10. always @(posedge clk)
  11. begin
  12. if(1'b1 == start)
  13. begin
  14. temp <= 8'd0;
  15. cbuf <= 8'd0;
  16. end
  17. else if (dataa > temp)
  18. begin
  19. temp <= temp + datab;
  20. cbuf <= cbuf + 8'h01;
  21. end
  22. else
  23. begin
  24. datac <= cbuf;
  25. end
  26. end

  27. Endmodule
直接测频法
  1. 闸门产生模块/gateout输出1s,clk设为1ms
  2. module gate(clk, gateout);
  3. input clk;
  4. output gateout;

  5. reg [9:0] cnt;
  6. reg gatebuf;

  7. assign gateout = gatebuf;

  8. always @(posedge clk)
  9. begin
  10. if (10'd999 == cnt)
  11. begin
  12. cnt <= 10'd0;
  13. gatebuf <= ~gatebuf; //产生1s闸门
  14. end
  15. else
  16. begin
  17. cnt <= cnt + 10'd1;
  18. end
  19. end

  20. endmodule

  21. 计数模块
  22. 说明:闸门信号高有效下进行计数,当闸门信号为低时停止计数并输出计数结果。采用5位十进制计数
  23. module cnt(clk, gate, done, dtwo, dthree, dfour, dfive);
  24. input clk;
  25. input gate;
  26. output done;//个位
  27. output dtwo;//十位
  28. output dthree;//百位
  29. output dfour;//千位
  30. output dfive;//万位

  31. reg [3:0] done, dtwo, dthree, dfour, dfive;
  32. reg [3:0] ddone, ddtwo, ddthree, ddfour, ddfive;
  33. reg gatebuf;

  34. always @(posedge clk)
  35. begin
  36. gatebuf <= gate;
  37. end

  38. always @(posedge clk)
  39. begin
  40. if((gatebuf == 1'b0) && (gate == 1'b1))
  41. begin
  42. ddone <= 4'd1;
  43. ddtwo <= 4'd0;
  44. ddthree <= 4'd0;
  45. ddfour <= 4'd0;
  46. ddfive <= 4'd0;
  47. end
  48. else if((gatebuf == 1'b1) && (gate == 1'b0))
  49. begin
  50. done <= ddone;
  51. dtwo <= ddtwo;
  52. dthree <= ddthree;
  53. dfour <= ddfour;
  54. dfive <= ddfive;
  55. end
  56. else if(gate == 1'b1)
  57. begin
  58. if (ddone == 4'd9)
  59. begin
  60. ddone <= 4'd0;
  61. if (ddtwo == 4'd9)
  62. begin
  63. ddtwo <= 4'd0;
  64. if (ddthree == 4'd9)
  65. begin
  66. ddthree <= 4'd0;
  67. if (ddfour == 4'd9)
  68. begin
  69. ddfour <= 4'd0;
  70. if (ddfive == 4'd9)
  71. begin
  72. ddfive <= 0;
  73. end
  74. else
  75. begin
  76. ddfive <= ddfive + 4'd1;
  77. end
  78. end
  79. else
  80. begin
  81. ddfour <= ddfour + 4'd1;
  82. end
  83. end
  84. else
  85. begin
  86. ddthree <= ddthree + 4'd1;
  87. end
  88. end
  89. else
  90. begin
  91. ddtwo <= ddtwo + 4'd1;
  92. end
  93. end
  94. else
  95. begin
  96. ddone <= ddone + 4'd1;
  97. end
  98. end
  99. end

  100. endmodule
周期测频法
  1. 计数模块
  2. module periodcnt(clk, clkt, cntout,cntok);
  3. input clk;//标准时钟信号
  4. input clkt;//被测信号

  5. output [19:0] cntout;//计数结果输出
  6. output cntok;//计数结果输出标志

  7. reg [19:0] cntout, cnt;
  8. reg cntok, clktbuf;

  9. always @(posedge clk)
  10. begin
  11. clktbuf <= clkt;
  12. end

  13. always @(posedge clk)
  14. begin
  15. if((clkt == 1'b1) && (clktbuf == 1'b0))//在被测信号上升沿输出计数结果并置计数为1
  16. begin
  17. cntout <= cnt;
  18. cnt <= 20'd1;
  19. cntok <= 1'b1;
  20. end
  21. else
  22. begin
  23. cnt <= cnt + 20'd1;
  24. cntok <= 1'b0;
  25. end
  26. end
  27. endmodule

  28. 除法运算模块
  29. module perioddiv(clk, datab, start, datac);
  30. input clk;
  31. input [19:0] datab;
  32. input start;
  33. output [19:0] datac;

  34. reg [19:0] dataa,datac, databbuf;
  35. reg [19:0] cbuf;
  36. reg [19:0] temp;
  37. reg finish, cntflag;

  38. always @(posedge clk)
  39. begin
  40. if((1'b1 == start) && (finish == 1'b0) && (datab != 20'd0))
  41. begin
  42. dataa <= 1000000;
  43. temp <= datab;
  44. cbuf <= 20'd1;
  45. databbuf <= datab;
  46. cntflag <= 1'b1;
  47. end
  48. else if ((dataa > temp) && (cntflag == 1'b1) )
  49. begin
  50. temp <= temp + databbuf;
  51. cbuf <= cbuf + 20'd1;
  52. finish <= 1'b1;
  53. end
  54. else
  55. begin
  56. datac <= cbuf;
  57. finish <= 1'b0;
  58. cntflag <= 1'b0;
  59. end
  60. end

  61. endmodule
等精度测频法
  1. 预设闸门模块:由标准时钟计数产生
  2. module pregate(clk, gateout);
  3. input clk;
  4. output gateout;

  5. reg gateout, gatebuf;
  6. reg [19:0] cnt;

  7. always @(posedge clk)
  8. begin
  9. if (cnt == 20'd1000)
  10. begin
  11. gatebuf <= ~gatebuf;
  12. gateout <= gatebuf;
  13. cnt <= 20'd0;
  14. end
  15. else
  16. begin
  17. cnt <= cnt + 20'd1;
  18. end
  19. end

  20. endmodule

  21. 实际闸门模块:由被测信号来同步预设闸门模块产生
  22. module actgate(clk, gatein, gateout);
  23. input clk;
  24. input gatein;
  25. output gateout;

  26. reg gateout;

  27. always @(posedge clk)
  28. begin
  29. gateout <= gatein;
  30. end

  31. endmodule

  32. 计数模块:在实际闸门信号有效时,标准时钟与被测信号同时进行计数;在闸门信号结束时输出计数结果
  33. module cnt(clk, gate, cntout);
  34. input clk;
  35. input gate;
  36. output [19:0] cntout ;

  37. reg [19:0] cnt, cntout;
  38. reg gatebuf;

  39. always @(posedge clk)
  40. begin
  41. gatebuf <= gate;
  42. end

  43. always @(posedge clk)
  44. begin
  45. if((gate == 1'b1) && (gatebuf == 1'b0))
  46. begin
  47. cnt <= 20'd1;
  48. end
  49. else if((gate == 1'b0) && (gatebuf == 1'b1))
  50. begin
  51. cntout <= cnt;
  52. end
  53. else if(gatebuf == 1'b1)
  54. begin
  55. cnt <= cnt + 20'd1;
  56. end
  57. end
  58. endmodule

  59. 频率计数模块:根据公式计算
  60. module frediv(clk, datat,datas, freout);
  61. input clk;
  62. input [19:0] datat;
  63. input [19:0] datas;

  64. output [19:0] freout;

  65. reg [19:0] datam,freout, databbuf;
  66. reg [19:0] cbuf;
  67. reg [19:0] temp;
  68. reg finish, cntflag;

  69. always @(posedge clk)
  70. begin
  71. if((finish == 1'b0) && (datas != 20'd0) && (datat != 20'd0))
  72. begin
  73. datam <= 20'd10000 * datat;
  74. temp <= datas;
  75. cbuf <= 20'd1;
  76. databbuf <= datas;
  77. cntflag <= 1'b1;
  78. finish <= 1'b1;
  79. end
  80. else if ((datam > temp) && (cntflag == 1'b1) )
  81. begin
  82. temp <= temp + databbuf;
  83. cbuf <= cbuf + 20'd1;

  84. end
  85. else
  86. begin
  87. freout <= cbuf;
  88. finish <= 1'b0;
  89. cntflag <= 1'b0;
  90. end
  91. end

  92. endmodule
参考资料
[1]求是科技.CPLD/FPGA应用开发设计与工程实践.北京:人民邮电出版社[M],2005.1
[2]王金名,冷自强.EDA技术与Verilog设计[M].北京:科学出版社,2008.4
[3]杨晓慧,杨旭.FPGA系统设计与实例[M].北京:人民邮电出版社,2010.1
[4]PPT:采用等精度测频原理的频率计
[5]王刚,张潋.基于FPGA的SOPC嵌入式系统设计与典型实例[M].北京:电子工业出版社社,2009.1
[6]叶舒亚.基于FPGA的便携式振动频谱分析仪的设计[D].成都理工大学硕士论文,2007.5
[7]刘福奇,刘波.VerilogHDL应用程序设计实例精讲[M].电子工业出版社,2009.10
[8]常晓明等.VerilogHDL语言编程[M].北京航天航空出版社,2005.8
[9]王彦.基于FPGA的工程设计与应用[M].西安:西安电子科技大学出版社,2007.5
---------------------------------------------------------------------------------------------------------------
Author:         SKySeraph
Email/GTalk: zgzhaobo@gmail.com    QQ:452728574
From:         http://www.cnblogs.com/skyseraph/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
---------------------------------------------------------------------------------------------------------------

回帖(13)

会飞的云

2012-7-18 12:52:04
举报

赢在南航

2012-7-18 20:17:55
很好
举报

陈华生

2012-9-25 00:38:05
嗯嗯,可以
举报

深圳圣莱尔小樊

2012-9-26 09:57:33
哇~都是数据啊,看不懂诶
举报

pular0820

2012-10-9 10:48:09
正在做这一块,学习了
举报

悲歌1990

2012-12-7 20:14:35
搞起啊
举报

povety

2013-2-2 22:42:33
代码挺详细的
举报

ened

2013-2-28 22:17:38
此贴很不错
举报

田志伟

2013-3-14 10:56:27
不错的东西啊
举报

MyBesT

2013-3-17 09:59:31
同求
举报

tonggl150

2013-3-19 09:09:14
总结得比较全面,支持。谢谢
举报

728812

2013-3-20 09:27:11
用了几种方法在做吗?
举报

高立稳

2013-3-20 16:27:08
老兄,本吊丝正需要
举报

更多回帖

发帖
×
20
完善资料,
赚取积分