📄 int0.c
字号:
/*定时器中断例子,简单的频率计,初学者留意各引脚电压极性和电压值,不可超出5V,我们只是做学习实验,不要超出板子范围
否则要求对电子非常熟悉*/
#include "reg51.h"
#include <intrins.h>
/********************************************************************/
void delay_nms(unsigned int n);//delay function
sbit Fin=P1^3; //测量频率管脚
sbit Fout=P1^7; //发生频率管脚
//可用单芯线将P1。7脚的频率输出连接P1。3的输入脚
void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数
void delay();//延时子函数,5个空指令
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 Mee_F(void); //测频函数
void Mee_T(void); //测周函数
void Fry_Mee(void); //测频测周选择
void main()
{
unsigned int tmp; //数据转换缓冲
unsigned int i=2000; //显示延时,提高亮度
EA=1; //开总中断
TMOD=0x11; //工作状态
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;
}
}
void time0(void) interrupt 1 //定时器0的中断函数
{
int_flag=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为第一位数码管
for(i=0;i<lc;i++){ //循环显示
P2=table[lp[i]]; //查表法得到要显示数字的数码段
delay(); //延时5个空指令
if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据
break;
P2=0; //清0端口,准备显示下位
P1++; //下一位数码管
}
}
void delay(void) //空5个指令
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -