打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
c语言单片机程序实例:低频频率计

c语言单片机程序实例:低频频率计



实例目的:学时定时器、计数器、中断应用
说明:选用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)。
unsigned int us100;              //对100us时间间隔单位计数,即有多少个100us。
unsigned char Second;
unsigned int K64;                //对64K单位计数,即有多少个64K     
unsigned char oldT0;
unsigned int oldus, oldK64, oldT1;
unsigned long fcy;               //存放频率值,单位为Hz
bit HighLow=1;                   //1:表示信号超过1KHz;0:表示信号低于1KHz。
void InitialHigh( void )
{
     IE=0; IP=0; HighLow=1;
TMOD = (TMOD & 0xf0) | 0x02; TH0=-200; TL0=TH0; PX0=1; T0=1;
     TMOD = (TMOD & 0x0f) | 0x50; TH1=0; TL1=0; T1=1; ET1=1;
     Us100=0; Second=0; K64=0;
     oldK64=0; oldT1=0;
     TCON |= 0x50;      //同时置 TR0=1; TR1=1;
     EA = 1;
}
void InitialLow( void )
{
     IE=0; IP=0; HighLow=0;
TMOD = (TMOD & 0xf0) | 0x02; TH0=-200; TL0=TH0; ET0=1; TR0=1;
     INT1 = 1; IT1=1; EX1=1;
     Us100=0; Second=0; K64=0;
     oldK64=0; oldT1=0;
     EA = 1;
}
void T0intr( void ) interrupt 1
{    if( HighLow==0 ) ++us100;
else
if( ++us100 >= 10000 )
{    unsigned int tmp1, tmp2;
TR1=0; tmp1=(TH1<<8) + (TL1); tmp2=K64; TR1=1;
fcy=((tmp2-oldK64)<<16) + (tmp1-oldT1);
oldK64=tmp1; oldT1=tmp2;
Second++;
us100=0;
}
}
void T1intr( void ) interrupt 3  {    ++K64;   }
void X1intr( void ) interrupt 2
{    static unsigned char sts=0;
switch( sts )
{
case 0: sts = 1; break;
case 1: oldT0=TL0; oldus=us100; sts=2; break;
case 2:
{
     unsigned char tmp1, tmp2;
     TR0=0; tmp1=TL0; tmp2=us100; TR0=1;
     fcy = 1000000L/( (tmp2-oldus)*100L + (256-tmp1)/2 );
     Second ++;
}
     Sts = 0;
     break;
     }
}
void main( void )
{
if( HighLow==1) InitialHigh(); else InitialLow();
     While(1)
     {
if( Second != 0 )
{
Second = 0;
//display fcy  引用前面的数码管驱动程序,注意下面对T0中断服务程序的修改
{    unsigned char i;
     for( i=0; i<8; i++ ){ Display(i, fcy%10); fcy /= 10; }
}
if( HighLow==1 )
if( fcy<1000L ){ InitalLow();}  
              else
                   if( fcy>1000L ){ InitalHigh();}
}
     }
}
//修改T0的中断服务程序,让它在完成时标的功能时,同时完成数码管显示刷新
void T0intr( void ) interrupt 1
{
     static unsigned char ms = 0;
     if( HighLow==0 ) ++us100;
else
if( ++us100 >= 10000 )
{    unsigned int tmp1, tmp2;
TR1=0; tmp1=(TH1<<8) + (TL1); tmp2=K64; TR1=1;
fcy=((tmp2-oldK64)<<16) + (tmp1-oldT1);
oldK64=tmp1; oldT1=tmp2;
Second++;
us100=0;
}
     if( ++ms >= 10 ){ ms=0; DisplayBrush(); } //1ms数码管刷新
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
51单片机之精华(三)
延时函数
PID温度控制系统源序程序
硬盘ide接口驱动程序——80C51
x264源码阅读笔记2(zhuantie)
各种排序算法C++实现(冒泡,选择,插入,快速,归并,堆)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服