#学习笔记 一些定时中断的笔记

一、TH1 TH0是怎么得的?
因为1个机器周期=6个状态周期=12个振荡周期,所以对于12mhz的晶振,振荡周期/时钟周期为1/12us,一个机器周期为1us,也就是1us产生一次计数。
理解参考了
https://blog.csdn.net/yueniaoshi/article/details/52530156 ;https://blog.csdn.net/henryheheng/article/details/80356711

中断方式1中有16位定时器,最大计数为2^16 = 65536。如果要以50ms为一个单位计时,那么就需要1100050=50000个机器周期。需要设置一个TH0,TL0来作为50ms溢出的阈值。ps.它们不是两个数字,而是一个数字的十位和个位。
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
如何理解?TH0为高八位,TL0为低八位。八位的二进制11111111转化为十进制是255。把TH0和TL0分别看作十位和个位的一个两位数,这个算法就相当于是一个256进制,逢256进1。

同时还有中断方式0,13位定时器,计算方法同理。

具体的值这个网站罗列了一些:http://www.sohu.com/a/202755409_464086

二、中断状态的设置
https://blog.csdn.net/u014453898/article/details/56857089
https://blog.csdn.net/qq_22512533/article/details/46961545
https://www.jianshu.com/p/f9a9ad575a3c
三、我所用到的中断
红外传感器测量心率。思路是测量每个心跳脉冲的时间,从而计算每分钟跳了多少下。
/定时器0初始化程序**/
void time_init()
{

EA   = 1;	 	  //开总中断
TMOD = 0X01;	  //定时器0、定时器1工作方式1
ET0  = 1;		  //开定时器0中断 
TR0  = 1;		  //允许定时器0定时

}

/外部中断0初始化程序*****/
void init_int0() //外部中断0初始化程序
{

EX0=1;			  //允许外部中断0中断
EA=1;	 		    //开总中断
IT0 = 1; 		  //外部中断0负跳变中断

}

//按键扫描(显示心率)******//

void KeyScanf3()
{

if(KeyRate_P==0) //功能按键被按下

{

	 LcdGotoXY(0,0);				          // 定位到(0,0)
     LcdPrintStr("   Heart Rate   ");	      // 显示标题
     LcdGotoXY(1,0);
	 LcdPrintStr("               ");
	 time_init();                     //初始化定时器
	 init_int0();	                    //外部中断0初始化程序
	 rate=0;i=0;timecount=0;flag_en=0;flag_ready=0;
	 time[0]=0;time[1]=0;time[2]=0;time[3]=0;time[5]=0;time[6]=0;
	 DelayMs(10);
	 while(!KeyRate_P);
	 DelayMs(10);
	 while(1)
 {	
	 if (flag_ready == 0)
	 {
	  rate=0;
	 }
	 else
	 {
	    if(flag_en == 1)
		 {
			rate = 60000/(time[1]/5+time[2]/5+time[3]/5+time[4]/5+time[5]/5);
	 	 }
	 }		  
		LcdGotoXY(1,7);
	    LcdPrintNum(rate);
        DelayMs(100);
	    if(KeyRate_P==0)
    	{
	     break;				
	    }
  }
	LcdShowInit();					// 液晶显示内容恢复为检测界面的
	DelayMs(10);						// 延时等待,消除按键按下的抖动
	while(!KeyRate_P);			// 等待按键释放
	DelayMs(10);					
}

}

/外部0中断服务程序***/
void int0() interrupt 0
{

	EX0=0;//暂时关外部中断

	
 if(timecount <= 20 && timecount>=8)
	
	{			
		time[i]=timecount*50+TH0*0.256+TL0/1000;//算出间隔时间
		TH0 = 0x4c;
		TL0 = 0x00;     // 50ms	 11.0592M
		timecount=0;//50ms计数清零
		i++;
		flag_en = 1;
		
		if(i==6)//记录到超过等于6次时间
		{
			i=1;//计数从1开始
			flag_ready = 1;//防止第一次打开功能乱闪。如果没有这个语句,会闪6次。
		}								
	} else 
	{

		timecount = 0;
	}
	EX0=1;

}
/定时器0中断服务程序**/
void time0_int() interrupt 1
{

TH0 = 0x4c;
TL0 = 0x00;     // 50ms	 11.0592M
timecount++;//每50ms一次计数
if(timecount>40)     //当超过40*50ms=2s没有检测到信号停止显示
{
		i=0;//数据个数清零
		timecount=0;//50ms计数清零
		TR0=0;//定时器关
		TH0 = 0x4c;
		TL0 = 0x00;     
}

}

你可能感兴趣的:(学习笔记,单片机,定时中断)