要学习51单片机中断的朋友,拥有这一篇博文就够了,深入浅出,里面包含了寄存器,外部中断、定时器中断、中断嵌套等的讲解,还有代码实战。快一万字,写得不容易,还请大家点赞支持一下,后续持续更新

  • (一)寄存器
    • 1.什么是寄存器
    • 2.寄存器怎么用
  • (二)中断
    • 1.中断允许寄存器IE
      • EX0
      • ET0
      • EX1
      • ET1
      • ES
      • EA
      • 使用方法
    • 2.中断优先级寄存器IP
      • PS——串行口中断优先级控制位
      • PT1——定时器/计数器1中断优先级控制位
      • PX1——外部中断1中断优先级控制位
      • PT0——定时器/计数器0中断优先级控制位
      • PX0——外部中断0中断优先级控制位
    • 中断优先级(高到低)
    • 3.TCON寄存器
      • TF1:片内定时器/计数器T1的溢出中断请求标志位。
      • TF0:片内定时器/计数器T0的溢出中断请求标志位。
      • IE1:外部中断请求1的中断请求标志位。
      • IE0: 外部中断请求0的中断请求标志位。
      • IT1:选择外部中断请求1为负跳变触发方式还是电平触发方式。
      • IT0:选择外部中断请求0为负跳变触发还是电平触发方式。
    • 4.SCON寄存器
      • TI:串行口发送中断请求标志位。
      • RI:串行口接收中断请求标志位。
  • (三)外部中断
    • 1.外部中断0,按下开关K3,数码管0变1
      • 寄存器配置:
      • 完整代码:
    • 2.外部中断1,按下开关K4,数码管0变1
      • 寄存器配置:
      • 完整代码:
    • 3.外部中断扩展
      • 寄存器配置:
      • 完整代码:
  • (四)定时器中断
    • 1.定时器0
      • 寄存器配置:
      • 完整代码:
    • 2.定时器1
      • 寄存器配置:
      • 完整代码:
    • 3.定时器计数控制数码管0到60
      • 寄存器配置:
      • 完整代码:
    • 4.定时器做的时钟
      • 寄存器配置:
      • 完整代码:
  • (五)中断嵌套
    • 1.外部中断嵌套K3,K4
      • 寄存器配置:
      • 完整代码:

(一)寄存器

要想学习中断那么首先就要了解寄存器,在这里我们学习一下什么是寄存器,寄存器怎么用。

1.什么是寄存器

寄存器是特殊的RAM,特殊功能寄存器是控制单片机硬件的开关(例如IE)或者是指示单片机状态的信号(例如PSW),通过特殊寄存器你就可以方便的控制整个MCU,并且知道当前的MCU的工作状态。

2.寄存器怎么用

AT89S51单片机中的特殊功能寄存器(SFR)的单元地址映射在片内RAM区的80H~FFH区域中,它共有26个,离散地分布在该区域中。用到哪个寄存器就相应配置哪个寄存器即可。寄存器太多就不一一写出来了,用到再去找就好。

(二)中断

单片机的中断是由单片机片内的中断系统来实现的。当中断请求源(简称中断源)发出中断请求时,如果中断请求被允许的话,单片机暂时中止当前正在执行的主程序,转到中断服务程序处理中断服务请求,处理完中断服务请求后,再回到原来被中止的程序之处(断点),继续执行被中断的主程序。

1.中断允许寄存器IE

EX0

外部中断0允许位。EX0=1,允许外部中断0中断;EX0=0,禁止外部中断0中断。当EX0=1( SETB EX0 )时,同时单片机P3.2引脚上出现中断信号时,单片机中断主程序的执行而“飞”往中断服务子程序,执行完后通过中断返回指令RET 动返回主程序。当EX0=0( CLR EX0)时,即使单片机P3.2引脚上出现中断信程序也不会从主程序“飞” 出去执行,因为此时单片机的CPU相当于被“堵上了耳朵”,根本接收不到P3.2引脚上的中断信号,但是这并不表示这个信号不存在。如果单片机的CPU有空查一下TCON中的IE0位,若为1就说明有中断信号出现过。

ET0

T0溢出中断允许位。ET0=1,允许T0中断;ET0=0,禁止T0中断。

EX1

外部中断1允许位。EX1=1,允许外部中断1中断;EX1=0,禁止外部中断1中断。当EX1=1( SETB EX1)时,并且外部P3.3引脚上出现中断信号时,单片机CPU会中断主程序而去执行相应的中断服务子程序;当EX1=0( CLR EX1)时使外部P3.3引脚上即使出现中断信号,单片机的CPU也不能中断主程序转而去行中断服务子程序。
因此,可以这样认为,EX0和EX1是决定CPU能否感觉到外部引脚P3.2P3.3上的中断信号的控制位。

ET1

T1溢出中断允许位。ET1=1,允许T1中断;ET1=0,禁止T1中断。

ES

串行中断允许位。ES=1,允许串行口中断;ES=0,禁止串行口中断。

EA

中断总允许位。EA=1,CPU开放中断;EA=0,CPU禁止所有的中断请求。总允许EA好比一个总开关。EA就相当于每家水管的总闸,如果总闸不开,各个龙头即使开了也不会有水;反过来,如果总闸开了而各个分闸没开也不会有水,所当我们想让P3.2和P3.3引脚上的信号能够中断主程序则必须将EA位设置为0(CLR EA)。

使用方法

(1)整体赋值:IE=0x81;(开启全局中断,打开外部中断0 )。
(2)单独赋值:EA=1;EX0=1;(开启全局中断,打开外部中断0 )。

2.中断优先级寄存器IP

PS——串行口中断优先级控制位

PS=1,串行口中断定义为高优先级中断。
PS=0,串行口中断定义为低优先级中断。

PT1——定时器/计数器1中断优先级控制位

PT1=1,定时器/计数器1中断定义为高优先级中断。
PT1=0,定时器/计数器1中断定义为低优先级中断。

PX1——外部中断1中断优先级控制位

PX1=1,外部中断1定义为高优先级中断。
PX1=0,外部中断1定义为低优先级中断。

PT0——定时器/计数器0中断优先级控制位

PT0=1,定时器/计数器0中断定义为高优先级中断。
PT0=0,定时器/计数器0中断定义为低优先级中断。

PX0——外部中断0中断优先级控制位

PX0=1,外部中断0定义为高优先级中断。
PX0=0,外部中断0定义为低优先级中断。

中断优先级(高到低)

外部中断0
T0溢出中断
外部中断1
T1溢出中断
串行口中断
T2溢出中断(52)

3.TCON寄存器

TF1:片内定时器/计数器T1的溢出中断请求标志位。

当启动T1计数后,定时器/计数器T1从初值开始加1计数,当计数溢出时,由硬件自动为TF1置“1”,向CPU申请中断。CPU响应TF1中断时,TF1标志位由硬件自动清零,TF1也可由软件清零。

TF0:片内定时器/计数器T0的溢出中断请求标志位。

功能与TF1相同。

IE1:外部中断请求1的中断请求标志位。

IE1=0,无中断请求。
IE1=1,外部中断1有中断请求。当CPU响应该中断,转向中断服务程序时,由硬件清“0”IE1。

IE0: 外部中断请求0的中断请求标志位。

IE0=0,无中断请求。
IE0=1,外部中断0有中断请求。当CPU响应该中断,转向中断服务程序时,由硬件清“0”IE0。

IT1:选择外部中断请求1为负跳变触发方式还是电平触发方式。

IT1=0,为电平触发方式,外部中断请求输入信号为低电平有效,并把IE置“1”。转向中断服务程序时,则由硬件自动把IE1清零。
IT1=1,为负跳变触发方式,外部中断请求输入信号电平为从高到低的负跳变有效,,并把IE置“1”。转向中断服务程序时,则由硬件自动把IE1清零。

IT0:选择外部中断请求0为负跳变触发还是电平触发方式。

与IT1相似。

4.SCON寄存器

TI:串行口发送中断请求标志位。

当CPU将1字节的数据写入串行口的发送缓冲器SBUF时,就启动一帧串行数据的发送,每发送完一帧串行数据后,硬件把TI中断请求标志位自动置“1”。CPU响应串行口发送中断时,并不能清除TI标志位,TI标志位必须在中断服务程序中用指令对其清零。

RI:串行口接收中断请求标志位。

在串行口接收完一个串行数据帧,硬件自动使RI中断请求标志位置“1”。CPU在响应串行口接收中断时,RI标志位并不清零,必须在中断服务程序中用指令对RI清零。

(三)外部中断

51单片机的外部中断int0对应的引脚为p3.2,外部中断int1对应的引脚为p3.3。

1.外部中断0,按下开关K3,数码管0变1

寄存器配置:

    EA=1;//总中断允许EX0=1;//允许外部中断0IT0=0;//选择外部中断0为电平触发方式

完整代码:

#include<reg51.h>
#define uchar unsigned char
sbit key = P3^2;void delay(unsigned int i)//延时函数
{unsigned int j;for(;i>0;i--)for(j=0;j<333;j++){}
}void main()//主函数
{EA=1;//总中断允许EX0=1;//允许外部中断0IT0=0;//选择外部中断0为电平触发方式while(1)//循环{P0=0x3f;}//P0.0口的Led亮
}
void key_scan() interrupt 0 //外部中断0的中断服务函数
{if(key==0)//判断是否有按键按下{delay(10);//延时去抖if(key==0){P2=0xfe;P0=0x06;while(!key);//等待按键松开P2=0xff;P0=0x3f;}}
}

2.外部中断1,按下开关K4,数码管0变1

寄存器配置:

    EA=1;//总中断允许EX1=1;//允许外部中断0IT1=0;//选择外部中断0为电平触发方式

完整代码:

#include<reg51.h>
#define uchar unsigned char
sbit key = P3^3;void delay(unsigned int i)//延时函数
{unsigned int j;for(;i>0;i--)for(j=0;j<333;j++){}
}void main()//主函数
{EA=1;//总中断允许EX1=1;//允许外部中断0IT1=0;//选择外部中断0为电平触发方式while(1)//循环{P0=0x3f;}//P0.0口的Led亮
}
void key_scan() interrupt 1 //外部中断1的中断服务函数
{if(key==0)//判断是否有按键按下{delay(10);//延时去抖if(key==0){P2=0xfe;P0=0x06;while(!key);//等待按键松开P2=0xff;P0=0x3f;}}
}

3.外部中断扩展

寄存器配置:

    IT0 = 1;//跳沿触发IT1 = 1;//跳沿触发PX1 = 1;//中断1高于中断0IE = 0x85;/*由低到高:EX1(第3位)=1,EX0 (第0位)= 1,EA (第八位)= 1 IE = 10000101*/

完整代码:

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uint i;
void delay(uint xms);
void Int();
void Interrupt0();
void Interrupt1(); void main()
{Int();P2 = 0xfe;
while(1)
{for (i = 0;i < 7;i++){P2 = _crol_(P2, 1);//先左移delay(600);}for (i = 0;i < 7;i++){P2 = _cror_(P2, 1);//再右移delay(600);}}}void Int()
{IT0 = 1;//跳沿触发IT1 = 1;//跳沿触发PX1 = 1;//中断1高于中断0IE = 0x85;/*由低到高:EX1(第3位)=1,EX0 (第0位)= 1,EA (第八位)= 1 IE = 10000101*/
}void delay(uint xms)//AT89C5211.0592MHz
{uint x, y;for (x = xms;x > 0;x--)for (y = 110;y > 0;y--);
}void Interrupt1() interrupt 0
{while (1){P2 = 0x0f;delay(600);P2 = 0xf0;delay(600);}
}
void Interrupt2() interrupt 2/*外部中断1的标号是2!*/
{while (1){P2 = 0xcc;//(11001100)delay(600);P2 = 0x33;delay(600);}}

(四)定时器中断

1.定时器0

寄存器配置:

  TMOD = 0x01;TH0 = (65536 - 45872) / 256; // 设置定时器0为工作方式1(M1M0为01)TL0 = (65536 - 45872) % 256; // 装初值11.0592M晶振定时50ms数位45872EA = 1; // 开总中断ET0 = 1; // 开定时器0中断TR0 = 1; // 启动定时器0

完整代码:

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1 = P2^0;
uchar num = 0;void main()
{TMOD = 0x01;TH0 = (65536 - 45872) / 256; // 设置定时器0为工作方式1(M1M0为01)TL0 = (65536 - 45872) % 256; // 装初值11.0592M晶振定时50ms数位45872EA = 1; // 开总中断ET0 = 1; // 开定时器0中断TR0 = 1; // 启动定时器0while(1){;}
}void T0_time() interrupt 1
{TH0 = (65536 - 45872) / 256;TL0 = (65536 - 45872) % 256;num++;if (num == 20){num = 0;led1 = ~led1;}
}

2.定时器1

寄存器配置:

  TMOD = 0x01;TH0 = (65536 - 45872) / 256; // 设置定时器1为工作方式1(M1M0为01)TL0 = (65536 - 45872) % 256; // 装初值11.0592M晶振定时50ms数位45872EA = 1; // 开总中断ET1 = 1; // 开定时器1中断TR1 = 1; // 启动定时器1

完整代码:

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit led1 = P2^0;
uchar num = 0;void main()
{TMOD = 0x01;TH0 = (65536 - 45872) / 256; // 设置定时器1为工作方式1(M1M0为01)TL0 = (65536 - 45872) % 256; // 装初值11.0592M晶振定时50ms数位45872EA = 1; // 开总中断ET1 = 1; // 开定时器1中断TR1 = 1; // 启动定时器1while(1){;}
}void T1_time() interrupt 3
{TH0 = (65536 - 45872) / 256;TL0 = (65536 - 45872) % 256;num++;if (num == 20){num = 0;led1 = ~led1;}
}

3.定时器计数控制数码管0到60

寄存器配置:

    TMOD=0x11;//写在一起//定时器0//TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-45872)%256;EA=1;ET0=1;TR0=1;//定时器1//TMOD=0x10;TH1=(65536-45872)/256;TL1=(65536-45872)%256;EA=1;ET1=1;TR1=1;

完整代码:

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴极数码管编码
uchar num0,num1;
uint ge ,shi;
sbit LSA=P2^2;//74HC138译码器端口
sbit LSB=P2^3;
sbit LSC=P2^4;
void  display_time(uint ,uint);
void delay_ms(uint);void main()
{TMOD=0x11;//写在一起//定时器0//TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-45872)%256;EA=1;ET0=1;TR0=1;//定时器1//TMOD=0x10;TH1=(65536-45872)/256;TL1=(65536-45872)%256;EA=1;ET1=1;TR1=1;while(1){   display_time(ge ,shi);//时间一直显示中}
}void T0_time()interrupt 1 //数码管处理 T0定时器
{TH0=(65536-45872)/256;//每50ms产生一次中断TL0=(65536-45872)%256;//所以每20次中断,个位+1num0++;if(num0==20){num0=0;ge++;if(ge==10){shi++; //时间进位ge=0;}if(shi==6)shi=0; //时间归零}
}void  display_time(uint ge ,uint shi)
{LSA=0;LSB=1;LSC=1;P0=table[ge];//送入个位数字delay_ms(5);LSA=1;LSB=1;LSC=1;P0=table[shi];//送入十位数字delay_ms(5);
}
void delay_ms(uint ms)
{uint i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);
}

4.定时器做的时钟

寄存器配置:

    TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-45872)%256;EA=1;ET0=1;TR0=1;

完整代码:

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴极数码管编码
uchar num;
uint hour_ge,hour_shi,minute_ge, minute_shi,second_ge,second_shi;
sbit LSA=P2^2;//74HC138译码器端口
sbit LSB=P2^3;
sbit LSC=P2^4;
void  display_time(uint,uint,uint,uint,uint,uint);
void delay_ms(uint);
void main()
{TMOD=0x01;TH0=(65536-45872)/256;TL0=(65536-45872)%256;EA=1;ET0=1;TR0=1;while(1){ display_time(hour_shi,hour_ge,minute_shi,minute_ge,second_shi,second_ge);//时间一直显示中}
}void T0_time()interrupt 1 //数码管处理 T0定时器
{TH0=(65536-45872)/256;//每50ms产生一次中断TL0=(65536-45872)%256;//所以每20次中断,个位+1num++;if(num==20){num=0;second_ge++;//秒+1}if(second_ge==10){second_ge=0;second_shi++;if(second_shi==6){second_shi=0;minute_ge++;if(minute_ge==10){minute_ge=0;minute_shi++;if(minute_shi==6){minute_shi=0;hour_ge++;if(hour_ge==10){hour_ge=0;hour_shi++;if(hour_shi==2&&hour_ge==4){hour_shi=0;hour_ge=0;}}  }   }}}}void display_time(uint hour_shi,uint hour_ge,uint minute_shi,uint minute_ge,uint second_shi,uint second_ge)
{LSA=0;LSB=0;LSC=0;//第六个数码管送入second_geP0=table[second_ge];delay_ms(1);LSA=1;LSB=0;LSC=0;//第五个数码管送入second_shiP0=table[second_shi];delay_ms(1);LSA=1;LSB=1;LSC=0;//第四个数码管送入minute_ge P0=table[minute_ge];         delay_ms(1);LSA=0;LSB=0;LSC=1;//第三个数码管送入minute_shi P0=table[minute_shi];delay_ms(1);LSA=0;LSB=1;LSC=1;//第二个数码管送入hour_geP0=table[hour_ge];delay_ms(1);LSA=1;LSB=1;LSC=1;//第一个数码管送入hour_shiP0=table[hour_shi];delay_ms(1);}void delay_ms(uint ms)
{uint i,j;for(i=ms;i>0;i--)for(j=110;j>0;j--);
}

(五)中断嵌套

1.外部中断嵌套K3,K4

寄存器配置:

    IT0 = 1;IT1 = 1;PX0 = 1;IE = 0x85;/*由低到高:EX1(第3位)=1,EX0 (第0位)= 1,EA (第八位)= 1 IE = 10000101*/

完整代码:

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED1 = P2 ^ 0;
sbit LED2 = P2 ^ 1;void Int();
void Interrupt1();
void Interrupt2(); void main()
{Int();while (1);}void Int()
{IT0 = 1;IT1 = 1;PX0 = 1;IE = 0x85;/*由低到高:EX1(第3位)=1,EX0 (第0位)= 1,EA (第八位)= 1 IE = 10000101*/
}void Interrupt1() interrupt 0
{LED1 = ~LED1;}
void Interrupt2() interrupt 2/*外部中断1的标号是2!*/
{LED2 = ~LED2;}

看到最后相信你也应该收获到很多,一起进步吧!

51单片机学习笔记之中断(外部中断、定时器中断、中断嵌套)相关推荐

  1. AutoLeaders控制组—51单片机学习笔记

    文章目录 AutoLeaders控制组-51单片机学习笔记 1.1单片机及开发板介绍 单片机介绍 单片机应用领域 STC89C52单片机 内部结构 开发板介绍 2.1点亮一个Led 新建工程 编程 认 ...

  2. 51单片机学习笔记2 仿真器的使用及STC89Cxx简介

    51单片机学习笔记2 仿真器的使用及STC89Cxx简介) 一.连接步骤 1. 硬件连接 2. 安装软件驱动 3. 检查是否安装成功 二.仿真步骤 1. 打开一个51工程 2. 选择仿真设备 3. S ...

  3. 51单片机学习笔记-1简介及点灯

    51单片机学习笔记 文章目录 51单片机学习笔记 1. 51单片机简介 1.1 安装软件 1.2 单片机简介 2. LED灯 2.1点亮一个LED 2.1.1原理分析 2.1.2 创建工程 2.2LE ...

  4. [51单片机学习笔记TWO]----蜂鸣器

    蜂鸣器音乐播放实验 首先应该了解一下蜂鸣器音乐播放的原理,在这里我只讲一下电磁式蜂鸣器驱动原理(还有一种是压电式蜂鸣器): 电磁式蜂鸣器驱动原理: 蜂鸣器发声原理是电流通过电磁线圈,使电磁圈产生磁场来 ...

  5. 单片机c语言北航,【下载资料】《51单片机学习笔记》北航版

    原标题:[下载资料]<51单片机学习笔记>北航版 如果手机下载有问题,请移步至电脑端,链接:https://forum.mianbaoban.cn/t/topic/36906 内容简介 本 ...

  6. 51单片机学习笔记5 流水灯实现及蜂鸣器控制

    51单片机学习笔记5 流水灯实现及蜂鸣器控制 一.流水灯 1. 硬件电路 2. 代码实现 (1) 点亮一个LED的基本操作 (2) 使用算术左移实现流水灯 (3) 使用库文件左移函数 二.蜂鸣器 1. ...

  7. 51单片机学习笔记1 简介及开发环境

    51单片机学习笔记1 简介及开发环境 一.51单片机 1. STC89C52单片机简介 2. 命名规则 3. 封装 (1)PDIP (2)LQFP (3)PLCC (4)PQFP 二.STC8051结 ...

  8. AutoLeader控制组——51单片机学习笔记(一)

    目录 1.点亮LED灯 1.1LED灯闪烁 1.2控制LED灯按时闪烁: 1.3 LED灯流水灯 1.4二进制点灯 2.独立按键控制LED灯 2.1按键控制LED亮灭 2.2.按键控制灯左右移动 3. ...

  9. 51单片机学习笔记(郭天祥版)(3)——引脚讲解、数码管静态显示、中断系统(外部中断,定时器中断)...

    学习引脚的功能 9引脚 复位管脚,当给2个机器周期(24个时钟振荡周期)的高电平时会复位,单片机正常工作时会给0.5v的低电平 VPD备用电源的输入端,当主电源VCC发生故障降低到某一规定的低电平时, ...

最新文章

  1. Blender三维建筑场景动画制作学习教程
  2. 工业红外温度传感器 测温探头在线式4-20mA 变送器红外线非接触式
  3. 【maven】idea maven slf4j : StackOverflowError
  4. 华为云 EI 聚焦三大基础研究创新,助力产业智能升级
  5. C++ Copy Elision
  6. Taurus入门,这么神奇的性能测试工具不能不知道
  7. python误差修正模型_如何用格兰杰检验、协整对数据进行分析_格兰杰因果检验...
  8. 《符号学:原理与推演》(一)符号的构成
  9. mentohust 使用
  10. 实时交通仿真平台概要
  11. ECCV 2020预会议 直播笔记| Cross-Modal Weighting Network for RGB-D Salient Object Detection
  12. vue 前端仿QQ截图实现Web端自定义截屏(JS版)
  13. 激光打印机热定影器的组成以及维护
  14. GoogleEarth二次开发平台指南(1) ---如何将谷歌地球嵌入到自定义的窗体中
  15. STL教程:C++ STL快速入门
  16. 网桥调用iptables规则的善后处理
  17. 怎么把视频中的音乐给快速提取出来
  18. 查看Linux服务器公网内网IP地址
  19. 小小破解一下百度MP3的加密URL链接
  20. SiTime硅晶振相位噪声测量指南

热门文章

  1. C#多态的三种实现方式
  2. 计算机网络的预习与复习(六)
  3. 端口速率测试软件,新手必看GPS分辨率、端口、速率、内存检测工具
  4. websocket linux测试,Linux - WebSocket测试错误
  5. 网络安全之伪基站的危害
  6. 【Nexus】Linux安装Nexus
  7. PHP中的explode函数
  8. 百度:地震姜常宏,求传播?!!
  9. 君正T31L 编译烧录问题小结
  10. 微信小程序中清除定时器