【笔记】中断
前言
中断学习笔记
注意:本文所有代码均按照sdcc编译器代码规范编写,如果使用的Keli编译器,需要自行修改代码
定义
- 中断:打断CPU当前工作的一种事件
- 中断源:所有可以引发中断的事件的集合
- 标准51单片机的中断源(5种/3类)
- 外部中断:由单片机引脚输入的中断
- 外部中断0
- 外部中断1
- 定时/计数器中断:由定时/计数器引起的中断
- 定时/计数器0中断
- 定时/计数器1中断
- 串行中断:由串行通讯(发送串行数据、接收串行数据)引起的中断
- 串行中断
- 外部中断:由单片机引脚输入的中断
- 标准51单片机的中断源(5种/3类)
- 中断向量:中断函数的入口地址
- 在C51代码中,通常不直接使用中断向量,而是根据头文件中指定的指针变量来使用中断向量
外部中断
数字信号的种类(4种/2类)
- 电平信号
- 高电平信号
- 低电平信号
- 边沿信号
- 上升沿信号
- 下降沿信号
外部中断请求类型
- 标准51单片机支持的外部中断请求类型
- 低电平请求
- 下降沿请求
STC12C5A60S2使用外部中断
- 开中断:STC12C5A60S2的12引脚默认为P3.2端口、13引脚默认为P3.3端口。如果需要开中断,需要将12引脚切换为INT0端口、将13引脚设置为INT1端口
- 指定中断请求类型(低电平请求、下降沿请求):虽然标准51单片机支持2种中断请求,但是使用时只能设置1种,每次需要中断时,通过这1种中断请求实现中断
- 指定中断处理函数:当检测到中断请求后,立即执行中断处理函数
开中断
- 通过IE寄存器实现开中断
- IE寄存器是可以位寻址的
- IE寄存器从第8位(最高位)到第1位(最低位)分别是:
EA
、空
、空
、ES
、ET1
、EX1
、ET0
、EX0
EA
:中断总开(1)关(0)EX0
:外部中断0的开(1)关(0)EX1
:外部中断1的开(1)关(0)ET0
:定时/计数器0的开(1)关(0)ET1
:定时/计数器1的开(1)关(0)ES
:串行中断的开(1)关(0)
关闭所有中断
通过字节寻址
1 | IE = 0x00; |
通过位寻址
1 | EA = 0; |
开启外部中断0
通过字节寻址
1 | IE = 0x81; |
通过位寻址
1 | EA = 1; |
开启外部中断1
通过字节寻址
1 | IE = 0x84; |
通过位寻址
1 | EA = 1; |
同时开启外部中断0和外部中断1
通过字节寻址
1 | IE = 0x85; |
通过位寻址
1 | EA = 1; |
指定中断请求类型
通过TCON(Timer Config)寄存器的低4位指定中断请求的类型
TCON寄存器是可以位寻址的
TCON寄存器从第4位到第1位分别是:
IE1
、IT1
、IE0
、IT0
IT0
:设置外部中断0的请求类型为低电平请求(0)或下降沿请求(1)IT1
:设置外部中断1的请求类型为低电平请求(0)或下降沿请求(1)IE0
:外部中断0的使能信号。当外部中断0接收到中断信号后,CPU会自动将IE0
设置为1;当外部中断0的中断信号处理结束后,CPU会自动将IE0
设置为0IE1
:外部中断1的使能信号。当外部中断1接收到中断信号后,CPU会自动将IE1
设置为1;当外部中断0的中断信号处理结束后,CPU会自动将IE1
设置为0
中断按键:将一个普通按键,一端接GND,另一端接INT0或INT1
中断请求类型设置为低电平请求(一个时刻)
- 这种方式如果中断按键按下时间过长,会导致中断处理函数执行多次
1 | IT0 = 0; |
中断请求类型设置为下降沿请求(一个瞬间)
- 这种方式如果中断按键按下出现抖动,会导致中断处理函数执行多次
1 | IT0 = 1; |
指定中断处理函数
- 无参数列表
- 无返回值
- 无需声明,通常放在整个程序最后
- 函数名自定义
- 必须指定中断向量号
- 中断处理函数不能手动调用
中断向量:用于控制中断的内存地址
中断向量号:用于标记中断的编号,方便编程
interrupt <num>
:指定中断向量号,取值范围为0~4
0
:外部中断01
:定时/计数器中断02
:外部中断13
:定时/计数器中断14
:串行终端
1 | void int0(void) interrupt <num> |
阻止中断的接收
- 当一个中断处理函数正在执行时,阻止中断的接收
- 阻止中断的接收可以用来消除抖动
1 | void int0(void) __interrupt 0 |
完整代码示例
- 利用外部中断0实现中断
1 |
|
定时/计数器中断
在标准51单片机上有2个16位的定时/计数器
计数值:计数的总次数
计数初值:开始计数的起点
计数最大值:可以计数的上限
- 51单片机做多可以计16位的数
定时/计数器的计数方式
- 减计数:从计数初值(计数值)开始减到0。x86的PC使用的就是减计数的计数器
- 加计数:从计数初值(最大值-计数值)开始加到计数器能力最大值。标准51单片机使用的就是加计数的计数器
定时/计数器的计数内容
- 定时器:数内部的时基(时间基准)
- 计数器:数外部的脉冲信号周期(每个周期一高一低)
定时/计数器的时间计算
- 时钟周期:1个时钟周期 = 1 / 晶振的频率
- 如果51单片机接了一个
12MHz
的晶振,那么时钟周期为1/12μs
- 如果51单片机接了一个
- 机器周期:1个机器周期 = 12 * 时钟周期
- 如果51单片机接了一个
12MHz
的晶振,那么机器周期为1μs
- 如果51单片机接了一个
STC12C5A60S2使用计数器中断
指定模式
- 通过TMOD(Timer Model)寄存器指定模式
- TMOD寄存器是不可以位寻址的
- TMOD寄存器从第4位到第1位是用来设置定时/计数器0的,分别是:
GATE
、C/T、M1
、M0
- TMOD寄存器从第8位到第5位是用来设置定时/计数器1的,分别是:
GATE
、C/T、M1
、M0
GATE
:门控信号,用来指定定时/计数器的开关的方式,1表示硬件开启,0表示软件开启- C/T:1表示工作在计数模式,0表示工作在定时模式
M1
:用来设置工作方式的高位M0
:用来设置工作方式的低位
模式 | M1 | M0 | 寄存器位数 | TH寄存器功能 | TL寄存器功能 | 特点 |
---|---|---|---|---|---|---|
工作方式0 | 0 | 0 | 13位 | - | - | 为了向下兼容 |
工作方式1 | 0 | 1 | 16位 | 存放计数初值的高位 | 存放计数初值的低位 | 只能手动载入初值 |
工作方式2 | 1 | 0 | 8位 | 存放计数初值的备份 | 存放计数初值 | 可以自动载入初值 |
工作方式3 | 1 | 1 | 8位 | 作为定时器 | 作为计数器 | 可以同时作为定时器和计数器的寄存器 |
写入计数初值
- 用2个初值寄存器存放初值,最大可以存放16位
- 定时/计数器0:高8位用
TH0
寄存器,低8位用TL0
寄存器 - 定时/计数器1:高8位用
TH1
寄存器,低8位用TL1
寄存器
- 定时/计数器0:高8位用
开启定时/计数器
- 通过TCON(Timer Config)寄存器的高4位指定定时/计数器的开启
- TCON寄存器从第8位到第5位分别是:
TF1
、TR1
、TF0
、TR0
TR0
:定时/计数器0的软开(1)关(0)TR1
:定时/计数器1的软开(1)关(0)TF0
:定时/计数器的计数溢出标识,标识计数是(1)否(0)已完成TF1
:定时/计数器的计数溢出标识,标识计数是(1)否(0)已完成
完整代码示例
通过按键,接收脉冲信号,累计5次开始中断
- 在计数模式下,需要利用
T0
和T1
引脚来接收脉冲信号,初始是高电平 - 可以将
T0
和T1
引脚接按键,实现发出脉冲信号
- 在计数模式下,需要利用
定时/计数器完成计数后自动中断
进入中断后溢出标识会自动置0
1 |
|
STC12C5A60S2使用定时器中断
完整代码示例
小于等于65536μs的定时
在定时时实际上是通过晶振的振动频率来数数,以达到定时的效果,12MHz的晶振机器周期为
1μs
由于在标准51单片机上有2个16位的定时/计数器,没个定时/计数器最大只能存储65536个数,所以每次计时只能累计
65536μs
设置一个50ms的定时器
1 |
|
大于65536μs的定时
虽然每次计时最多只能累计
65536μs
,但是通过多次计时能实现更多时间的累计,其中每次计时的时间为时间基值设置一个1s的定时器
- 通过在时间基值为50ms的定时器,累计定时20次,实现1s的定时器
1 |
|
只改变标识
- 如果一个定时器需要反复使用,在定时器完成定时后,不立即执行业务代码,而是改为只改变预先设定的标识,这样能减小定时器的误差
- 通过
bit
关键字可以定义一个布尔值,只能存放1或0,bit
不能用unsigned
关键字修饰
1 |
|
总结
中断函数的中断向量号总结
中断向量号 | 中断类型 |
---|---|
0 | 外部中断0 |
1 | 定时/计数器中断0 |
2 | 外部中断1 |
3 | 定时/计数器中断1 |
4 | 串行终端 |
寄存器总结
寄存器名 | 用来定义的功能 | 第8位 | 第7位 | 第6位 | 第5位 | 第4位 | 第3位 | 第2位 | 第1位 |
---|---|---|---|---|---|---|---|---|---|
IE |
寄存器的总开关 | EA |
- | - | ES |
ET1 |
EX1 |
ET0 |
EX0 |
TCON |
外部中断的使能信号、请求类型 | - | - | - | - | IE1 |
IT1 |
IE0 |
IT0 |
TCON |
定时计数器的溢出标识、软开关 | TF1 |
TR1 |
TF0 |
TR0 |
- | - | - | - |
TMOD |
定时计数器0的开关方式、定时/计数模式、工作方式 | - | - | - | - | GATE |
C/T | M1 |
M0 |
TMOD |
定时计数器1的开关方式、定时/计数模式、工作方式 | GATE |
C/T | M1 |
M0 |
- | - | - | - |
TH1 |
定时计数器1的计数初值高8位 | - | - | - | - | - | - | - | - |
TL1 |
定时计数器1的计数初值低8位 | - | - | - | - | - | - | - | - |
TH0 |
定时计数器0的计数初值高8位 | - | - | - | - | - | - | - | - |
TL0 |
定时计数器0的计数初值低8位 | - | - | - | - | - | - | - | - |
EA
:中断总开(1)关(0)ES
:串行中断的开(1)关(0)ET1
:定时/计数器1的开(1)关(0)EX1
:外部中断1的开(1)关(0)ET0
:定时/计数器0的开(1)关(0)EX0
:外部中断0的开(1)关(0)IE1
:外部中断1的使能信号。当外部中断1接收到中断信号后,CPU会自动将IE1
设置为1;当外部中断0的中断信号处理结束后,CPU会自动将IE1
设置为0IT1
:设置外部中断1的请求类型为低电平请求(0)或下降沿请求(1)IE0
:外部中断0的使能信号。当外部中断0接收到中断信号后,CPU会自动将IE0
设置为1;当外部中断0的中断信号处理结束后,CPU会自动将IE0
设置为0IT0
:设置外部中断0的请求类型为低电平请求(0)或下降沿请求(1)TF1
:定时/计数器的计数溢出标识,标识计数是(1)否(0)已完成TR1
:定时/计数器1的软开(1)关(0)TF0
:定时/计数器的计数溢出标识,标识计数是(1)否(0)已完成TR0
:定时/计数器0的软开(1)关(0)GATE
:门控信号,用来指定定时/计数器的开关的方式,1表示硬件开启,0表示软件开启
C/T:1表示工作在计数模式,0表示工作在定时模式M1
:用来设置工作方式的高位M0
:用来设置工作方式的低位
定时计数器工作方式总结
模式 | M1 | M0 | 寄存器位数 | TH寄存器功能 | TL寄存器功能 | 特点 |
---|---|---|---|---|---|---|
工作方式0 | 0 | 0 | 13位 | - | - | 为了向下兼容 |
工作方式1 | 0 | 1 | 16位 | 存放计数初值的高位 | 存放计数初值的低位 | 只能手动载入初值 |
工作方式2 | 1 | 0 | 8位 | 存放计数初值的备份 | 存放计数初值 | 可以自动载入初值 |
工作方式3 | 1 | 1 | 8位 | 作为定时器 | 作为计数器 | 可以同时作为定时器和计数器的寄存器 |