51单片机中断处理环节(51单片机玩转物联网基础篇07-外部中断)
51单片机中断处理环节(51单片机玩转物联网基础篇07-外部中断)TCON为定时器/计数器T0、T1的控制器,同时也锁存了T0、T1的溢出中断源和外部中断源(1) 中断允许寄存器TCON(88H)中断是指CPU在执行A事件的时候,突然收到B事件发出的(中断)请求,CPU停止手中的事情,转而去执行B事件,B事件执行完毕后,又回到原来A事件被打断的地方,继续执行程序的过程,示意图如下所示:51单片机共有5个中断源,分别是外部中断0、外部中断1、定时器中断0、定时器中断1和串口中断,这5个中断源有二个中断优先级,每个中断源可以编程为高优先级和低优先级中断,可实现二级中断服务程序嵌套。2.中断寄存器
前言
本节我们开始,我们学习51单片机的中断系统,51单片机有5个中断源,我们首先学习外部中断,并通过中断方式检测P3^2接口是否有低电平产生。
一、基础知识
1.中断简介
中断是指CPU在执行A事件的时候,突然收到B事件发出的(中断)请求,CPU停止手中的事情,转而去执行B事件,B事件执行完毕后,又回到原来A事件被打断的地方,继续执行程序的过程,示意图如下所示:
51单片机共有5个中断源,分别是外部中断0、外部中断1、定时器中断0、定时器中断1和串口中断,这5个中断源有二个中断优先级,每个中断源可以编程为高优先级和低优先级中断,可实现二级中断服务程序嵌套。
2.中断寄存器
(1) 中断允许寄存器TCON(88H)
TCON为定时器/计数器T0、T1的控制器,同时也锁存了T0、T1的溢出中断源和外部中断源
各个控制位功能如下表
(2) 中断允许寄存器IE(A8H)
寄存器IE为特殊功能寄存器,控制CPU对中断源的开放或者屏蔽,以及每个中断源是否允许中断
各个控制位功能如下表
(3) 中断优先级寄存器IP(B8H)
特殊功能寄存器IP为中断优先级寄存器,保存各种中断源优先级控制位,用户可以通过软件控制
各个控制位功能如下表
当系统复位后,IP各位均为0,所有中断处于低优先级状态,低优先级中断可以被高优先级中断打断,反之则不行,一种中断一旦得到相应,与他同级的中断不能再中断打断,中断优先级默认如下
3.中断处理流程
系统启动后需要使用软件设置中断类型以及中断触发方式,并打开中断
void interrupt_init(void)
{
EA=1; // 打开总中断
IT0=1; // 外部中断0, P3.2引脚 下降沿触发
EX0=1
}
当中断源发出中断请求时候,CPU停止手头的工作,进入中断服务程序运行,中断服务程序按照如下流程处理
中断处理过程主要包括三个阶段,分别是:中断响应、中断处理、中断返回
4.硬件连接
硬件连接如下所示,通过杜邦线连接P32和GND,控制杜邦线插拔和GND连接一端,控制P32中断源输入的电平
二、示例程序
1.创建工程
将上一节工程复制出来,并修改名字为06-interrupt
2.修改程序
/*------------------------------------------------------
*店铺网址:https://shop321633213.taobao.com/?spm=a1z10.3-c.0.0.33816af5iLgN2F
*适用于A08开发板
*实验现象:驱动LCD1602
*QQ群:906015840
-------------------------------------------------------*/
#include<reg51.h> //头文件
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table_xiaoyi[]="XIAOYI IOT"; //
uchar code table_xiaoyi_welcome[]="Welcome!";
uchar code table_xiaoyi_interrupt[]="INT0!";
sbit LCD_EN=P3^7; //液晶使能信号
sbit LCD_RS=P3^5; //数据/命令选择端
sbit LCD_WR=P3^6;
int interrupt_flag = 0;
void delay_ms(uint ms)
{
uint x y;
for(x=ms;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com) //命令
{
LCD_RS=0; //选择写命令
P0=com;
delay_ms(5);
LCD_EN=1; //使能信号
LCD_EN=0; //关闭使能
}
void write_data(uchar date) //数据
{
LCD_RS=1; //选择写数据
P0=date;
delay_ms(5);
LCD_EN=1;
LCD_EN=0;
}
void init()
{
LCD_EN=0;
write_com(0x38); //00111000 设置16*2显示,5*7点阵 8为数据接口
write_com(0x0c); //00001100 设置开显示,不显示光标
write_com(0x06); // 00000110 写一个字符后地址指针加 1
write_com(0x01); //00000001 显示清0,数据指针清零 /* */
}
void interrupt_init(void)
{
EA=1; // 打开总中断
IT0=1; // 外部中断0, P3.2引脚 下降沿触发
EX0=1;
}
void main(void) //主函数
{
uchar i;
LCD_WR=0;
interrupt_init();
init();
// 写第一行数据
write_com(0x80);
for(i=0;i<10;i )
{
write_data(table_xiaoyi[i]);
delay_ms(5);
}
// 写第二行数据
write_com(0x80 0x40);
for(i=0;i<8;i )
{
write_data(table_xiaoyi_welcome[i]);
delay_ms(5);
}
while(1)
{
if (interrupt_flag == 1)
{
// 第二行显示清空
write_com(0x80 0x40);
for(i=0;i<8;i )
{
write_data(0x20);
delay_ms(5);
}
// 写第二行数据
程序中interrupt_init()函数初始化外部中断0,中断处理函数int0_func()中先关闭总中断,防止被高优先级中断打断,然后赋值标志位,最后开启总中断
三、运行
将上述程序生成的hex文件烧录到板子中,使用杜邦线将P32引脚接地,可以看到LCD1602第二行显示INT0!,说明进入中断成功。
注意:
不建议直接在中断处理函数中处理数据,本文是中断处理函数中设置interrupt_flag标志位,然后主程序中查询标志位进行数据处理。