×
嵌入式 > 技术百科 > 详情

定时器中断—频率计程序

发布时间:2020-06-12 发布时间:
|

/*注:定时器中断的例子,简单的频率计,初学者留意各引脚电
 压极性和电压值,不可超出5V,我们只是做学习实验,不要
 超出51hei单片机学习板的承受范围,否则要求对电子非常熟悉,
不然会烧坏芯片, 版权:www.51hei.com,注意:P1.3与P1.7要相连接
如果是测量外部频率要共地.
*/
#include //头文件
#include
#define uchar unsigned char//宏定义
#define uint  unsigned int
sbit Fin=P1^3;  //测量频率管脚
sbit Fout=P1^7;  //发生频率管脚
uchar code table[]={0x3f,0x06,0x5b,//数码管显示的数值
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,};
void display(uchar *lp,uchar lc);  //显示子函数
void delay(); //延时子函数
void mee_F(); //测频率子函数
void mee_T(); //测周期子函数
void Fry_mee(); //测频测周选择的子函数
uchar l_tmpdata[8]; //程序显示的缓冲区
bit int_flag; //中断事件相应的标志
uint fry;   //保存的频率值
void init() ;
void main() //主函数
{
init(); // 调用初始化函数

}
void init()   //初始化函数
{
uint tmp; //数据转换缓冲区
uint i=2000;//显示延时,提高亮度
EA=1; //打开总中断
TMOD=0x11;//工作方式3
TH0=256-(50000/256); //装入初值
TL0=256-(50000%256);
TH1=256-500/256;
TL0=256-500%256;
ET0=1;  //定时器0开
ET1=1;  //定时器1开
TR1=1;  //启动定时器1
     while(1)
     {
 Fry_mee();//开始测量
 l_tmpdata[0]=tmp/10000;  //测量完后将整数分离出来
 tmp=tmp%10000;   //进行显示
  l_tmpdata[1]=tmp/1000;
 tmp=tmp%1000;
 l_tmpdata[2]=tmp/100;
 tmp=tmp%100;
 l_tmpdata[3]=tmp/10;
 l_tmpdata[4]=tmp%10;
  while(i--)  //显示延时,提高亮度
 {
  display(l_tmpdata,5); //用数字显示频率
 }
   i=2000;  //从新装入初值
     }
}
void time0() interrupt 1 //定时器0的中断函数
{
 int_flag=1;    //中断标志
}
void time1() interrupt 3   //定时器1的中断函数,用来产生频率
{
 TH1=(65536-1000)/256; //从新赋值
 TL1=(65536-1000)%256;
 Fout=!Fout;  //?反,产生频率,即频率发生器
}
void Fry_mee()
{
 if(fry<2000)   //?于2k的,侧周
    mee_T();
 else if(fry>=2000) //大于2k的,测频
  mee_F();
}
//测频原理:用一个标准的50ms计数中断,对被测信号计数
void mee_F()  //测频子函数
{
 bit lhj_old=1,lhj_new=1;  //定义起始状态
 uint f_count=0;//计数变量
 int_flag=0;
 TH0=(65536-50000)/256;//定时器,初值50ms
 TL0=(65536-50000)%256;
 TR0=1;    //启动定时器0
     while(1)   //死循环,测频
     {
 lhj_new=Fin; //?现在频率引脚的状态
 if(lhj_old!=lhj_new) //与前一刻的值比较
 f_count++;
 lhj_old=lhj_new; //将新值赋给旧值
 if(int_flag) //如果到了定时时间
   {
  TR0=0; //关闭定时器0
  fry=f_count*10; //计算频率,f_count=f_count*20/2
  //一个周期有2个跳变,20个周期为1s
  return;     //返回
   }
     }
}
//测周原理:以被测信号的一个周期为中断源,对单片机及其
//周期进行计数读?定时器的值为计数值
void mee_T() //测周子函数
{
 bit lhj_old=0,lhj_new=0; //定义初始状态
 uchar temp_flag=0;
 uint t_count;  //计数变量
 TH0=0;   //赋初始值
 TL0=0;
 while(1) //死循环,测周
 {
  lhj_new=Fin; //取现在的频率发声引脚的状态
   if(lhj_old&&!lhj_new) //当下降沿来临时,启动定时器
   {
  temp_flag++;
  TR0=1;   //启动定时器并开始计数
   }
  if(temp_flag==2)
  {
  TR0=0; //停止计数
  t_count=TH0*256+TL0;//取得当前的计数值
  fry=1000000/t_count;//计算频率,这个1000000是
  //晶振12M经12分频的计数脉冲
  return;   //返回
  }
  lhj_old=lhj_new;
     }
}
void display(uchar *lp,uchar lc)  //显示子函数
{
 uchar i;
 P2=0;
 P1=0xf8;
 for(i=0;i {
  P2=table[lp[i]];
  delay();
  if(i==7)
  break;
  P2=0;
  P1++;
 }
}
void  delay()  //延时子函数
{
 _nop_();_nop_();_nop_();_nop_();_nop_();
}

 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
FPGA及CPLD应用领域不断拓展