【STC8A8K64S4A12开发板】—再聊单片机外部中断

版权声明:本文为博主原创文章,转载请附上原文出处链接。

文章目录

  • 前言
  • 一、硬件电路设计
    • 1.开发板IO口外部中断硬件电路
    • 2.STC8A8K64S4A12系列MCU外部中断
    • 3.单片机中断方式和查询方式
    • 4.外部中断配置步骤
  • 二、软件设计
    • 1.寄存器解析
      • 1.1.中断允许寄存器IE
      • 1.2.外部中断和时钟输出控制寄存器INTCLKO2
      • 1.3.定时器/计数器中断控制寄存器TCON
    • 2.外部中断0实验(下降沿中断方式)
      • 2.1.工程需要用到的c文件
      • 2.2.头文件引用和路径设置
      • 2.3.编写代码
      • 2.4.硬件连接
    • 3.外部中断0实验(上升沿或下降沿中断方式)
      • 3.1.程需要用到的c文件
      • 3.2.编写代码
      • 3.3.硬件连接
    • 4.外部中断0实验(上升沿或下降沿中断方式)
      • 4.1.工程需要用到的c文件
      • 4.2.编写代码
      • 4.3.硬件连接
    • 5.外部中断1实验(上升沿或下降沿中断方式)
      • 5.1.工程需要用到的c文件
      • 5.2.编写代码
      • 5.3.硬件连接
    • 6.外部中断2实验(下降沿中断方式)
      • 6.1.工程需要用到的c文件
      • 6.2.编写代码
      • 6.3.硬件连接
    • 7.外部中断3实验(下降沿中断方式)
      • 7.1.工程需要用到的c文件
      • 7.2.编写代码
      • 7.3.硬件连接
    • 8.外部中断4实验(下降沿中断方式)
      • 8.1.工程需要用到的c文件
      • 8.2.编写代码
      • 8.3.硬件连接
    • 9.多个外部中断实验
      • 9.1.工程需要用到的c文件
      • 9.2.编写代码
      • 9.3.硬件连接
  • 总结


前言

接着之前单机中断原理,再跟大家说说外部中断!


一、硬件电路设计

1.开发板IO口外部中断硬件电路

STC8A8K64S4A12开发板上设计了4个用户轻触按键,其中KEY1和KEY2按键可以为外部中断引脚提供触发信号,电路如下。
【STC8A8K64S4A12开发板】—再聊单片机外部中断_第1张图片
■ 开发板5个可用外部中断引脚如下表:

表1:开发板外部中断引脚分配
INT 对应IO口 功能描述 说明 备注
INT0 P3.2 外部中断0 非独立GPIO LCD显示屏模块用。
INT1 P3.3 外部中断1 非独立GPIO nRF24L01模块接口J11使用。
INT2 P3.6 外部中断2 非独立GPIO W5500模块接口J7使用。
INT3 P3.7 外部中断3 非独立GPIO W5500模块接口J7使用。
INT4 P3.0 外部中断4 非独立GPIO 板载USB转TTL电路用。

☆注:独立GPIO表示开发板没有其他的电路使用这个GPIO,非独立GPIO说明开发板有其他电路用到了该GPIO。针对非独立GPIO使用时需特别注意。

2.STC8A8K64S4A12系列MCU外部中断

STC8A8K64S4A12系列MCU不是每一个GPIO口都可以作为外部中断输入使用,只有特定的GPIO口才可以作为特定的外部中断输入使用。STC8A8K64S4A12系列MCU具有5个外部中断引脚,列表如下。

表2:STC8A8K64S4A12系列外部中断引脚分配
序号 INT 对应IO口 功能描述 备注
1 INT0 P3.2 外部中断0 中断优先级可设置0/1/2/3。
2 INT1 P3.3 外部中断1 中断优先级可设置0/1/2/3。
3 INT2 P3.6 外部中断2 只能为最低中断优先级0。
4 INT3 P3.7 外部中断3 只能为最低中断优先级0。
5 INT4 P3.0 外部中断4 中断优先级可设置0/1/2/3。

单片机外部中断引脚电平变化了,就有可能触发中断,进而执行中断服务程序。电平变化有可能是高电平到低电平(即产生下降沿),也可能是低电平到高电平(即产生上升沿)。STC8A8K64S4A12系列外部中断引脚支持的触发方式是不一样的。如下表。

表3:STC8A8K64S4A12系列外部中断引脚触发方式
序号 触发方式 INT 备注
1 下降沿触发 INT0、INT1、INT2、INT3、INT4
2 上升沿触发 指只可上升沿触发的意思。
3 上升沿或下降沿触发 INT0、INT1

实现GPIO口电平变化的方式有很多,使用外部按键改变GPIO口电平是一种简单直观的方式。但在实际使用中单片机的外部中断功能是应用于一些模块或芯片的中断引脚上,比如W5500以太网模块、nRF24L01无线模块等。
下面介绍下带有中断引脚(IRQ)的模块或传感器与单片机连接示意图。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第2张图片

图2:带中断引脚的模块或传感器与单片机连接示意图

■ 需要弄清楚的问题。

  1. 模块或传感器IRQ引脚的有效电平(低电平有效还是高电平有效)。
  2. 模块或传感器IRQ引脚一旦跳变到有效电平后需要单片机执行的操作。

■ 延伸出的问题。

  1. 如果模块或传感器IRQ引脚是低有效电平,那么产生的就是下降沿;如果模块或传感器IRQ引脚是高有效电平,那么产生的就是上升沿。这就需要单片机外部中断引脚有匹配的触发方式才可,如果没有怎么办呢?
  2. 与模块或传感器IRQ引脚相连的单片机引脚可以不是外部中断引脚,而是普通的GPIO口吗?

■ 回答延伸出的问题。

  1. 从STC8A8K64S4A12系列外部中断引脚触发方式表格中可以获悉,单片机INT0和INT1可选择为上升沿或下降沿触发方式,这基本可以满足大部分的应用需求的。如果单片机只有INT2、INT3或INT4(下降沿触发方式)的外部中断引脚可用,比较简便的方式是对模块或传感器的IRQ信号进行取反处理,硬件上加个反相器是一种做法,但务必考虑会有一个信号延时的问题。
  2. 模块或传感器IRQ引脚一般是可以和单片机GPIO口引脚相连的,这在程序设计时采用的就是查询方式。也就是单片机程序设计时不断循环查询与模块或传感器IRQ引脚相连的GPIO口状态,若检测到GPIO口跳变到有效电平后才会执行需要的操作。当单片机使用中断引脚与模块或传感器IRQ引脚相连时,设计程序便可采用中断方式,后面会详细介绍查询方式和中断方式的区别。

3.单片机中断方式和查询方式

单片机中断方式,是事件触发的,占用的CPU资源相对很少。换言之打开中断之后,CPU可以做其他事情,只有当符合条件的事件产生时才会进入中断,去执行中断服务程序。举例,针对STC8A8K64S4A12系列单片机,前面介绍的下降沿中断或上升沿中断都是触发中断的条件,在这个条件不满足时单片机是不用理会外部中断引脚的,而一旦条件满足,如果程序中没有其他同时发生的更高优先级的中断的话,CPU会立即执行该外部中断对应的中断服务函数。
单片机查询方式,就是在主函数里面不停循环,查询端口状态,这会占用大量CPU资源。这时模块或传感器IRQ引脚是可以和单片机普通IO口引脚相连的。这种方式的弊端:

  1. 占用过多CPU资源,影响响应速度。
  2. 在处理事件多,处理流程复杂,函数嵌套执行的情况下,由于CPU处理不过来可能会丢失事件。(往往模块或传感器IRQ引脚跳变到有效电平的时间也是有限的,如果在有限的时间内没有捕获到有效信号就会丢失事件)

☆注:单片机查询方式的缺点就是单片机中断方式的优点。当然,单片机查询方式的优点是可以使用普通IO口甚至不使用IO口。

4.外部中断配置步骤

针对STC8A8K64S4A12系列单片机5个外部中断引脚,软件的配置过程如下:

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第3张图片

图3:外部中断软件配置步骤

☆注:实验例程即是按照上述配置步骤操作寄存器相关位实现,后有详述。

二、软件设计

1.寄存器解析

首先普及一个常用知识点:在操作单片机寄存器时常说有的寄存器支持位寻址,有的寄存器不支持位寻址?这里的位寻址究竟是什么含义?
位寻址定义:对位地址中的内容进行位操作的寻址方式称为位寻址。由于单片机中只有内部RAM和特殊功能寄存器的部分单元有位地址,因此位寻址只能对有位地址的这两个空间进行寻址操作。
单片机中不是每个寄存器都支持位寻址的,一般如果SFR(特殊功能寄存器)的地址值能被8整除,则该SFR可以进行位寻址。举例P0端口数据寄存器是支持位寻址的。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第4张图片

图4:P0端口数据寄存器

☆注:单片机中寄存器地址值如不能被8整除,则该寄存器是不支持位寻址的。针对STC8A8K64S4A12系列有些SFR是位于扩展RAM中,这些SFR不可以按照这个总结的规则去判定是否支持位寻址。访问位于扩展RAM中的SFR需要先操作P_SW2的BIT7才可,这个在用到时讲解。

1.1.中断允许寄存器IE

中断允许寄存器IE支持位寻址,该寄存器的B7位是单片机所有中断的总闸,即其他中断位使能后,最后还必须将这个总中断打开才能开启中断,与外部中断有关的还有B0和B2位,含义如下图。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第5张图片

图5:中断允许寄存器

1.2.外部中断和时钟输出控制寄存器INTCLKO2

外部中断允许和时钟输出寄存器INTCLKO2不支持位寻址,该寄存器的B4、B5和B6位是外部中断2、外部中断3和外部中断4的中断允许位。因为AUXR2寄存器不支持位寻址,所以操作该寄存器位时,不可以直接“EX2=0;”进行操作INT2中断允许位,参考下图。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第6张图片

图6:外部中断和时钟输出控制寄存器

1.3.定时器/计数器中断控制寄存器TCON

定时器/计数器中断控制寄存器TCON支持位寻址,该寄存器的B0位和B2位是选择INT0和INT1中断源类型的(可理解成中断触发方式),寄存器B1位和B3位是INT0和INT1中断请求标志,含义如下图。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第7张图片

图7:定时器/计数器中断控制寄存器

☆注:单片机中很多寄存器都像TCON寄存器一样,寄存器关联的单片机外设不止一个,这就需要我们在操作寄存器时一定要按位操作,用不到的位千万不要操作,否则在程序比较复杂、用到的外设比较多时,往往会遇到不可知问题。

2.外部中断0实验(下降沿中断方式)

☆注:本节的实验源码是在“实验2-2-2: GPIO输入按键检测(多个c文件)”的基础上修改。本节对应的实验源码是:“实验2-4-1:外部中断0(下降沿中断方式)”。

2.1.工程需要用到的c文件

本例需要用到的c文件如下表所示,工程需要添加下表中的c文件。

表4:实验需要用到的c文件
序号 文件名 后缀 功能描述
1 led .c 包含与用户led控制有关的用户自定义函数。
2 exint .c 外部中断有关的用户自定义函数。
3 delay .c 包含用户自定义延时函数。

2.2.头文件引用和路径设置

■ 需要引用的头文件

#include "delay.h"  
#include "led.h"  
#include "exint.h"  

■ 需要包含的头文件路径
本例需要包含的头文件路径如下表:

表5:头文件包含路径
序号 路径 描述
1 …\ Source led.h、exint.h和delay.h头文件在该路径,所以要包含。
2 …\User STC8.h头文件在该路径,所以要包含。

MDK中点击魔术棒,打开工程配置窗口,按照下图所示添加头文件包含路径。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第8张图片

图8:添加头文件包含路径

2.3.编写代码

首先,在exint.c文件中编写外部中断0初始化函数INT0_Init,代码如下。

程序清单:外部中断0初始化函数

/*********************************************************** 
功能描述:外部中断0初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT0_Init(void)  
{  
    IE0  = 0;        //将INT0中断请求标志位清"0"  
    EX0 = 1;         //使能INT0中断允许位  
    IT0 = 1;         //选择INT0为下降沿触发方式  
} 

然后,编写外部中断服务函数,一旦进入中断会执行翻转蓝色指示灯D3的任务,代码如下。

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT0_Isr (void) interrupt 0        
{  
    led_toggle(LED_3);        //翻转蓝色指示灯D3  
}  

最后,在主函数中调用INT0初始化函数,开启总中断,在主循环中没有任务,蓝色指示灯D3变化来自于中断。

代码清单:主函数

int main(void)  
{        
    INT0_Init();     //外部中断0的初始化配置    
    EA = 1;            //允许总中断  
  
  while (1)  
    {  
        ;              //无任务,说明LED亮灭来自于中断  
    }  
} 

2.4.硬件连接

本实验需要使用P3.2(外部中断0引脚)连接到J26端子KEY1,因此需要按下图所示连接杜邦线。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第9张图片

图9:开发板连接图

3.外部中断0实验(上升沿或下降沿中断方式)

☆注:本节的实验源码是在“实验2-4-1:外部中断0(下降沿中断方式)”的基础上修改。本节对应的实验源码是:“实验2-4-2:外部中断0(上升沿或下降沿中断方式)”。

3.1.程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-4-1:外部中断0(下降沿中断方式)”部分。

3.2.编写代码

首先,在exint.c文件中编写外部中断0初始化函数INT0_Init,代码如下。

程序清单:外部中断0初始化函数

/*********************************************************** 
功能描述:外部中断0初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT0_Init(void)  
{  
    IE0  = 0;        //将INT0中断请求标志位清"0"  
    EX0 = 1;         //使能INT0中断允许位  
    IT0 = 0;         //选择INT0为上升沿或下降沿触发方式  
} 

然后,编写外部中断服务函数,一旦进入中断会执行翻转蓝色指示灯D3的任务,代码如下。

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT0_Isr (void) interrupt 0        
{  
    led_toggle(LED_3);        //翻转蓝色指示灯D3 
} 

最后,在主函数中调用INT0初始化函数,开启总中断,在主循环中没有任务,蓝色指示灯D3变化来自于中断。

代码清单:主函数

int main(void)  
{  
    INT0_Init();     //外部中断0的初始化配置    
    EA = 1;            //允许总中断  
  
  while (1)  
    {  
        ;              //无任务,说明LED亮灭来自于中断  
    }  
} 

3.3.硬件连接

本实验需要使用P3.2(外部中断0引脚)连接到J26端子KEY1,因此需要按下图所示连接杜邦线。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第10张图片

图10:开发板连接图

4.外部中断0实验(上升沿或下降沿中断方式)

☆注:本节的实验源码是在“实验2-4-1:外部中断0(下降沿中断方式)”的基础上修改。本节对应的实验源码是:“实验2-4-3:外部中断1(下降沿中断方式)”。

4.1.工程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-4-1:外部中断0(下降沿中断方式)”部分。

4.2.编写代码

首先,在exint.c文件中编写外部中断1初始化函数INT1_Init,代码如下。

程序清单:外部中断1初始化函数

/*********************************************************** 
功能描述:外部中断1初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT1_Init(void)  
{  
    IE1  = 0;        //将INT1中断请求标志位清"0"  
    EX1 = 1;         //使能INT1中断允许位  
    IT1 = 1;         //选择INT1为下降沿触发方式   
} 

然后,编写外部中断服务函数,一旦进入中断会执行翻转蓝色指示灯D3的任务,代码如下。

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT1_Isr (void) interrupt 2        
{  
    led_toggle(LED_3);        //翻转蓝色指示灯D3  
} 

最后,在主函数中调用INT1初始化函数,开启总中断,在主循环中没有任务,蓝色指示灯D3变化来自于中断。

代码清单:主函数

int main(void)  
{  
    INT1_Init();     //外部中断1的初始化配置    
    EA = 1;            //允许总中断  
  
  while (1)  
    {  
        ;              //无任务,说明LED亮灭来自于中断  
    }  
} 

4.3.硬件连接

本实验需要使用P3.3(外部中断1引脚)连接到J26端子KEY1,因此需要按下图所示连接杜邦线。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第11张图片

图11:开发板连接图

5.外部中断1实验(上升沿或下降沿中断方式)

☆注:本节的实验源码是在“实验2-4-3:外部中断1(下降沿中断方式)”的基础上修改。本节对应的实验源码是:“实验2-4-4:外部中断1(上升沿或下降沿中断方式)”。

5.1.工程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-4-1:外部中断0(下降沿中断方式)”部分。

5.2.编写代码

首先,在exint.c文件中编写外部中断1初始化函数INT1_Init,代码如下。

程序清单:外部中断1初始化函数

/*********************************************************** 
功能描述:外部中断1初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT1_Init(void)  
{  
    IE1  = 0;        //将INT1中断请求标志位清"0"  
    EX1 = 1;         //使能INT1中断允许位  
    IT1 = 0;        //选择INT1为上升沿或下降沿触发方式   
} 

然后,编写外部中断服务函数,一旦进入中断会执行翻转蓝色指示灯D3的任务,代码如下。

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT1_Isr (void) interrupt 2        
{  
    led_toggle(LED_3);        //翻转蓝色指示灯D3 
} 

最后,在主函数中调用INT1初始化函数,开启总中断,在主循环中没有任务,蓝色指示灯D3变化来自于中断。

代码清单:主函数

int main(void)  
{  
    INT1_Init();     //外部中断1的初始化配置    
    EA = 1;            //允许总中断  
  
  while (1)  
    {  
        ;              //无任务,说明LED亮灭来自于中断  
    }  
} 

5.3.硬件连接

本实验需要使用P3.3(外部中断1引脚)连接到J26端子KEY1,因此需要按下图所示连接杜邦线。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第12张图片

图12:开发板连接图

6.外部中断2实验(下降沿中断方式)

☆注:本节的实验源码是在“实验2-4-1:外部中断0(下降沿中断方式)”的基础上修改。本节对应的实验源码是:“实验2-4-5:外部中断2(下降沿中断方式)”。

6.1.工程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-4-1:外部中断0(下降沿中断方式)”部分。

6.2.编写代码

首先,在exint.c文件中编写外部中断2初始化函数INT2_Init,代码如下。

程序清单:外部中断2初始化函数

int main(void)  
/*********************************************************** 
功能描述:外部中断2初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT2_Init(void)  
{  
    INTCLKO |= 0x10;   //使能INT2中断允许位  
}  

然后,编写外部中断服务函数,一旦进入中断会执行翻转蓝色指示灯D3的任务,代码如下。

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT2_Isr (void) interrupt 10        
{  
    led_toggle(LED_3);        //翻转蓝色指示灯D3  
} 

最后,在主函数中调用INT2初始化函数,开启总中断,在主循环中没有任务,蓝色指示灯D3变化来自于中断。

代码清单:主函数

int main(void)  
{  
    INT2_Init();     //外部中断2的初始化配置    
    EA = 1;          //允许总中断  
  
  while (1)  
    {  
        ;              //无任务,说明LED亮灭来自于中断  
    }  
}  

6.3.硬件连接

本实验需要使用P3.6(外部中断2引脚)连接到按键KEY2,因此需要按下图所示连接短路帽。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第13张图片

图13:开发板连接图

7.外部中断3实验(下降沿中断方式)

==☆注:本节的实验源码是在“实验2-4-1:外部中断0(下降沿中断方式)”的基础上修改。本节对应的实验源码是:“实验2-4-6:外部中断3(下降沿中断方式)”。 ==

7.1.工程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-4-1:外部中断0(下降沿中断方式)”部分。

7.2.编写代码

首先,在exint.c文件中编写外部中断3初始化函数INT3_Init,代码如下。

程序清单:外部中断3初始化函数

/*********************************************************** 
功能描述:外部中断3初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT3_Init(void)  
{  
   INTCLKO |= 0x20;   //使能INT3中断允许位  
}  

然后,编写外部中断服务函数,一旦进入中断会执行翻转蓝色指示灯D3的任务,代码如下。

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT3_Isr (void) interrupt 11         
{  
     led_toggle(LED_3);       //翻转用户指示灯D3  
} 

最后,在主函数中调用INT3初始化函数,开启总中断,在主循环中没有任务,蓝色指示灯D3变化来自于中断。

代码清单:主函数

int main(void)  
{  
    INT3_Init();       //外部中断3的初始化配置    
    EA = 1;            //允许总中断  
  
  while (1)  
    {  
        ;              //无任务,说明LED亮灭来自于中断  
    }  
}  

7.3.硬件连接

本实验需要使用P3.7(外部中断3引脚)连接到按键KEY1,因此需要按下图所示连接短路帽。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第14张图片

图14:开发板连接图

8.外部中断4实验(下降沿中断方式)

==☆注:本节的实验源码是在“实验2-4-1:外部中断0(下降沿中断方式)”的基础上修改。本节对应的实验源码是:“实验2-4-7:外部中断4(下降沿中断方式)”。 ==

8.1.工程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-4-1:外部中断0(下降沿中断方式)”部分。

8.2.编写代码

首先,在exint.c文件中编写外部中断4初始化函数INT4_Init,代码如下。

程序清单:外部中断4初始化函数

/*********************************************************** 
功能描述:外部中断4初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT4_Init(void)  
{  
   INTCLKO |= 0x40;   //使能INT4中断允许位  
} 

然后,编写外部中断服务函数,一旦进入中断会执行翻转蓝色指示灯D3的任务,代码如下。

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT4_Isr (void) interrupt 16     
{  
     led_toggle(LED_3);       //翻转用户指示灯D3  
}

最后,在主函数中调用INT4初始化函数,开启总中断,在主循环中没有任务,蓝色指示灯D3变化来自于中断。

代码清单:主函数

int main(void)  
{  
    INT4_Init();     //外部中断4的初始化配置    
    EA = 1;            //允许总中断  
  
  while (1)  
    {  
        ;              //无任务,说明LED亮灭来自于中断  
    }  
}  

8.3.硬件连接

本实验需要使用P3.0(外部中断4引脚)连接到J26端子KEY1,因此需要按下图所示连接杜邦线。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第15张图片

图15:开发板连接图

9.多个外部中断实验

==☆注:本节的实验源码是在“实验2-4-1:外部中断0(下降沿中断方式)”的基础上修改。本节对应的实验源码是:“实验2-4-8:多个外部中断”。 ==

9.1.工程需要用到的c文件

本实验需要用到的头文件以及添加头文件包含路径的方法请参考“实验2-4-1:外部中断0(下降沿中断方式)”部分。

9.2.编写代码

首先,在exint.c文件中编写外部中断0初始化函数INT0_Init和外部中断1初始化函数INT1_Init,代码如下。

程序清单:外部中断0初始化函数

/*********************************************************** 
功能描述:外部中断0初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT0_Init(void)  
{  
    IE0 = 0;         //将INT0中断请求标志位清"0"  
    EX0 = 1;         //使能INT0中断允许位  
    IT0 = 1;           //选择INT0为下降沿触发方式  
    /* 将INT0优先级设置为最低优先级 */  
    IP &= 0xFE;      //将PX0位置0  
    IPH &= 0xFE;     //将PX0H位置0  
}  

程序清单:外部中断1初始化函数

/*********************************************************** 
功能描述:外部中断1初始化 
入口参数:无 
返回值:无 
************************************************************/  
void INT1_Init(void)  
{  
    IE1  = 0;        //将INT1中断请求标志位清"0"  
    EX1 = 1;         //使能INT1中断允许位  
    IT1 = 1;           //选择INT1为下降沿触发方式   
    /* 将INT1优先级设置为最高优先级 */  
    IP |= 0x04;      //将PX1位置1  
    IPH |= 0x04;     //将PX1H位置1  
} 

然后,编写外部中断服务函数,一旦进入外部中断0会执行翻转4次蓝色指示灯D3的任务,进入外部中断1会执行翻转4次蓝色指示灯D4的任务,代码如下。

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT0_Isr (void) interrupt 0          
{  
    led_on(LED_3);         //点亮用户指示灯D3  
    delay_ms(200);    
    led_off(LED_3);        //熄灭用户指示灯D3  
    delay_ms(100);    
    led_on(LED_3);         //点亮用户指示灯D3  
    delay_ms(200);    
    led_off(LED_3);        //熄灭用户指示灯D3  
    delay_ms(100);    
    led_on(LED_3);         //点亮用户指示灯D3  
    delay_ms(200);    
    led_off(LED_3);        //熄灭用户指示灯D3  
    delay_ms(100);  
    led_on(LED_3);         //点亮用户指示灯D3  
    delay_ms(200);    
    led_off(LED_3);        //熄灭用户指示灯D3  
    delay_ms(100);  
} 

程序清单:中断服务函数

/*********************************************************** 
功能描述:外部中断服务程序 
入口参数:无 
返回值:无 
************************************************************/  
void INT1_Isr (void) interrupt 2          
{  
    led_on(LED_4);         //点亮用户指示灯D4  
    delay_ms(200);    
    led_off(LED_4);        //熄灭用户指示灯D4  
    delay_ms(100);    
    led_on(LED_4);         //点亮用户指示灯D4  
    delay_ms(200);    
    led_off(LED_4);        //熄灭用户指示灯D4  
    delay_ms(100);    
    led_on(LED_4);         //点亮用户指示灯D4  
    delay_ms(200);    
    led_off(LED_4);        //熄灭用户指示灯D4  
    delay_ms(100);  
    led_on(LED_4);         //点亮用户指示灯D4  
    delay_ms(200);    
    led_off(LED_4);        //熄灭用户指示灯D4  
    delay_ms(100);  
} 

最后,在主函数中调用INT0和INT1初始化函数,开启总中断。在主循环中没有任务,蓝色指示灯D3和蓝色指示灯D4变化来自于中断。

代码清单:主函数

int main(void)  
{  
    INT0_Init();     //外部中断0的初始化配置    
    INT1_Init();     //外部中断1的初始化配置    
    EA = 1;            //允许总中断  
  
  while (1)  
    {  
        ;              //无任务,说明LED亮灭来自于中断  
    }  
}  

9.3.硬件连接

本实验需要使用P3.2(外部中断0引脚)连接到J26端子KEY1,P3.3(外部中断1引脚)连接到J26端子KEY2,因此需要按下图所示连接杜邦线。

【STC8A8K64S4A12开发板】—再聊单片机外部中断_第16张图片

图16:开发板连接图

总结

以上就是今天要讲的内容,大家看完不妨思考一下:根据本例实验现象分析INT0和INT1谁的中断优先级高?为什么?

你可能感兴趣的:(STC8)