频率计原理及用单片机AT89C52设计时的程序代码---求高手帮助急 - 仪器网
仪器社区

频率计原理及用单片机AT89C52设计时的程序代码---求高手帮助急

1282188191 2011-07-14
评论
全部评论
ozhengshun
简单的频率计
#include "reg51.h"

/********IO引脚定义***********************************************************/
sbit Fin=P1^3; //测量频率管脚
sbit Fout=P1^7; //发生频率管脚,可用单芯线将P1。7脚的频率输出连接P1。3的输入脚

/********数据定义*************************************************************/
code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};//共阴数码管段值表 0-9 - 空
unsigned char l_tmpdate[8]; //显示的缓冲区
bit int_flag; //中断事件的响应
unsigned int fry; //保存的频率值

/********函数声明*************************************************************/
void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数
void delay(unsigned int timer); //延时子函数
void Mee_F(void); //测频函数
void Mee_T(void); //测周函数
void Fry_Mee(void); //测频测周选择

/***********主函数开始********************************************************/
void main()
{
unsigned int tmp; //数据转换缓冲
unsigned int i=2000; //显示延时,提高亮度
EA=1; //开总中断
TMOD=0x11; //定时器工作方式1
TH0=256-(50000/256); //定时器初值
TL0=256-(50000%256);
TH1=256-500/256;
TL1=256-500%256;
ET0=1; //开定时器0 中断
ET1=1; //开定时器1 中断
TR1=1; //启动定时器1

while(1)
{
Fry_Mee(); //开始测量

l_tmpdate[0]=fry/10000; //测量完后将整型数分离出来,进行显示
tmp=fry%10000;
l_tmpdate[1]=tmp/1000;
tmp=tmp%1000;
l_tmpdate[2]=tmp/100;
tmp=tmp%100;
l_tmpdate[3]=tmp/10;
l_tmpdate[4]=tmp%10;
while(i--) //显示延时
display(l_tmpdate,5); //显示频率
i=2000;
}
}

/**********定时器0入口函数**************************************************/
void time0(void) interrupt 1
{
int_flag=1; //中断标志
}

/**********定时器1入口函数**************************************************/
void time1(void) interrupt 3 //定时器1的中断函数,我们用来产生频率
{
TH1=256-1000/256; //重设初值
TL1=256-1000%256;
Fout=!Fout; //取反 产生频率,也就是频率发生器,可改变计数值改变频率
}

/**********测频测周选择**************************************************/
void Fry_Mee(void)
{
if(fry<2000) //小于 2k 测周
Mee_T();
else if(fry>=2000) //大于2k 测频
Mee_F();
}

/**********测频,原理:开一个标准的50ms计数中断,对被测信号计数**********/
void Mee_F(void)
{
bit lhj_old=1,lhj_new=1; //定义状态
unsigned int f_count=0; //计数临时值
int_flag=0;
TH0=256-50000/256; //定时器初值 50ms
TL0=256-50000%256;
TR0=1; //启动计数器
while(1) //循环 测频
{
lhj_new=Fin; //取得现在的 频率发生引脚状态
if(lhj_old!=lhj_new) //与前一个时刻 旧值 比较,如果不同
f_count++; //则 计数加1
lhj_old=lhj_new; //将新值赋给旧值
if(int_flag) //如果到了定时时间
{
TR0=0; //关闭定时器0
fry=f_count*10; //计算频率,定时 50ms计数 每1个周期 计2次 所以 1s内计数= f_count*20/2=f_count*10
return; //返回 跳出循环
}
}
}

/**********测周,原理:以被测信号的一个周期为中断源,读取定时器的值为计数值***************/
void Mee_T(void)
{
bit lhj_old=0,lhj_new=0; //定义状态
unsigned char temp_flag=0;
unsigned int 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(unsigned char *lp,unsigned char lc)
{
unsigned char i; //定义变量
P2=0; //端口2为输出
P1=P1&0xF8; //将P1口的前3位输出0,对应138译码器的输入脚,全0为diyi位数码管
for(i=0;i P2=table[lp[i]]; //查表法得到要显示数字的数码段
delay(10); //短延时
P2=0; //清0端口,准备显示下位
if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到P13数据
break;
P1++; //下一位数码管
}
}

/*************延时子函数 *******************************************/
void delay(unsigned int timer)
{
while(timer--);
}
11 0 2011-07-15 0条评论 回复
jftijbcfik
我来帮你写写
8 0 2011-07-15 0条评论 回复
您可能感兴趣的社区主题
加载中...
发布 评论