[AVR单片机] 基于AVR单片机的数控频率计

[复制链接]
1663|6
 楼主| 一路向北lm 发表于 2018-6-22 20:43 | 显示全部楼层 |阅读模式
数控频率计原理图·



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 一路向北lm 发表于 2018-6-22 20:46 | 显示全部楼层
AVR单片机源码
  1. //包含所需头文件
  2. #include <avr/io.h>
  3. #include <avr/interrupt.h>
  4. #include <avr/signal.h>


  5. /*------宏定义------*/
  6. #define uchar        unsigned char
  7. #define uint        unsigned int
  8. #define ulong   unsigned long

  9. //数码管字型表,对应0, 1, 2,  3,  4,  5,  6,  7,  8,   9//
  10. uchar Table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
  11. uchar Data[4]={0,0,0,0};       //显示初始值:0 0 0 0
  12. uint data=0;
  13. uint CNT=0;
  14. uchar fanwei=1;
  15. unsigned long Load;

  16. //延时函数
  17. void delay_us( int t)     //us
  18. {
  19. do
  20. t--;
  21. while(t>1);
  22. }
  23. void delay_ms(unsigned int t)   //ms
  24. {
  25. while(t!=0)
  26. {
  27.   delay_us(1142);
  28.   t--;
  29. }
  30. }

  31. //动态显示函数
  32. void Display(uchar *p)         //参数p为待显示的数组名
  33. {uchar i,sel=0x01;           
  34. for(i=0;i<4;i++)
  35.   {
  36.    PORTA=Table[p[i]];          //送字型码
  37.    PORTD=~sel;
  38.    delay_us(500);              //显示延时   
  39.    sel=sel<<1;                 //移位以显示前一位
  40.   }
  41. }

  42. //计数值处理函数
  43. void Process(unsigned long i,uchar *p)
  44. {
  45. if(fanwei==2)
  46.    i=i/1000;
  47. if(fanwei==1)
  48. {
  49.    if(i>9999)
  50.     i=9999;
  51. }          
  52. p[0]=i/1000;
  53. i=i%1000;
  54. p[1]=i/100;
  55. i=i%100;
  56. p[2]=i/10;
  57. p[3]=i%10;
  58. }

  59. void xuanze (void)
  60. {
  61.   if((PINB&0X10)==0)
  62.     fanwei=1;       //单位为1Hz
  63.          
  64.   if((PINB&0X20)==0)
  65.     fanwei=2;       //单位为1KHz
  66.   if(fanwei==1)
  67.     PORTC=0X01;
  68.   if(fanwei==2)
  69.     PORTC=0X02;               
  70. }
  71. //端口初始化
  72. void port_init(void)
  73. {
  74. PORTA = 0xFF;
  75. DDRA  = 0xFF;
  76. PORTB = 0xFF;
  77. DDRB  = 0x00;
  78. PORTC = 0xFF;
  79. DDRC  = 0xFF;
  80. PORTD = 0xFF;
  81. DDRD  = 0xFF;
  82. }


  83. //定时T1初始化
  84. void timer1_init(void)
  85. {
  86. TCCR1B = 0x00;//停止定时器
  87. TIMSK |= 0x04;//中断允许

  88. TCNT1H = 0x00;
  89. TCNT1L = 0x00;//初始值
  90. OCR1AH = 0xFF;
  91. OCR1AL = 0xFF;//匹配A值
  92. OCR1BH = 0xFF;
  93. OCR1BL = 0xFF;//匹配B值
  94. ICR1H  = 0xFF;
  95. ICR1L  = 0xFF;//输入捕捉匹配值
  96. TCCR1A = 0x00;
  97. TCCR1B = 0x07;//启动定时器
  98. }

  99. //定时器T1溢出中断服务程序
  100. #pragma interrupt_handler timer1_ovf_isr:9
  101. void timer1_ovf_isr(void)
  102. {
  103. CNT++;
  104. TCNT1H = 0x00; //重装值高位
  105. TCNT1L = 0x00; //重装值低位
  106. }

  107. //定时器T2初始化
  108. void timer2_init(void)
  109. {
  110. PORTC =0X01;
  111. TCCR2  = 0x00;//停止定时器
  112. ASSR   = 0x08;//异步时钟模式  AS2=1
  113. TCNT2  = 0xFF;//初始值
  114. OCR2   = 0xFE;//匹配值
  115. TIMSK |= 0x40;//中断允许
  116. TCCR2  = 0x05;//启动定时器    PCK/128
  117. }


  118. //T2溢出中断服务程序
  119. #pragma interrupt_handler timer2_ovf_isr:5
  120. void timer2_ovf_isr(void)
  121. {
  122. PORTC=0X02;
  123. TCCR1B = 0x00;                  //关闭计数
  124. //读取计数值
  125. Load=CNT*65536+TCNT1;           //计算频率值
  126. TCNT1 = 0X00;                   //清除计数值
  127. CNT=0;

  128. TCCR1B = 0x07;                  //开始计数
  129. }


  130. void init_devices(void)
  131. {
  132. cli(); //禁止所有中断
  133. MCUCR  = 0x00;
  134. MCUCSR = 0x80;//禁止JTAG
  135. GICR   = 0x00;
  136. port_init();
  137. timer1_init();
  138. timer2_init();
  139. sei();//开全局中断
  140. }
  141. //主函数
  142. void main(void)
  143. {
  144. init_devices();
  145. while(1)
  146. {
  147.   xuanze();
  148.   Process(Load,Data);    //计数值处理
  149.   Display(Data);        //动态扫描显示
  150. }


  151. }




coody 发表于 2018-6-25 09:56 | 显示全部楼层
测量最高频率是多少?
 楼主| 一路向北lm 发表于 2018-6-25 12:43 | 显示全部楼层
coody 发表于 2018-6-25 09:56
测量最高频率是多少?

kHZ级别  不上M估计也就几十K
coody 发表于 2018-6-25 16:29 | 显示全部楼层
一路向北lm 发表于 2018-6-25 12:43
kHZ级别  不上M估计也就几十K

我的简易频率计用74HC14做输出整形,MCU使用STC12C5204AD,跑有源0.1ppm的32.768MHZ,直接测频最高16MHZ,通过一个外接的74HC系列的计数器分频可以测到100MHZ,通过MB506分频可以测2.4GHZ。
 楼主| 一路向北lm 发表于 2018-6-25 18:49 | 显示全部楼层
coody 发表于 2018-6-25 16:29
我的简易频率计用74HC14做输出整形,MCU使用STC12C5204AD,跑有源0.1ppm的32.768MHZ,直接测频最高16MHZ ...

加一个牛点的分频器还是可以把频率给提上去的,我之前发过一个制作2.4G频率计的帖子。
Boreas_Tyr 发表于 2018-6-29 09:11 | 显示全部楼层
频率测量如果只是用于显示,分频没问题,但是用于控制,分频显然降低了系统的实时性。例如灌装系统中测试流量,脉冲到特定数目代表灌装满,这种高速计数模式不适合分频
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3837

帖子

81

粉丝
快速回复 在线客服 返回列表 返回顶部