单片机笔记(3)定时计数与中断

本文为博主 日月同辉,与我共生,csdn原创首发。希望看完后能对你有所帮助,不足之处请指正!一起交流学习,共同进步!

> 发布人:https://blog.csdn.net/LIN___IT?spm=1011.2266.3001.5343

> 欢迎你为独创博主日月同辉,与我共生点赞❤❤❤+关注👍+收藏🌹+评论☺。

系列专栏:CSDN-单片机学习系列🎁

> 我的格言是:“尽最大努力,做最好的自己!💪

版权声明:本文为CSDN博主「日月同辉,与我共生」的原创文章,CSDN独一份。

75c55e0821c54ad180cd3ae3e1a7ed84.png

目录

一、中断基础                                                                                 

1.1中断寄存器IE

1.2中断寄存器IP

1.3中断优先级

1.4中断初始化

1.5外部中断服务函数

二、中断举例                                                                                 

三、定时计数器基础                                                                       

3.1工作原理

3.2定时计数器寄存器TMOD

3.3定时计数器寄存器TCON

3.4初值X的设置

 3.5初始化

3.6定时计数器中断服务函数

四、定时器计数器举例                                                                  

一、中断基础                                                                                 

1.1中断寄存器IE

109814651b1644bcaa11dcdfd7474f39.png

EX0/EX1:外部中断 INT0 /INT1允许位。当 EX0 /EX1为 1,允许外部中断INT0/INT1 中断。当 EX0 /ET1为0 ,不允许外部中断 0 /1中断。

ET0:定时器T0溢出中断允许位.。当 ET0 = 1, 允许 T0 中断。当 ET0 = 0, 不允许 T0 中断。ET1同上。

ES:串行口中断允许位。当 ES = 1, 允许串口中断。当 ES = 0, 不允许串口中断。

EA:总允许位。当 EA = 1, CPU开开放中断。当 EA = 0, CPU 不开放中断。

1.2中断寄存器IP

c892738c51044b6dbffd4a46bd1f682d.png

PS为串口优先级,PT0/PT1为定时器计数器优先级,PX0/PX1为外部中断优先级。设置为1,高优先级,设置为0,低优先级。

1.3中断优先级

1.优先级高的要比优先级低优先执行:当优先级在执行前或执行过程中,有优先级高的要执行,则打断低优先级的执行,优先级先执行。

优先级相同时,按顺序执行。

2.中断源自然优先级:外部中断0>定时计数器0>外部中断1>定时计数器1>串行口

3.优先级可分为软件设置优先级(寄存器IP设置)和自然优先级,一般地,软件设置优先级>自然优先级。

4.软件设置优先级可以借用IP寄存器进行设置,设置成1,为高优先级,设置为0,为低优先级。

f8a00f2507624c0f95382e007fe8d781.png

1.4中断初始化

中断初始化,首先打开总中断EA=1和EX0/EX1 ,设置触发方式IT0/IT1。现在市场上有很多数字型模块,比如红外模块,比如声敏模块等等,他们在识别到物品或者声音响度达到一定值时,就会被触发,进而输出低电平。这种情况下,我们一般选择使用单片机的外部中断,模式设置为低电平触发,高电平则是关闭中断不触发。另外按键的使用,一般是写在主函数里面,通过不断的进行扫描判断,但是这样极大的占用了单片机的CPU资源,所以大部分时候都是将按键连接在外部中断触发引脚上,将模式配置为下降沿触发模式,检测到外部中断的引脚从高电平被拉低为低电平时,触发中断。

5269203d8692464babdb227e258480e4.png

1.5外部中断服务函数

外部中断0入口编号为0,外部中断1入口编号为2。格式:void init() interrupt n

中断服务函数不能被调用,无返回值。

二、中断举例                                                                                 

初始化:

void EX1_init()
{
	IT1=1;//下降沿触发
	EA=1;//开启总中断
	EX1=1;//开启外部中断1
}

中断服务函数:

void time1() interrupt 2 //中断服务函数--外部中断1
{
	switch(P2&0x0f)//判断哪个按键按下
	{
		case 0x0e:
			num++;if(num>9999) num=0;//实现加法运算
		  break;
		case 0x0d:
			num--;if(num>9999) num=9999;//实现减法运算
		  break;
		case 0x0b:
			num=0;//实现清0
		  break;
		case 0x07:
			num=8888;//数码管显示8888
		  break;
		default:break;
	}
}

三、定时计数器基础                                                                       

3.1工作原理

定时器计数器本质上都是+1计数器。它们工作的动力源于脉冲,脉冲可以分为一个是由系统的时钟振荡器输出脉冲经12分频(机器周期)后送来,另一个是T0或T1引脚输入的外部脉冲信号。当定时器计数器溢出(此时加到了0xff)时,TCON寄存器的TF0/TF1会自动置1,从而触发中断请求,所以计数值=溢出值-初值。

3.2定时计数器寄存器TMOD

47463e5834a9448aab50504d61580d82.png

共有8位,可以分为2个定时计数器,高4位定时计数器T1,低4位定时计数器T0,每一个定时计数器分别是GATE、C/T、M1、M0。

GATE:门控位。GATE=0时,只要用软件使TCON中的TR0或TR1为1,就可以启动定时器/计数器工作;GATA=1时,要用软件使TR0或TR1为1,同时外部中断引脚也为高电平时,才能启动定时/计数器工作。即此时定时器的启动多了一条件。

C/T :定时/计数模式选择位。 C/T =0为定时模式; C/T =1为计数模式。

M1、M0:工作方式设置位。定时/计数器有四种工作方式,由M1、M0进行设置。我们通常会使用方式1(16位的定时计数器)

0a4c443c3e3c4aeb9f290ff9df1c8327.png

3.3定时计数器寄存器TCON

TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出时由硬件自动置TF1为1。单片机响应中断后TF1由硬件自动清0。

TR1(TCON.6):T1运行控制位。TR1置1时,T1开始工作;TR1置0时,T1停止工作。TR1由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。

TF0(TCON.5):T0溢出中断请求标志位,其功能与TF1同。

TR0(TCON.4):T0运行控制位,其功能与TR1类同。

3.4初值X的设置

通过上面的解释,我们知道定时计数器溢出时,会触发中断一次,所以当我们要设置某个定时值/计数值时,要求出其初值。

以定时器T0为例,选择工作方式1(16位),晶振频率为12Mhz,机器周期是等于12个时钟周期,所以机器周期T=12×(1/12)=1us,假设我要定时5ms(5000us),那么定时器定时5ms需要经历5000us/1us=5000个机器周期,那么初值=溢出的值2^16-5000,结果是个16位2进制,需要将高8位转成十六进制赋予TH0,低8位转成十六进制赋予TL0。

目前,将初值分成高8位和低8位,有两种方法。一、提取高8位和低8位,手算出结果。二、公式法。高8位=初值/256,低8位=初值%256。

据上面可得初值X=2^16-自己设置的值/(12/fosc)

这里的2^16是工作方式1,跟位数有关,比如工作方式0(13位),就是2^13。

06887b9d3ccb4bf2a74785a662f7a4c3.jpg

 3.5初始化

初始化首先要计算出高8位和低8位,如果用到中断,通常打开要打开总断总开关EA=1,定时计数器中断总开关ET0=1/ET1=1,至于定时器启动TR0/TR1是否置1,需要看设计要求。优先级可以设置,也可以不设置,具体看设计要求。

3.6定时计数器中断服务函数

定时器计数器T0入口编号为1,T1入口编号为3。为提高计数/定时精度和防其他模块干扰,进入中断服务函数时,暂时关闭定时计数器TR0/TR1,结束时重新打开,另外,需要重新赋初值,以便下次继续使用无误。

格式:void timer() interrupt n

中断服务函数不能被调用,无返回值。

四、定时器计数器举例                                                                   

初始化:

void Timer0_Init()		//1毫秒 @12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	EA=1;           //总中断打开
	ET0=1;          //定时器0的中断打开
	TR0 = 1;				//定时器0开始计时
}

中断服务函数:

void timer0() interrupt 1 //定时器0的中断服务函数
{
	TR0=0;            //关闭定时器0
	if(systemflag==1)//软件拓充定时器
	{
		systemTimer++;
	}
	display();        //数码管显示函数放在定时器中断服务函数,实现延时功能
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TR0=1;            //再次打开定时器0
}

———————————————————————————————————————————

本次介绍了定时计数与中断,同时提供初始化代码和中断服务函数代码,帮助大家理解相关编码思路。

hi!我是博主日月同辉,与我共生🔥,喜欢或期待更好作品的,可以关注一下我日月同辉,与我共生🙏🙏🙏,我们一起进步,另外欢迎大家的点评😊!!!

关注博主:点击支持——日月同辉,与我共生
———————————————————————————————————————————

 

 

 

 

 

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值