网站导航: 首页 > 设计参考 > 正文 文章搜索
51单片机C语言编程基础及实例
 
文章编号:
090106102159
文章分类: 单片机 51系列
点 击:
...
关 键 词: C语言,基础,实例
文章来源:
网络
摘 要:
基础知识:51单片机编程基础。第一节:单数码管按键显示。第二节:双数码管可调秒表。第三节:十字路口交通灯。第四节:数码管驱动。第五节:键盘驱动。第六节:低频频率计。第七节:电子表。第八节:串行口应用。

第六节:低频频率计
实例目的:学时定时器、计数器、中断应用
说明:选用24MHz的晶体,主频可达2MHz。用T1产生100us的时标,T0作信号脉冲计数器。假设晶体频率没有误差,而且稳定不变(实际上可达万分之一);被测信号是周期性矩形波(正负脉冲宽度都不能小于0.5us),频率小于1MHz,大于1Hz。要求测量时标1S,测量精度为0.1%。
解:从测量精度要求来看,当频率超过1KHz时,可采用1S时标内计数信号脉冲个数来测量信号频,而信号频率低于1KHz时,可以通过测量信号的周期来求出信号频率。两种方法自动转换。
对于低于1KHz的信号,信号周期最小为1ms,也就是说超过1000us,而我们用的定时器计时脉冲周期为0.5us,如果定时多计或少计一个脉冲,误差为1us,所以相对误差为1us/1000us=0.1%。信号周期越大,即信号频率越低,相对误差就越小。
从上面描述来看,当信号频率超过1KHz后,信号周期就少于1000us,显然采用上面的测量方法,不能达到测量精度要求,这时我们采用1S单位时间计数信号的脉冲个数,最少能计到1000个脉冲,由于信号频率不超过1MHz,而我们定时脉冲为2MHz,最差多计或少计一个信号脉冲,这样相对误差为1/1000,可见信号频率越高,相对误差越小。
信号除输入到T1(P3.5)外,还输入到INT1(P3.3)。

 

 

 
  1. unsigned int us100;   //对100us时间间隔单位计数,即有多少个100us。       
  2. unsigned char Second;       
  3. unsigned int K64;    //对64K单位计数,即有多少个64K         
  4. unsigned char oldT0;       
  5. unsigned int oldus, oldK64, oldT1;       
  6. unsigned long fcy;    //存放频率值,单位为Hz       
  7. bit HighLow=1;    //1:表示信号超过1KHz;0:表示信号低于1KHz。       
  8. void InitialHigh( void )       
  9. {       
  10.     IE=0; IP=0; HighLow=1;       
  11.     TMOD = (TMOD & 0xf0) | 0x02; TH0=-200; TL0=TH0; PX0=1; T0=1;        
  12.     TMOD = (TMOD & 0x0f) | 0x50; TH1=0; TL1=0; T1=1; ET1=1;       
  13.     Us100=0; Second=0; K64=0;       
  14.     oldK64=0; oldT1=0;       
  15.     TCON |= 0x50;  //同时置 TR0=1; TR1=1;       
  16.     EA = 1;       
  17. }       
  18. void InitialLow( void )       
  19. {       
  20.     IE=0; IP=0; HighLow=0;       
  21.     TMOD = (TMOD & 0xf0) | 0x02; TH0=-200; TL0=TH0; ET0=1; TR0=1;       
  22.     INT1 = 1; IT1=1; EX1=1;       
  23.     Us100=0; Second=0; K64=0;       
  24.     oldK64=0; oldT1=0;       
  25.     EA = 1;       
  26. }       
  27. void T0intr( void ) interrupt 1       
  28. {    
  29.     if( HighLow==0 ) ++us100;       
  30.     else if( ++us100 >= 10000 )       
  31.     {     
  32.         unsigned int tmp1, tmp2;       
  33.         TR1=0; tmp1=(TH1<<8) + (TL1); tmp2=K64; TR1=1;       
  34.         fcy=((tmp2-oldK64)<<16) + (tmp1-oldT1);       
  35.         oldK64=tmp1; oldT1=tmp2;       
  36.         Second++;       
  37.         us100=0;       
  38.     }       
  39. }       
  40. void T1intr( void ) interrupt 3    
  41. {    
  42.     ++K64;    
  43. }       
  44. void X1intr( void ) interrupt 2       
  45. {    
  46.     static unsigned char sts=0;       
  47.     switch( sts )        
  48.     {       
  49.     case 0:    
  50.         sts = 1;   
  51.         break;       
  52.     case 1:   
  53.         oldT0=TL0;    
  54.         oldus=us100;    
  55.         sts=2;    
  56.         break;       
  57.     case 2:        
  58.         {       
  59.             unsigned char tmp1, tmp2;       
  60.             TR0=0; tmp1=TL0; tmp2=us100; TR0=1;       
  61.             fcy = 1000000L/( (tmp2-oldus)*100L + (256-tmp1)/2 );       
  62.             Second ++;       
  63.         }       
  64.         Sts = 0;       
  65.         break;       
  66.     }       
  67. }       
  68. void main( void )       
  69. {       
  70.     if( HighLow==1) InitialHigh(); else InitialLow();       
  71.     While(1)       
  72.     {       
  73.         if( Second != 0 )       
  74.         {       
  75.             Second = 0;       
  76.             //display fcy  引用前面的数码管驱动程序,注意下面对T0中断服务程序的修改       
  77.             {    
  78.                 unsigned char i;       
  79.                 for( i=0; i<8; i++ )   
  80.                 {    
  81.                     Display(i, fcy%10); fcy /= 10;    
  82.                 }       
  83.             }       
  84.             if( HighLow==1 )       
  85.             {   
  86.                 if( fcy<1000L )   
  87.                 {    
  88.                     InitalLow();   
  89.                 }         
  90.                 else if( fcy>1000L )   
  91.                 {   
  92.                     InitalHigh();   
  93.                 }     
  94.             }   
  95.         }       
  96.     }       
  97. }       
  98. //修改T0的中断服务程序,让它在完成时标的功能时,同时完成数码管显示刷新       
  99. void T0intr( void ) interrupt 1       
  100. {       
  101.     static unsigned char ms = 0;       
  102.     if( HighLow==0 ) ++us100;       
  103.     else      
  104.         if( ++us100 >= 10000 )       
  105.         {    
  106.             unsigned int tmp1, tmp2;       
  107.             TR1=0; tmp1=(TH1<<8) + (TL1); tmp2=K64; TR1=1;       
  108.             fcy=((tmp2-oldK64)<<16) + (tmp1-oldT1);       
  109.             oldK64=tmp1; oldT1=tmp2;       
  110.             Second++;       
  111.             us100=0;       
  112.         }       
  113.         if( ++ms >= 10 )   
  114.         {    
  115.             ms=0; DisplayBrush();   
  116.         } //1ms数码管刷新       
  117. }      
 
相关文章:

上一页 123456789 下一页
 
最新开源项目
 
 
  查看更多...  
 
本站相关产品   淘宝网店
 




 
  查看更多...  

 

本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4