⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 int0.c

📁 自己单片机板c程序
💻 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 + -