51单片机入门教程(5)——定时器中断

  • 一、中断的概念
  • 二、定时器中断
    • 2.1 软件延时的不足
    • 2.2 中断寄存器
      • 2.2.1 中断允许控制寄存器 IE
      • 2.2.2 定时器工作方式寄存器 TMOD
      • 2.2.3 定时器控制寄存器 TCON
      • 2.2.4 定时器初值寄存器 THx/TLx
    • 2.3 定时器中断程序写法

写在开头: 中断是包括单片机在内的所有微处理器很 重要的功能之一,初学单片机必须这一部分的知识。

一、中断的概念

先看百度百科是怎么定义中断的:

中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
—— 百度百科

那么怎么理解中断?看下面的例子。

关于中断
小A正在学习。这时,他的朋友小B叫他一块儿吃鸡,小A停止学习,转去玩吃鸡游戏。玩了几局后,关掉游戏,继续学习。
关于中断优先级
小A正在学习。这时,他的朋友小B叫他一块儿吃鸡,小A停止学习,转去玩吃鸡游戏,(吃鸡过程中,小A女朋友打来电话,于是挂机游戏,去接电话,接完电话,继续游戏。)玩了几局后,关掉游戏,继续学习。

  • 几个重要概念:

中断:小A学习被小B打断的过程就称为中断
中断源:小B被称为中断源
中断服务程序:小A执行的玩游戏操作称为中断服务程序
中断优先级:小A女朋友的电话比游戏优先级

在89c52单片机中,有3类中断源:

1、外部中断:当外部中断引脚信号产生跳变(低电平→高电平)时引起中断。
2、定时器/计数器中断:当计数器计满溢出时引起跳变。
3、串口中断:串行端口完成一帧数据的发送/接受时引起(如蓝牙传输)。

其优先级如下表:

中断源 优先级 中断服务号
INT0 – 外部中断0 最高 0
T0 – 定时器/计数器0中断 第2 1
INT1 – 外部中断1 第3 2
T1 – 定时器/计数器1中断 第4 3
串口中断 第5 4
T2 – 定时器/计数器2中断 最低 5

下面以定时器中断为例,讨论中断的编程方法。

二、定时器中断

2.1 软件延时的不足

根据现有的知识,如果要在程序中等待一端时间,想到的操作应该是通过执行若干次空指令,达到延时的效果。
如下:

//延时xms
void delayms(uint xms){uint i,j;for(i = 0; i < xms; ++i)for(j = 0; j < 110; ++j);
}

但是,假设要实现以下功能:

1、8位数码管动态扫描显示。
2、LED灯每隔1s闪烁一次。

电路如下:

考虑程序怎么写……

//代码不完整,仅为举例说明
void main(){P2 = 0x01;       //数码管从最低位开始扫描while(1){//功能1:执行数码管动态扫描//P2控制显示哪一个数码管,P0控制数码管显示什么内容P2 = P2<<1;      //扫描更高一位的数码管P0 = xxxx;       //输出段码delayms(5);      //延时5ms后显示下一位数码管//功能2:执行LED灯闪烁led = ~led;     //LED灯状态取反delayms(1000);  //延时1000ms}
}

功能1和功能2单独写都没有问题。
但是如果组合在一起,写在一个while循环中,就会有问题了:
一个while循环中有两个延时函数,因此执行一次while循环,共延时了1005ms。这并不是我们所希望的结果。我们希望led闪烁的延时不影响数码管动态扫描的延时。

2.2 中断寄存器

要使用硬件定时,主要涉及到寄存器的操作。51单片机里的关于中断的寄存器如下:

IE – 中断允许控制寄存器
IP – 中断优先级控制寄存器
TMOD – 定时器工作方式寄存器
TCON – 定时器控制寄存器
SCON – 串口控制寄存器
THx/TLx – 定时器初值寄存器

在定时器中断中,需要设置的有TMOD、THx/TLx、TCON、IE。
下面只介绍使用定时器中断所需要设置的寄存器,其余寄存器可自行查阅资料。

2.2.1 中断允许控制寄存器 IE

该寄存器的主要功能是控制中断的开启与关闭,共7个有效位,包含一个全局中断控制位和6个中断源的控制位。
中断允许控制寄存器 IE各位的定义如下表:

序号 D7 D6 D5 D4 D3 D2 D1 D0
符号 EA ET2 ES ET1 EX1 ET0 EX0

说明:
EA 全局中断允许位,当此位是1时中断可用。(重要)
ET2 定时器/计数器2中断允许位
ES 串口中断允许位
ET1 定时器/计数器1中断允许位
EX1 外部中断1允许位
ET0 定时器/计数器0中断允许位 (重要)
EX0 外部中断0允许位
要使用定时器中断,需要将IE寄存器中的EA位设置为1,以及需要将ETx(x = 0,1,2)设置为1。

2.2.2 定时器工作方式寄存器 TMOD

该寄存器的主要功能是设置定时器/计数器中断的工作方式。如设置位定时器模式、定时器模式的计数位的位数。以下是详细介绍:
定时器工作方式寄存器 TMOD各位的定义如下表:

序号 D7 D6 D5 D4 D3 D2 D1 D0
符号 GATE C/TˉC/\bar{T} C/Tˉ M1 M0 GATE C/TˉC/\bar{T} C/Tˉ M1 M0

说明:
GATE 定时器/计数器的开关控制选项。常将该位置0,即定时器/计数器的开关控制仅由TCON寄存器中的TRx(x = 0,1)控制。(见2.2.3的TRx)
C/T 定时器模式和计数器模式选择位,将该位置0则为定时器模式。
M1M0 设置定时器/计数器工作方式,常将该两位设置为0 1,其定义如下表:

M1 M0 工作方式
0 0 模式0,13位计数
0 1 模式1,16位计数,常用此模式
1 0 模式2,8位初值自动重装
1 1 模式3,仅适用于T0,分为两个8位计数器,T1停止计数

2.2.3 定时器控制寄存器 TCON

该寄存器用于控制中断,如控制定时器的启动,停止、判断定时器的溢出和中断情况。
定时器控制寄存器 TCON各位的定义如下表:

序号 D7 D6 D5 D4 D3 D2 D1 D0
符号 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

说明:
TF1 定时器1溢出标志位
TR1 定时器1运行控制位,将该位置1时启动定时器1
TF0 定时器0溢出标志位
TR0 定时器0运行控制位,将该位置1时启动定时器0 (重要)
IE1 外部中断1请求标志
IT1 外部中断1触发方式选择位
IE0 外部中断0请求标志
IT0 外部中断0触发方式选择位

2.2.4 定时器初值寄存器 THx/TLx

以定时器T0为例,其的工作原理是,每当晶振产生一次脉冲,就将该寄存器TL0加一,当TL0加满溢出后,将TL0清空,TH0加一,TH0计满后产生定时中断。即TH0与TL0组成了一个16位的计数器,这个计数器可以从0x0000(0)加到0xffff(65535)。
以12Mhz的晶振、定时10ms为例:
51单片机为12分频单片机,因此执行一条指令的时间是12×(1/12M) s,即计数器每1us加一。
若定时10ms,则共需要加10000次。
因此将TH0、TL0设置从(65536-10000)= 55536开始计数。55536 的16进制为0xD8F0。因此将TH0设置为0xD8,TL0 设置为0xF0

2.3 定时器中断程序写法

首先要初始化定时器,即将命令写入以上的寄存器。 假设使用定时器T0
首先设置定时器工作模式TMOD:GATE设置为0;C/T位设置为0使其工作在定时器模式下;M1M0设置为01,使用16位计数。
因此第一句代码是

TMOD = 0x01;   // 0000 0001

然后设置定时器时长THx/TLx:

TH0 = 0xD8;
TL0 = 0xF0;

设置定时器允许寄存器IE,打开中断总开关和T0中断开关

EA = 1;
ET0 = 1;

最后设置定时器控制寄存器TCON,使定时器开始计数

TR0 = 1;

因此,完整的定时器初始化代码如下

void initT0(){TMOD = 0x01;   // 0000 0001.TH0 = 0xD8;    //65536-10000TL0 = 0xF0;    //55536EA = 1;ET0 = 1;TR0 = 1;
}

当定时器计数触发中断时,单片机会调用中断服务程序。中断服务程序的格式如下:

void 函数名() interrupt 中断号 using 工作组
{//所要执行内容
}

说明:
中断服务函数要写在主函数后面,且不需要声明 。
中断服务函数无返回值,所以用void
函数名可以随便起
interrupt后的中断号由下表的重点服务号确定
using 工作组可省略不写

中断源 优先级 中断服务号
INT0 – 外部中断0 最高 0
T0 – 定时器/计数器0中断 第2 1
INT1 – 外部中断1 第3 2
T1 – 定时器/计数器1中断 第4 3
串口中断 第5 4
T2 – 定时器/计数器2中断 最低 5

因此T0中断服务程序如下:

void t0Intr() interrupt 0
{//因为执行到此时,计数器已经清零,所以要重新赋值TH0 = 0xD8;    //65536-10000TL0 = 0xF0;    //55536//下面写需要执行的操作
}

根据以上内容,可设计一个简单定时器电路如下:

其中:

D1灯由定时器控制,每秒闪一次
D2 - D8由软件延时实现流水灯效果,周期为100ms

代码如下

#include <reg51.h>
#include <intrins.h>
//num为计数器,每10ms将num加一,当num为100时为1s
unsigned char num;
sbit led = P1^0;
//函数声明
void delay100ms();  //软件延时100ms
void initT0();      //初始化定时器T0void main()
{unsigned char k ;//初始化num值num = 0;//初始化定时器initT0();//初始化led灯led = 0;//初始化流水灯P0 = 0xfe;k = 0xfe;while(1){//每100ms流水灯移位一次k = _crol_(k, 1);P0 = k;delay100ms();}
}
//t0定时器中断服务程序
//每隔10ms进入一次该程序
void t0Intr() interrupt 1
{TH0 = 0xD8;TL0 = 0xF0;num++;   //该变量加至100说明为1sif(num == 100){num = 0;led = ~led;   //翻转led灯状态}
}
void delay100ms()
{unsigned char a,b,c;for(c=19;c>0;c--)for(b=20;b>0;b--)for(a=130;a>0;a--);
}void initT0()
{TMOD = 0x01;TH0 = 0xD8;TL0 = 0xF0;EA = 1;ET0 = 1;TR0 = 1;
}

51单片机入门教程(5)——定时器中断相关推荐

  1. 51单片机入门教程(6)——外部中断

    51单片机入门教程(6)--外部中断 一.外部中断 1.1 中断 1.2 外部中断 二.中断优先级 一.外部中断 1.1 中断 关于中断的概念在上一篇博客中已经提到了.(传送门:51单片机入门教程(5 ...

  2. 51单片机入门教程(1)——点亮一个LED灯

    51单片机入门教程(1)--点亮一个LED灯 一.什么是单片机 单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU.随机存储器 ...

  3. 51单片机入门教程学习笔记

    基于江科大自化协B站教学视频<51单片机入门教程-2020版 程序全程纯手打 从零开始入门> 一.单片机介绍 单片机,英文Micro Controller Unit,简称MCU 内部集成了 ...

  4. 51单片机入门教程(3)——数码管显示

    51单片机入门教程(3)--数码管显示 一.LED数码管简介 二.数码管静态显示 三.数码管动态显示 特别鸣谢:HFUTer-朱聪强 一.LED数码管简介 LED数码管(LED Segment Dis ...

  5. b站江科大自化协51单片机入门教程笔记(2)

    文章目录 6-1 矩阵键盘 6-2 矩阵键盘密码锁 7-1 定时器 7-2 按键控制LED流水灯 & 定时器时钟 独立按键模块 定时器模块 8-1 串口通信 8-2 串口向电脑发送数据 &am ...

  6. 51单片机入门教程(1)——如何建立工程

    目录 1.Keil篇 2.Proteus篇 3.小结 由于大家可以在本网站上找到很多安装keil和protues的教程,在此我就不再赘述.当大家都顺利安装好这两个软件之后,下面我们来学习如何建立新工程 ...

  7. 51单片机入门教程(3)——数码管显示学号

    目录 1.数码管简介 2.静态显示 3.动态显示 4.小结 相信经过了流水灯的实现,大家已经弄清楚了Keil和Proteus是如何联动使用的,并且对51单片机也有了一定的认识,在这一章里,我带大家利用 ...

  8. 51单片机(四)定时器中断(+数码管——24小时制钟表)

    定时器中断 一.中断 1.中断概念 2.中断嵌套 二.中断源(优先级顺序必记!) 三.中断允许寄存器IE和中断优先级寄存器IP 1.中断允许寄存器IE(Interrupt Enable ) 2.中断优 ...

  9. b站江科大自化协51单片机入门教程笔记(1)

    文章目录 1 综述 2-1 点亮一个LED 2-2 LED闪烁 2-3 LED流水灯 2-4 LED流水灯PLus 3-1 独立按键控制LED亮灭 3-2 独立按键控制LED状态 3-3 独立按键控制 ...

最新文章

  1. flutter 安装遇坑记录
  2. python的下载和安装步骤-PyCharm下载和安装详细步骤
  3. Ubuntu18.04 显卡驱动安装
  4. python决策树生成规则_如何从scikit-learn决策树中提取决策规则?
  5. 从LXMERT到VLMO:多模态预训练模型的演变史
  6. 对话阿里巴巴贾扬清:如何成为一名优秀的 AI 架构师?
  7. html语言音乐添加路径,HTML5简单实现添加背景音乐的几种方法
  8. 信息学奥赛C++语言: 求正整数2和n之间的完全数
  9. 分布式文件系统之MogileFS的使用
  10. asp.net 学习交流群 130017551
  11. 使用BAPI批量修改采购信息记录的税率
  12. Linux3.2.8系统启动过程及启动延时初步分析
  13. html带圈的数字号码,html – 带有数字的CSS圈子
  14. 使用procexp.exe查看线程
  15. 前期交互流程(PTES的第一步)
  16. 测试wi-fi信号软件是什么,Wi-Fi Inspector - WIFI 信号检测及连接工具
  17. 细粒度情感分析在到餐场景中的应用
  18. Web3 来临前的准备工作
  19. 洛谷刷题笔记5.p1116 车厢重组
  20. 基本算法4.1堆积木详细题解

热门文章

  1. UITableView使用总结和性能优化
  2. (转)Linux SLUB 分配器详解
  3. 无线路由器连接电信光纤宽带光猫设置方法(转)
  4. 在 .NET 中设置页面元素的 javascript 事件 - IEBrowser [5]
  5. WCF 第一章 基础 完成一个WCF服务客户端
  6. thinkpad e420 装完新系统后,耳机有声音,外音没有,解决方法
  7. ARC单例模式的实现
  8. 《快活帮》第三次作业:团队项目的原型设计
  9. 2018-2019-2 20175320实验三《敏捷开发与XP实践》实验报告
  10. ThreadLocal 解决多线程程序的并发问题+事务处理