定时器中断触发原理
在 51 单片机中,定时器中断的触发流程如下:
- 定时器配置:对定时器的工作模式、初值等进行设置。
- 计数操作:定时器开启后,依据系统时钟频率和预分频系数开始计数。
- 中断触发:当计数值达到最大值(溢出)时,会置位定时器溢出标志位。
- 中断响应:若中断允许,单片机就会暂停当前程序,转而执行对应的定时器中断服务程序。
- 中断返回:中断服务程序执行完毕后,单片机返回主程序继续执行。
简单示例
下面是一个 51 单片机定时器 0 的简单示例,该示例将定时器 0 设置为模式 1(16 位定时器),每 50ms 触发一次中断,在中断服务程序中对一个变量进行计数,计满 20 次(即 1 秒)时,翻转 P1.0 引脚的电平。
- #include <reg51.h>
-
- // 定义定时器0溢出次数计数器
- unsigned char count = 0;
-
- // 定时器0中断服务程序
- void timer0_isr() interrupt 1 {
- // 重新加载初值,以实现每50ms触发一次中断
- TH0 = (65536 - 50000) / 256;
- TL0 = (65536 - 50000) % 256;
- count++;
- if (count >= 20) {
- // 每1秒翻转一次P1.0引脚的电平
- P1 ^= 0x01;
- count = 0;
- }
- }
-
- void main() {
- // 配置定时器0为模式1
- TMOD = 0x01;
- // 加载初值,以实现每50ms触发一次中断
- TH0 = (65536 - 50000) / 256;
- TL0 = (65536 - 50000) % 256;
- // 使能定时器0中断
- ET0 = 1;
- // 使能全局中断
- EA = 1;
- // 启动定时器0
- TR0 = 1;
-
- while (1) {
- // 主循环可以处理其他任务
- }
- }
复制代码
代码解释- 头文件包含:#include <reg51.h>包含了 51 单片机的寄存器定义。
- 全局变量:count用于记录定时器 0 的溢出次数。
- 中断服务程序:timer0_isr()是定时器 0 的中断服务程序,当中断触发时会执行该程序。在程序里,重新加载定时器初值,使定时器每 50ms 溢出一次;对count进行计数,计满 20 次(即 1 秒)时,翻转 P1.0 引脚的电平,并将count清零。
- 主函数:
- 配置定时器 0 为模式 1。
- 加载定时器初值,让定时器每 50ms 溢出一次。
- 使能定时器 0 中断和全局中断。
- 启动定时器 0。
- 进入无限循环,主循环可处理其他任务。
这个示例展示了如何使用 51 单片机的定时器 0 产生中断,并在中断服务程序中执行特定任务。
定时器 0 每 50ms 触发一次计数并非定时器本身固有的特点,而是通过对定时器进行一系列设置来实现的。下面为你详细说明在 51 单片机里如何设置以达成每 50ms 触发一次计数。
关键设置因素
1. 工作模式选择
51 单片机的定时器有多种工作模式,不同模式下定时器的计数范围和功能有所不同。以定时器 0 为例,一般选用模式 1(16 位定时器模式),因为该模式计数范围较大,能够满足较长时间间隔的定时需求。
2. 初值计算与加载
定时器的计数是从初始值开始的,当计数值达到最大值(对于 16 位定时器,最大值为 65535)时会产生溢出中断。要实现每 50ms 触发一次中断,就需要根据单片机的晶振频率来计算并加载合适的初值。
假设单片机的晶振频率为 11.0592MHz,机器周期是晶振周期的 12 倍,即机器周期
要定时 50ms,需要的机器周期数
那么定时器的初值 X=65536−N=65536−46080=19456。将这个初值拆分为高 8 位和低 8 位:
- 高 8 位:TH0=(65536−46080)/256=76(十六进制为 0x4C)
- 低 8 位:TL0=(65536−46080)%256=160(十六进制为 0xA0)
3. 中断使能
要让定时器溢出时能够触发中断,需要使能定时器中断和全局中断。通过设置相应的中断允许寄存器(如ET0和EA)来实现。
- #include <reg51.h>
-
- // 定时器0中断服务程序
- void timer0_isr() interrupt 1 {
- // 重新加载初值,以实现每50ms触发一次中断
- TH0 = (65536 - 50000) / 256;
- TL0 = (65536 - 50000) % 256;
- // 其他中断处理代码
- }
-
- void main() {
- // 配置定时器0为模式1
- TMOD = 0x01;
- // 加载初值,以实现每50ms触发一次中断
- TH0 = (65536 - 50000) / 256;
- TL0 = (65536 - 50000) % 256;
- // 使能定时器0中断
- ET0 = 1;
- // 使能全局中断
- EA = 1;
- // 启动定时器0
- TR0 = 1;
-
- while (1) {
- // 主循环可以处理其他任务
- }
- }
复制代码
- TMOD = 0x01;:把定时器 0 设置为模式 1。
- TH0 = (65536 - 50000) / 256; 和 TL0 = (65536 - 50000) % 256;:计算并加载定时器 0 的初值,以实现每 50ms 触发一次中断。
- ET0 = 1;:使能定时器 0 中断。
- EA = 1;:使能全局中断。
- TR0 = 1;:启动定时器 0。
综上所述,定时器 0 每 50ms 触发一次计数是通过对工作模式、初值以及中断使能等方面进行设置来实现的。
|