51单片机 - 中断系统
Contents
- 1> 定义
- 2> 作用
- 3> 组成
- 3.1> 中断系统结构
- 3.2> 8个中断源
- 3.3> 中断向量
- 3.4> 中断优先级
- 4> 工作原理
- 5> 程序设计
- 6> 视频链接
1> 定义
中断(interrupt)是指:
CPU执行某一程序过程中,由于系统内,或外部某种原因,
必须中止原程序的执行,
转去执行相应的处理程序,
处理结束后,再回来继续执行原程序的【过程】
2> 作用
解决CPU与外设之间速度匹配问题,使计算机可以及时处理系统中许多随机的参数和信息;
3> 组成
3.1> 中断系统结构
3.2> 8个中断源
4种中断控制:硬件实现,软件设置;
1》中断触发方式;
2》中断允许控制;
3》中断请求标志;
4》中断优先级控制;
3.3> 中断向量
中断向量(Interrupt Vector):是程序存储器的一个地址,表明一个中断服务程序从这里开始存放。
中断发生后要通过它引导CUP转【向】相应的中断服务
正因为具有【指定性】,所以称其为中断向量。
3.4> 中断优先级
中断原则:
只有【高】优先级中断 打断【低】优先级;
硬件设计,同级中断优先级:
0> 外部中断 0;
1> 定时器0中断;
2> 外部中断1;
3> 定时器1中断;
4> 串口中断;
5> 定时器2中断;
6> 外部中断2;
7> 外部中断3;
4> 工作原理
CPU中断响应过程,以外部中断0(INT0#)为例:
Step 1> CPU每个机器周期对芯片引脚P3.2(INT0)采样;
Step 2> CPU根据采样结果设置中断标志位(IE0);
Step 3> CPU中断查询,CPU逐个检测中断标志位;
Step 4> 中断响应,程序计数器PC的值压栈;
Step 5> 外部中断入口地址(0003H)装入程序计数器PC,执行中断服务服务程序,此时中断标志位硬件清0;
Step 6> 中断返回,将PC值从栈中取出,执行主程序;
- 内部中断不需要 Step 1> 对引脚采用;
5> 程序设计
硬件平台:普中-A7开发板, STC89C516R
功能实现:
主程序中,数码管循环显示0~F;
用外部中断0,实现按键1按下的下降沿,LED1状态翻转;
用外部中断1,实现按键2按下的下降沿,LED2状态翻转,并能打断中断0服务程序;
#include <reg52.h>
typedef unsigned char uchar;
typedef unsigned short ushort;
/* byte device */
#define NUM_PORT P0
/* bit Device */
sbit KEY1 = P3^2;
sbit KEY2 = P3^3;
sbit LED1 = P2^0;
sbit LED2 = P2^1;
sfr IPH = 0xB7; // Interrupt Priority High
unsigned char DS_code[16] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99,
0x92, 0x82, 0xF8, 0x80, 0x90,
0x88, 0x83, 0xa7, 0xa1, 0x86,
0x8E };
void digit_ctrl(uchar num);
void delay_10us(ushort num);
/**
* main
*/
int main(void)
{
uchar i = 0;
/* initialize INT0# */
IT0 = 1; // set falling edge;;
IPH = 0x01; // set Priority High bit 1;
PX0 = 0; // set Priority Low bit 1;
EX0 = 1; // Enable INT0#;
/* initialize INT1# */
IT1 = 1; // Set falling edge;
IPH = 0x05; // set priority High bit 1;
PX1 = 1; // set priority Low bit 0;
EX1 = 1; // Enable INT1 #;
EA = 1; // Enable global interrupt;
while (1) {
for (i= 0; i<16; i++) {
digit_ctrl(i);
delay_10us(60000);
}
}
}
/**
* INT0# interrupt handle
*/
void Int0_handle(void) interrupt 0
{
uchar i = 0;
for (i = 0; i < 10; i++){
delay_10us(65535); // kidding
LED1 = ~LED1;
}
}
/**
* INT1# interrupt handle
*/
void Int1_handle(void) interrupt 2
{
LED2 = ~LED2; /* 快速按KEY2,观察中断现象 */
}
void delay_10us(unsigned short num)
{
while (num--) {
/* nothing */;
}
}
/**
* Ctrl digit number
*/
void digit_ctrl(uchar num)
{
NUM_PORT = DS_code[num];
}
// file end
假如你是CPU,
那么数码管循环显示,好比是你在看电影,
外部中断0或1,好比是快递到了,要去楼下拿,
所以中断要尽量短,才不会影响你看电影;
6> 视频链接
🔗B站视频链接
qq_24158561: 请问各个任务内部局部变量怎么保存到栈和出栈?每个任务的现场保存和恢复不止sp
saintlior: 毕业论文
saintlior: 您好,3.2的那张图可以使用吗,放在论文里
橡木工作室: HHH
普通网友: 这篇文章真是一篇佳作!作者运用了生动有趣的语言,将枯燥的理论知识娓娓道来,让人如沐春风。【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】