说明
本人使用的是清翔的51单片机开发板,如果型号相同最方便,但是如果型号不同也可以参考,因为芯片都是一样的,只是外设不同而已,使用时只需要对照自己的开发板原理图稍微修改下引脚即可。
本次笔记将对应视频教程的26,27 中断系统和外部中断(理论+实践)
一、引脚说明
上图
二、中断系统
中断就是遇到某种突发情况,单片机去处理突发事件,处理完突发事件之后再回到由原来的地方继续处理原来的内容。
官方定义如下
见数据手册第6章 中断系统
三、数据传输方式
3.1 数据的输入/输出传送方式
- 无条件传送:一方队另一方来说总是准备好的;
- 查询(LOOK UP):传送前先先查询对方状态,若对方准备好了,再传送,否则就继续查询/等待;
- 中断(IRQ):一方通过申请中断的方式与另一方进行数据传送;
- 直接存储器存取方式(DMA):双方直接通过总线传送数据,不经CPU中转。适用于数据量大,高速通讯的设备,不占用CPU时间。
以上内容复制自视频PPT
3.2 2 中断传送方式特点
数据传送的双方平时各自做自己的工作,一旦甲方要求与乙方进行数据传送,就主动发出信号提出申请,乙方接到申请后若同意传送,安排好当前的工作,再响应与甲方发生数据传送。完事后,回去继续做中断前的工作。
中断功能强弱是计算机性能优劣的重要标志
- 提高CPU效率
- 解决速度矛盾
- 实现并行工作
- 应付突发事件
- ...
四、51中断源
注:我在数据手册看到STC89C52RC有8个中断源,分别是外部中断0~3,定时器中断0~2, 串口中断,但是我查找网上资料发现大多数都说51单片机有5个中断,正如视频所讲那样
目前只找到这个文章STC89C52的四个 外部中断 基本使用方法说有4个外部中断,但是外部中断2和3在P4.3和P4.2上,我芯片上好像没这两个引脚,就非常奇怪,就先按照视频所讲的写笔记了,以后弄明白了再更正,或者有懂的朋友在评论区指出。
4.1 中断系统内部结构
由于上文所说的原因,这理只分析5个中断
数据手册图片
4.2 配置触发方式
两个外部中断可以配置是下降沿触发还是低电平触发
注意:可位寻址
还需要注意的一点
4.3 配置中断允许
EX0,EX1,ET0,ET1,ES是对应中断的开关,EA是所有中断的总开关,只有总开关被打开了,各自的中断开关才会有效。对应寄存器如图
注意:可位寻址
可位寻址意思是我直接写这个寄存器里面的某个位的名字编译器认识,比如我直接写EA = 1;是可以的。如果不可位寻址,那么写EA = 1就会报错或者无法实现想要的功能,只能对IE寄存器整体赋值一个十六进制数来改变想要改变的位。
4.4 配置中断优先级
右边的是配置中断优先级的。
中断优先级处理原则:
不同优先级同时申请:先处理优先级高的
相同优先级同时申请:按顺序依次执行
正在处理一个中断,同时又产生另一个中断:先处理优先级高的,比如正在处理一个中断,突然产生另一个优先级更高的中断,则马上去执行高优先级的中断,处理完再回来接着处理原来的中断;如果正在处理一个中断,突然产生另一个优先级更低的中断,则等待当前中断处理完成再处理优先级更低的中断。
4.4.1 同级查询次序
当同时收到几个同一优先级的中断要求时,哪一个要求得到服务,取决于内部的查询次序,这相当于在每个优先级内,还同时存在另一个辅助优先级结构,STC89C51RC/RD+系列单片机各中断优先查询次序如下:
4.4.2 手动配置优先级
优先级可以配置0,1,2,3共四级优先级,数据手册内容如下
4.2.2.2 寄存器图
4.2.2.3 寄存器具体位设置
4.2.2.4 注意事项
- 数据手册介绍如图
- 也就是说单片机复位后,如果不设置优先级,那么所有中断优先级都是相同的,即优先级0(最低优先级),根据优先级相同的情况下,使用 4.4.1 同级查询次序 的内容,有一个默认查询次序,相当于一个默认优先级,所以在下面的代码中没有配置优先级这一项。
- 注意IPH是不可位寻址的,所以不能写类似 PSH = 1;这样的代码,而是需要给整个IPH寄存器赋值,改变想要改变的位。
4.5 中断函数
中断函数编写规范:
也就是在普通的函数后面加上interrupt 并且加上中断号,那么就变成了对应的中断处理函数。
4.6 总结
- 设置触发方式。是低电平触发还是下降沿触发(TCON寄存器)
- 设置中断允许。打开中断总开关EA,还要打开对应的中断开关
- 写中断处理函数。在函数名后加上interrupt 和 中断号
五、中断使用示范
以外部中断1的使用为例,来说明外部中断如何编写程序
5.1 创建工程
复制上一份工程文件夹,修改名称为“9.外部中断”,进入项目文件夹,打开工程文件,删除main.c函数的内容。
5.2 硬件连接
把P33和P37通过一根杜邦线连接起来。P33是外部中断1的中断产生引脚,P37是我们准备用来产生一个下降沿,从而使外部中断1触发。连接如图:
5.3 main.c 以下降沿触发为例
void main()
{
int1init();
while(1)
{
if (key_s2 == 0)
{
delay(20); //软件消抖
if (key_s2 == 0)
{
flag = 1; //和下一句结合就能产生一个下降沿
flag = 0;
while(!key_s2);
}
}
}
}
void int1init() //外部中断1初始化函数
{
EA = 1; //打开中断总开关
EX1 = 1; //打开外部中断1开关
IT1 = 1; //设置外部中断1触发方式为下降沿
}
void int1() interrupt 2 //外部中断1处理函数,中断号是2
{
P1 = ~P1; //~表示按位取反
}
5.4 main.h
void int1init(void); //外部中断1初始化函数
sbit key_s2 = P3^0;
sbit flag = P3^7;
5.5 现象说明
按下s2,8颗板载LED立刻全亮,再按下s2,板载8颗LED立刻全灭。注意这个“立刻”,在main函数里面写的有
while(!key_s2);
按理说没松手就不会执行接下来的程序,但是LED立马发生变化,说明当产生中断后会跳转到中断函数中处理。
5.6 main.c 以低电平触发为例
void main()
{
int1init();
while(1)
{
if (key_s2 == 0)
{
delay(20); //软件消抖
if (key_s2 == 0)
{
//低电平触发
flag = 0; //产生低电平
flag = 0;
flag = 1;
while(!key_s2);
}
}
}
}
void int1init() //外部中断1初始化函数
{
EA = 1; //打开中断总开关
EX1 = 1; //打开外部中断1开关
IT1 = 0; //低电平触发
}
void int1() interrupt 2 //外部中断1处理函数,中断号是2
{
P1 = ~P1; //~表示按位取反
}
注意
flag = 0;
flag = 0;
flag = 1;
写两个flag = 0;是因为在4.2节已经说过,中断信号至少需要2个周期,图片再放一次最后还有一个flag = 1;是为了下次产生低电平信号触发中断。
现象和刚才一样,不再赘述。
本次笔记将对应视频教程的26,27 中断系统和外部中断(理论+实践),中断内容已经不少了,初学者需要好好消化认真看数据手册。我觉得现在还没写明白的是终端的数量,在本次笔记的 四、51中断源 这一节我有说明,还有就是中断优先级的设置,虽然我感觉对于优先级的设置,我已经写的比较详细了,但是视频中没有详细地讲如何去进行中断优先级的配置,也没有对应的例程,所以我仅做分析,感兴趣的朋友可以自行按照知识点尝试。
下一次笔记将对应视频教程的第28,29,30,31集 定时计数器的定时和计数(理论+实践)
如果笔记之中有任何错误,请在评论区指出,谢谢