基于STC8单片机的频率计

测频原理:计数法测频率。
实现方法:利用51单片机定时器可作为外部脉冲计数器的特点,可实现频率计数。具体使用两个定时器,本例中,使用定时器0作为外部脉冲计数器,用于对外部脉进行捕获(下降沿触发),定时器3产生1s定时,用于提取计数频率。
代码如下

  1. //系统时钟频率 24MHz  
  2. #include "STC8.H"  
  3.   
  4. bit send_flag = 0;  
  5. unsigned int freq = 0;     //频率计数  
  6. unsigned long cont_freq = 0;   //频率计数溢出  
  7. unsigned char res[6];   //频率转换结果  
  8.   
  9. void TM0_Init();  
  10. void TM3_Init();  
  11. void UartSend(unsigned char dat);  
  12. void UartInit(void);  
  13. void UartSendStr(unsigned char *p);  
  14. void Num_Cut(unsigned long num);  
  15. void Uart_Send_Str(unsigned char str[],unsigned char len,bit mode);  
  16.   
  17. void main ()  
  18. {  
  19.     TM0_Init();      
  20.     TM3_Init();      
  21.     UartInit();      
  22.     while(1)  
  23.     {   
  24.     if(send_flag)  
  25.         {  
  26.         Num_Cut(cont_freq+(unsigned long)freq); //频率值等于溢出值加当前值  
  27.               send_flag = 0;  
  28.               UartSendStr("Freq: ");  
  29.                 Uart_Send_Str(res,6,1);  
  30.                 Uart_Send_Str(res,6,0);  
  31.                 UartSendStr(" Hz\n");  
  32.         }  
  33.     }  
  34. }   
  35. /****************************************************************************** 
  36.  * 描  述 : 定时器3初始化函数,定时时间1ms 
  37.  * 入  参 : 无 
  38.  * 返回值 : 无 
  39.  ******************************************************************************/  
  40. void TM3_Init()  
  41. {  
  42.         T3L    = 0x35;                                                                  //设置定时初值,1ms  
  43.       T3H    = 0xA2;                                                                    //设置定时初值  
  44.     T4T3M |= 0x08;                                  //启动定时器  
  45.       T4T3M |= 0x02;                                                               //定时器时钟1T模式  
  46.     IE2   |= ET3;                                  //使能定时器中断  
  47.     EA     = 1;                                      //开总中断  
  48. }  
  49. /****************************************************************************** 
  50.  * 描  述 :  定时器0初始化函数,外部计数模式 
  51.  * 入  参 :  无 
  52.  * 返回值 :  无 
  53.  ******************************************************************************/  
  54. void TM0_Init()  
  55. {  
  56.       TMOD |= 0x04;                                //设置外部计数模式  
  57.       TMOD |= 0x01;                                //工作模式1,16位不自动重载  
  58.       TR0   = 1;                                    //打开计数器  
  59.     TH0   = 0x00;                                 //计数器复位  
  60.       TL0   = 0x00;                                  
  61.       ET0   = 1;                                    //开计数器中断  
  62. }  
  63. /****************************************************************************** 
  64.  * 描  述 : 定时器0中断服务函数  
  65.  * 入  参 : 无 
  66.  * 返回值 : 无 
  67.  ******************************************************************************/  
  68. void TM0_Isr() interrupt 1  
  69. {    
  70.     cont_freq += 65536;    //溢出计数,每溢出一次,计数次数为TH0<<8|TL0 = 0xffff,经调试结果加1  
  71.       TH0 = 0x00;            //复位计数器  
  72.       TL0 = 0x00;            //复位计数器      
  73. }  
  74. /****************************************************************************** 
  75.  * 描  述 :   定时器3中断服务函数 
  76.  * 入  参 :   无 
  77.  * 返回值 :   无 
  78.  ******************************************************************************/  
  79. void TM3_Isr() interrupt 19  
  80. {     
  81.   static unsigned int ms_flag = 0;  //1s计数标志  
  82.     if(ms_flag++ == 1000)  
  83.     {  
  84.         freq = (TH0<<8|TL0);           //获取当前计数器计数值            
  85.         ms_flag = 0;                   //1s计数标志复位  
  86.         send_flag = 1;                 //串口发送标志位置位  
  87.       TH0 = 0x00;                    //复位计数器  
  88.       TL0 = 0x00;                    //复位计数器      
  89.     }  
  90.     AUXINTIF &= ~T3IF;               //清中断标志  
  91. }  
  92. /****************************************************************************** 
  93.  * 描  述 :  串口1初始化函数,波特率9600  
  94.  * 入  参 :  无 
  95.  * 返回值 :  无 
  96.  ******************************************************************************/  
  97. void UartInit(void)     //9600bps@24.000MHz  
  98. {  
  99.     SCON |= 0x50;       //8位数据,可变波特率  
  100.     AUXR |= 0x01;       //串口1选择定时器2为波特率发生器  
  101.     AUXR |= 0x04;       //定时器2时钟为Fosc,即1T  
  102.     T2L   = 0x8F;       //设定定时初值  
  103.     T2H   = 0xFD;       //设定定时初值  
  104.     AUXR |= 0x10;       //启动定时器2  
  105. }  
  106. /****************************************************************************** 
  107. * 描  述 : 串口字符发送和函数  
  108. * 入  参 : 发送字符 
  109. * 返回值 : 无 
  110. ******************************************************************************/  
  111. void UartSend(unsigned char dat)  
  112. {  
  113.     SBUF =dat;             
  114.     while(!TI);       
  115.       TI=0;   
  116. }  
  117. /****************************************************************************** 
  118. * 描  述 : 串口字符串发送函数 
  119. * 入  参 : 发送字符串 
  120. * 返回值 : 无 
  121. ******************************************************************************/  
  122. void UartSendStr(unsigned char *p)  
  123. {  
  124.     while (*p)  
  125.     {  
  126.         UartSend(*p++);  
  127.     }  
  128. }  
  129.  /****************************************************************************** 
  130.  * 描  述 : 数字拆分函数 
  131.  * 入  参 : 拆分数字 
  132.  * 返回值 : 无 
  133.  ******************************************************************************/  
  134. void Num_Cut(unsigned long num)  
  135. { unsigned long temp = num;   
  136.     unsigned char cont = 5;  
  137.     while(temp != 0)  
  138.     {  
  139.         res[cont--] = (unsigned char)(temp % 10);  
  140.         temp /= 10;  
  141.     }  
  142.   cont_freq = 0;  
  143. }  
  144. /****************************************************************************** 
  145. * 描  述 :  串口数字数组发送函数 
  146. * 入  参 :  str:数组,len:数组长度或者要发送数据长度,mode:1发送,0清零数组 
  147. * 返回值 :  
  148. ******************************************************************************/  
  149. void Uart_Send_Str(unsigned char str[],unsigned char len,bit mode)  
  150. {  
  151.     unsigned char k;  
  152.     if(mode == 1)  
  153.     {  
  154.         for(k = 0;k < len; k++)  
  155.         {  
  156.             UartSend(48 + str[k]);  
  157.         }     
  158.     }else  
  159.     {  
  160.         for(k = 0;k < len; k++)  
  161.         {  
  162.             str[k] = 0;  
  163.         }  
  164.     }  
  165. }  

测试结果分析如下:

shashou47

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: