目录

C51单片机学习日志

基础知识部分

踩坑

一开始安装驱动那里就出问题,驱动明明已经安装,但是识别不了单片机的接口,最后还是解决了。目测要么是USB线接触不良,要么是安装的WIN10驱动没起作用,所以后面还安装了一个XP驱动。

单片机相关概念

单片机是单芯片微型计算机的简称,常用英文缩写MCU(Microcontroller Unit)代指单片机。
我所使用的单片机为DIP封装,虽然体积较大,但是方便拆卸,从而损坏后更换芯片更便捷。
其他两种封装(PLCC,LQFP),虽然体积小,但是更换比较麻烦。厂商为STC的,这家厂商单片机烧录程序便捷些。
厂商虽然不同,但是内核都是使用的Intel公司的80C51系列内核,STC的单片机命名规则如下:
https://gitee.com/cindycyber/blog-pic/raw/master/img/20210501120634.png

一些零散知识点(C语言)

由于C语言已经学过不少了,就选择性地记了些笔记:
常用存储单位关系:

中文名称 英文名称 换算关系
比特(字位) bit 1B = 8bit
字节 byte 1B = 8bit
千字节 kibibyte 1KB = 1024B
兆字节 Mebibyte 1MB = 1024KB
吉字节 Gigabyte 1GB = 1024MB

常说的100M宽带,并非是100MB而是100Mbit,所以换算成下载速度需要除以8,换算成字节单位,也就是12.5MB

数据类型 所占位数 范围
bit 1 0~1
unsigned char 8 0~255
char 8 -128~127
unsigned int 16 0~65535
int 16 -32768~32767
unsigned long 32 0~429467295
float 32 3.4e-38~3.4e38
double 64 1.7e-308~1.7e308

其中,有符号位的最高位是符号位,0表示正数,1表示负数。

一些零散知识点(电子电路基础)

单片机是一种数字集成芯片,数字电路中只有两种电平:高电平和低电平。
高电平为5V,低电平为0V
TTL电平信号被利用的较多,因为数字电路中通常数据表示采用二进制,5V等价于逻辑10V等价于逻辑0。TTL电平规定高电平输出电压>2.4V,低电平输出电压<0.4V,这是因为实际发送信号时,可能并不一定达到高电平和低电平的精确值,所以只要在这个波动范围内都是会被认定为高电平和低电平的。
而计算机串口使用的是RS232电平。 高电平为-12V,低电平为+12V,单片机与计算机串口通信时需要使用电平转换芯片,把RS232电平转换为TTL电平后,单片机才能识别。但是电路USB接口的供电口是5V,充电宝也是,所以可以用充电宝和电脑USB接口来给单片机供电。
I/O口是基本输入Input/输出Output接口,单片机对外围设备的控制都是通过I/O口来进行的(输出高低电平)。接收外部控制也是通过I/O口来读取外部电压信号。
选电容时,一般选耐压值比应用系统高2-3倍的电容。
有极性的电容,长脚为正,短脚为负。
电容上颜色面积小的部分所对应的为负极,反之为正极(对于直插和贴片电解电容)。而对于钽电容则相反。
单片机需要运行起来最基本的条件为:

  1. 电源
  2. 单片机芯片
  3. 晶振电路
  4. 复位电路
    单片机工作的基本时序:
    振荡周期:也称时钟周期,是指为单片机提供时钟脉冲信号的振荡源的周期。
    机器周期:一个机器包含12个时钟周期。在一个机器周期内,CPU可以完成一个独立的操作。
    电路原理图中:
    电阻上的471字样代表电阻阻值为47*10^1 Ω
    电容上的105字样代表电容大小为10*10^5 pF
    网络标号相同的两点表示这两点实际电气相连(有导线连接)。

实践部分

正确安装驱动并配置好环境后,使用usb线连接电脑上电。

Keil5的使用

点击Project新建项目文件,选用合适的芯片(可以去下载STC官方的元件库,也可以直接用ATMEL的,没什么区别),注意别把startup程序添加到项目中。 新建后,Ctrl+N新建空白文件,然后Ctrl+S保存到项目文件夹中,注意保存为.c文件,然后双击左侧栏中的Source Group文件夹,添加刚刚的.c文件到项目中,添加后展开Source Group文件夹可以看到就算添加成功,就可以开始编写程序了。 但最后烧录之前,记得单机上方菜单栏中的魔法棒图标(有点长得像锤子),在output页面勾选Creat HEX File并确定,这样才能烧录进板子,因为烧录进去的是.hex文件。

程序烧录软件的使用

单片机型号要选对(注意看芯片上是否带RC),串口号选对,名称为USB-SERIAL CH430。 第一次烧录程序需要先点击打开程序文件,我们需要选择的是.hex文件(在项目文件夹的Object文件夹中),选择之后,同一个程序文件更改代码可以直接点击下载,会自动覆盖掉之前的代码。

点亮LED灯

LED(Light-Emitting Diode),即发光二极管。其优点是,功耗低,高亮度,色彩艳丽,寿命长。
同样的,LED灯也是长正短负。它的封装方式和电容电阻类似,开发板中用的就是最小的0603封装。贴片式的LED,有小绿点的一端为负极,另一端为正极。
普通发光二极管工作压降为1.6V~2.1V。工作电流为1~20mA。普通发光二极管导通压降通常为0.7V。由于其工作电流较小,通常会再串一个限流电阻。
原理
https://gitee.com/cindycyber/blog-pic/raw/master/img/20210502113203.png
由原理图可知,要想点亮LED灯,二极管需要处于导通状态,由于电源输入到阳极的信号恒为高电平,那么阴极为低电平才能导通,那么给阴极输入0即可。
实践
Tip:在建项目编译文件时,记得在output里勾选输出hex文件。
点灯方式1
按位寻址点灯。

/*
 * @Descripttion: 按位寻址点亮LED灯
 * @Author: 五月雨
 * @Date: 2021-05-16 14:43:49
 * @LastEditors: 五月雨
 * @LastEditTime: 2021-06-01 15:12:21
 */
#include <reg52.h>

//点亮第一个和第三个LED灯
sbit LED1 = P1^0;
sbit LED3 = P1^2;   

void main()
{
    LED1 = 0;   //发送低电平信号使得二极管导通,从而点亮LED灯
    LED3 = 0;
}

点灯方式2
P1的8个口一起操作,由于操作时是按位操作,所以赋值的数是二进制数,二进制数位上的0和1就分别代表了低电平和高电平,但是写程序时一般会赋值16进制的数。
二进制高位到低位就对应了P1的8个口从大到小的序号

/*
 * @Descripttion: 直接对IO口赋值点亮LED灯
 * @Author: 五月雨
 * @Date: 2021-05-16 22:39:29
 * @LastEditors: 五月雨
 * @LastEditTime: 2021-06-01 15:16:36
 */
#include <reg52.h>

void main()
{
    //P1已经定义在了头文件reg52.h中,直接赋值即可
    P1 = 0xFA;  //1111 1010
}

实现LED灯闪烁

原理
由于程序中,main函数是会自动循环的,所以如果不加延时,直接让LED灯点亮然后再熄灭的话,对于人来说是看不到闪烁的。所以,针对于人眼的视觉暂留效应,需要添加延时,使得LED灯亮和灭的时间间隔在人眼可见范围内。
而延时分为软件延时(占用CPU资源)和定时延时(使用寄存器,不浪费CPU资源),这里由于初学,采用的是实现较为简单的软件延时。
实践
实现不可控延时闪烁

/*
 * @Descripttion: 实现不可控延时LED灯闪烁
 * @Author: 五月雨
 * @Date: 2021-06-01 15:25:34
 * @LastEditors: 五月雨
 * @LastEditTime: 2021-06-01 15:34:05
 */
#include <reg52.h>

#define uint unsigned int

void delay()    //不可控延时函数
{
    uint i = 65535; //无符号整形最大值
    while(i--);
}

void main() //main函数会自动循环
{ 
    P1 = 0; //等价于十六进制0x00,把P1的每一个口赋值成0,点亮
    delay();    //利用人眼的视觉暂留效应实现闪烁
    P1 = 0xFF;  //熄灭
    delay();
}

实现可控延时闪烁

/*
 * @Descripttion: 实现可控延时LED灯闪烁
 * @Author: 五月雨
 * @Date: 2021-07-15 17:29:33
 * @LastEditors: 五月雨
 * @LastEditTime: 2021-07-15 17:50:55
 */
#include <reg52.h>

#define uint unsigned int

void delay_ms(uint z)   //毫秒级延时函数
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;    //114可以用单片机精灵算,为的是实现毫秒级延时
}

void main() //main函数会自动循环
{
    P1 = 0; //等价于十六进制的0x00,把P1的每一个口赋值成0,点亮8个LED灯
    delay_ms(100);    
    P1 = 0xFF;  //等价于二进制1111 1111,把P1的每一个口赋值成1,熄灭8个LED灯
    delay_ms(100);    
}

使用库函数实现流水灯闪烁

/*
 * @Descripttion: 使用库函数实现流水灯闪烁
 * @Author: 五月雨
 * @Date: 2021-07-15 18:00:45
 * @LastEditors: 五月雨
 * @LastEditTime: 2021-07-15 18:04:52
 */
#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

void delay_ms(uint z)   
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ; 
}

uchar temp;
void main() 
{
    temp = 0xFE;   //只让第一个LED点亮
    P1 = temp;
    delay_ms(500);
    while(1)
    {
        temp = _crol_(temp, 1); //循环左移
        P1 = temp;
        delay_ms(500); 
    }
}

使用循环实现推推点灯

#include<reg52.h>

#define uchar unsigned char

void delay_ms(uchar z)
{
	uchar x, y;
	for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;
}

void main()
{
	uchar m = 255;
	while(1)
	{
		P1 = m;
		delay_ms(100);
		m--;
	}
}

自己写的组合点灯

/*
 * @Descripttion: 自己写的组合点灯
 * @Author: 五月雨
 * @Date: 2021-07-15 18:11:59
 * @LastEditors: 五月雨
 * @LastEditTime: 2021-07-15 18:12:19
 */
#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char
uchar temp;
uint i;

void delay_ms(uint z)   
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;    //114可以用单片机精灵算出,为的是实现毫秒级延时
}

/*下面的点亮函数中,延时函数的参数设置为不同时长,看起来更有层次感*/
void left() //向左依次点亮一个灯
{
    temp = 0xFE;   //只让第1个LED点亮
    P1 = temp;
    delay_ms(100);
    for(i = 0; i < 7; i++)
    {
        temp = _crol_(temp, 1); //循环左移
        P1 = temp;
        delay_ms(100); 
    }
    P1 = 0xFF;
    delay_ms(150);
}

void right()    //向右依次点亮一个灯
{
    temp = 0x7F;   //只让第8个LED点亮
    P1 = temp;
    delay_ms(100);
    for(i = 0; i < 7; i++)
    {
        temp = _cror_(temp, 1); //循环右移
        P1 = temp;
        delay_ms(100); 
    }
    P1 = 0xFF;
    delay_ms(150);
}

void side_to_mid()  //从两边向中间依次点亮一个灯
{
    P1 = 0x7E;
    delay_ms(200);
    P1 = 0xBD;
    delay_ms(150);
    P1 = 0xDB;
    delay_ms(100);
    P1 = 0XE7;
    delay_ms(100);
    P1 = 0xFF;
    delay_ms(150);
}

void mid_to_side()  //从中间向两边依次点亮一个灯
{
    P1 = 0XE7;
    delay_ms(200);
    P1 = 0xDB;
    delay_ms(150);
    P1 = 0xBD;
    delay_ms(100);
    P1 = 0x7E;
    delay_ms(100);
    P1 = 0xFF;
    delay_ms(150);
}

void all()  //从两边向中间全部点亮
{
    P1 = 0x7E;
    delay_ms(200);
    P1 = 0x3C;
    delay_ms(150);
    P1 = 0x18;
    delay_ms(100);
    P1 = 0X00;
    delay_ms(150);
}

void main() 
{
    left();
    right();
    side_to_mid();
    mid_to_side();
    all();
    while(1);   //保持全亮状态
}

Keil中的调试工具

工具栏中一个像放大镜一样的debug功能,可以看IO口在执行完语句的变化。
在debug前记得先点击魔法棒图标,设置晶振频率,我所使用的开发板频率为11.0592MHz
先编译再进入debug模式,进入之后可以选择IO口监控状态。同时左边的窗口中有程序运行的时间等等信息,右下角窗口可以选择具体的变量进行监控。左上角可以选择调试模式。

蜂鸣器

原理
单片机是用于控制的,不适合驱动功率器件,所以并不是直接将IO口接到蜂鸣器上面,因为它的输出电流很小,而是用三极管作开关管,再加一个限流电阻,来控制蜂蜜器是否发声的。
直流电机不能直接接到开发板电源上,因为在其结束转动时有较高的反电动势,可能会损坏开发板。
实践
直接在流水灯的代码上稍加修改即可,蜂鸣器在P23口,如果直接赋值给beep一个逻辑0的话,就会使其发出连续不间断的蜂鸣声。

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char
uchar temp;
sbit beep = P2^3;

void delay(uint z)
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--);
}

void main()
{
    temp = 0xF0;
    P1 = temp;
    delay(100);
    while(1)
    {
        temp = _crol_(temp, 1);
        P1 = temp;
        beep = ~beep;   //不断取反,使得其每间隔100ms发声
        delay(100);
    }
}

数码管

原理
数码管内部由8颗LED组成,想要显示什么样的字符,就控制想要显示的部分亮起,其他部分熄灭即可。一般分为两种,共阴极和共阳极。两者只在公共脚处不同,公共脚为VCC的是共阳极,为GND的是共阴极。可以用万用表连接公共脚和其他任意脚即可测出数码管类型。
数码管的公共脚叫做位选,其他脚叫做段选。位选用来选择数码管哪一位亮起,段选用来选择亮起数码管的哪些LED灯亮。
我所使用的开发板中,数码管为共阴极型的,由于它们的阴极连接的公共脚是接地,为低电平,那么给数码管输入高电平即可电亮LED管。
数码管显示分为静态显示动态显示。这里先详细学习静态显示。
静态显示比较占IO口,因为每个数码管的段选都必须接一个8位数据线来保持显示的字形码,显示的字形可以一直保持,直到送入新的字形。
锁存器
可以把数据输入端与输出端进行隔离或连接。 以74HC573为例:
https://gitee.com/cindycyber/blog-pic/raw/master/img/20210502221150.png
https://gitee.com/cindycyber/blog-pic/raw/master/img/20210502221209.png
输出口Q要想输出高低电平,OE脚必须接GND。
LE脚为高时,输出端Q随输入端D的数据而变化。LE脚为低时,输出端Q数据保持不变,输入端D数据变化不会改变Q的数据。
上拉电阻
将不确定的信号通过一个限流电阻(一般为10k-4.7k欧姆的电阻)钳位在高电平,下拉同理,钳位在低电平。准双向IO中有上拉电阻,那么它就既能够输出高电平又能够输出低电平,而漏极开路输出电路,由于没有上拉电阻,就只能输出低电平,输入高电平会让它处于开路状态。

2021/05/03

由于使用的是共阴极数码管,位选就是阴极,所以给位选输入低电平才能使得数码管中的LED在输入高电平之后能够导通,从而发亮。
实践

#include <reg52.h>

sbit digit_selector = P2^7;
sbit segment_selector = P2^6;

void main()
{       
    digit_selector = 1; //输入高电平,打开位选锁存器
    P0 = 0xFE;  //只电亮第一位数码管
    digit_selector = 0; //锁存位选数据
    
    segment_selector = 1;   //打开段选锁存器
    P0 = 0x06;  //使数码管显示1
    segment_selector = 0;   //锁存段选数据
    
    while(1)
    {
        //由于使用了锁存器,下面这条语句不会生效
        P0 = 0x01;
    }
}

接下来实现动态显示
原理
利用人眼的视觉暂留效果和LED发光的余辉,使得人眼看起来像各位上的数码管像是在显示不同的数字。
实践
由于位选和段选共用P0口,所以需要清除P0中的段选数据,防止这个数据在开启位选锁存器后,短暂地影响到位选中的数据。
数码表使用code关键字可以使得其中的数据不会被修改,而默认是用data关键字修饰的,也就是数码表中的数据是可以被更改的,但由于data关键字所对应的存储区域很小,所以这里用code好些。

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char 
uchar code num_table[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
sbit digit_selector = P2^7;
sbit segment_selector = P2^6;

void delay_ms(uint z)
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;
}

void display(uchar n)
{
    uchar hrd, dcd, dgt;    //百位,十位,个位
    hrd = n / 100;
    dcd = n % 100 / 10;
    dgt = n % 10; 
    
    //第一位数码管
    P0 = 0xFF;  //清除断码(段选数据)
    digit_selector = 1; 
    P0 = 0xFE;  
    digit_selector = 0; 
    
    segment_selector = 1;   
    P0 = num_table[hrd];  
    segment_selector = 0; 
    delay_ms(5);    //使得数字显示不重叠
    
    //第二位数码管
    P0 = 0xFF;
    digit_selector = 1; 
    P0 = 0xFD;  
    digit_selector = 0; 
    
    segment_selector = 1;   
    P0 = num_table[dcd];  
    segment_selector = 0; 
    delay_ms(5);
    
    //第三位数码管
    P0 = 0xFF;
    digit_selector = 1; 
    P0 = 0xFB;  
    digit_selector = 0; 
    
    segment_selector = 1;   
    P0 = num_table[dgt];  
    segment_selector = 0;
    delay_ms(5);
}

void main()
{       
    display(123);
}

独立键盘

理论
键盘是一种轻触开关,常态下保持断开状态,按下按键时才闭合。
MCU组成的各种系统中,最常用非编码键盘,它靠软件来识别按下的是哪个按键,程序较复杂,电路简单。还有一种是编码键盘,计算机使用的就是这种键盘。相对的,它的按键键值由硬件电路产生,使用方便,程序简单,电路复杂。
非编码键盘又分为独立键盘矩阵键盘
独立键盘的每个按键占用一个IO口,因此IO口利用率不高,但程序简单,适用于所需按键较少的场合。
矩阵键盘电路连接和软件编程都较复杂,但提高了IO口利用率,适用于大量按键的场合。
由独立按键的内部结构原理图可以知道,由于按键的一端接到了GND,而IO口默认输入是高电平,所以在准双向IO口中,检测到低电平就说明按键被按下了,反之则没有被按下。

2021/05/04

实践
注意机械按键都会有抖动存在,所以需要消抖,并且是按下和松开时都要消抖,否则会导致显示的数字因为这个抖动而变化。

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char 
uchar code num_table[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
uchar num;  //数码管显示的值
sbit digit_selector = P2^7;
sbit segment_selector = P2^6;
sbit key_s2 = P3^0; //独立键盘的第一个按键
sbit key_s3 = P3^1; //独立键盘的第二个按键

void delay_ms(uint z)
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;
} 

void main()
{       
    //只使用第一位数码管的值
    digit_selector = 1; 
    P0 = 0xFE;  
    digit_selector = 0; 
    
    while(1)
    {
        if(key_s2 == 0) //判断S2是否被按下,若按下,第一位数码管数字加一
        {
            delay_ms(20);   //消除按键抖动
            if(num < 9) num++;  //使得显示的值只在0~9范围内,且加一时不超过9
            
//            //按下就变化数码管的值
//            segment_selector = 1;   
//            P0 = num_table[num];  
//            segment_selector = 0; 
            
            while(!key_s2); //松手检测,当松手才继续执行下面的语句,否则数字仍会一直循环变化
        }
        
        if(key_s3 == 0) //判断S3是否被按下,若按下,第一位数码管数字减一
        {
            delay_ms(20);   //消除按键抖动
            if(num > 0) num--;  //使得显示的值只在0~9范围内,且减一时不低于0
            
//            //按下就变化数码管的值
//            segment_selector = 1;   
//            P0 = num_table[num];  
//            segment_selector = 0; 
            
            while(!key_s3); //松手检测,当松手才继续执行下面的语句,否则数字仍会一直循环变化
        }
        
        //松手之后刷新显示,即使循环里有这三句(按下独立键盘
        //数码管显示就变化的情况下),这里也不能去掉,因为循
        //环是一直进行的,去掉后在没按键时就会显示位选中P0的值
        segment_selector = 1;   
        P0 = num_table[num];  
        segment_selector = 0; 
    }
}

2021/05/06

矩阵键盘+独立键盘

理论
由原理图可知,这16个键盘可以分别按照列和行的位置来唯一确定。 需要确定按下按键的位置,只需要分别进行列扫描和行扫描即可。
以先进行列扫描位列,需要确定列的位置,那么就把列所连接的IO口置为高电平,因为按下按键电路连通之后(原先是断开状态),高电平与低电平连通,会被拉低成低电平,那么检测列所连接的IO口哪个变成了低电平即可知道是哪一列按下。对于行同理。
实践

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char 
uchar code num_tabel[]= {
//0		1	  2     3     4     5     6     7     8
  0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9     A     B	    C	  D	    E	  F		H	  L	 
  0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x76, 0x38,
//n	    u	  -	    熄灭
  0x37, 0x3E, 0x40, 0x00 
};
uchar keyValue = 20;  //没有按下按键时默认显示'-'
sbit digit_selector = P2^7;
sbit segment_selector = P2^6;

void delay_ms(uint z)
{
    uint x, y;
    for(x = z; x > 0; x--)
        for(y = 114; y > 0; y--) ;
} 

void key_scan()
{
    /*矩阵键盘检测*/
    //列检测
    P3 = 0xF0;
    if(P3 != 0xF0)  //判断是否有按键被按下
    {
        delay_ms(10);   //消抖
        switch(P3)
        {
            case 0xE0: keyValue = 0; break; //第一列有按键被按下
            case 0xD0: keyValue = 1; break; //第二列有按键被按下
            case 0xB0: keyValue = 2; break; //第三列有按键被按下
            case 0x70: keyValue = 3; break; //第四列有按键被按下
        }
        
        //行检测
        P3 = 0x0F;
        switch(P3)
        {
            case 0x0E: keyValue = keyValue + 0; break; //第一行有按键被按下
            case 0x0D: keyValue = keyValue + 4; break; //第二行有按键被按下
            case 0x0B: keyValue = keyValue + 8; break; //第三行有按键被按下
            case 0x07: keyValue = keyValue + 12; break; //第四行有按键被按下
        }
        
        while(P3 != 0x0F) ; //松手检测
    }
    
    /*独立键盘检测*/
    P3 = 0xFF;  
    if(P3 != 0xFF)
    {
        delay_ms(10);
        switch(P3)
        {
            case 0xFE: keyValue = 16; break;
            case 0xFD: keyValue = 17; break;
            case 0xFB: keyValue = 18; break;
            case 0xF7: keyValue = 19; break;
        }
        
        while(P3 != 0xFF) ;
    }
}

void main()
{       
    //只使用第一位数码管的值
    digit_selector = 1; 
    P0 = 0xFE;  
    digit_selector = 0; 
    
    segment_selector = 1;   //打开段选锁存器
    while(1)
    {
        key_scan();
        P0 = num_tabel[keyValue];
    }
}

中断系统

理论
计算机执行某程序时,发生了紧急事件或有特殊请求,CPU暂停某程序的执行,转而去处理上述事件或请求,处理完毕后再重新执行某程序的过程叫做中断。
为了让我们更加方便的理解中断这个概念,举例:假设你正在吃饭,这时接到快递员电话叫你下楼取快递只等5分钟,这就是中断请求。然后你回答:“好的我现在就来”这就是中断响应。接着你停止吃饭下楼去取快递,这就是中断处理。取完快递,你再回来接着吃饭,这就叫做中断返回。从以上可以看出,中断分为4个步骤:中断请求->中断响应->中断处理->中断返回。