一、基础知识
外部设备所产生的信号通过EXIT触发中断。
1、与中断相关的主要寄存器
EXTI共设有6个寄存器,分别为中断屏蔽寄存器(IMR),事件屏蔽寄存器(EMR),上升沿触发选择寄存器(RTSR),下降沿触发选择寄存器(FTSR),软中断事件寄存器(SWIER)和挂起寄存器(PR)。
EXTI:外部中断/事件控制器,管理时间线EXTI0~EXTI18,对于STM32的EXTI控制器支持19个外部中断/事件请求,每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。
EXTI0~15:对应GPIO的输入中断
EXTI16:连接到PVD输出
EXTI17:连接到RTC闹钟事件
EXTI18:连接到USB唤醒事件
EXTIX:事件线,连接GPIO所对应的管脚
EXTICR:寄存器组,共有四个,编译器的寄存器组都是从0开始编号。EXTICR[0]~EXTICR[3]对应的是EXTICR1~EXTICR4。
EXTIi[3:0]:指每条线的选择位
EXTI13:连接GPIOC对应的PC13管脚
2、嵌入式中断函数的一些特点
(1)不能返回值
中断服务函数的调用是硬件级别的,中断产生时,PC指针强行跳转到对应的中断服务函数入口进入中断具有随机性,并不是通过某段代码对其进行调用,因此返回值没有意义;如果有返回值,必须压栈,但何时和如何出栈是个问题。
(2)不能向ISR传递参数
同理是由于栈结构传参数会破坏栈
(3)ISR应该尽可能短小精悍
若某个中断频繁产生而它对应的ISR相对地耗时会影响中断的响应时间,会丢掉许多的中断请求。
3、单片机中while的作用
(1)while(1)
调试代码时防止后面干扰
有些代码运行错误时会抛出错误,然后进入到while(1)
机器需要复位时,停止喂狗进入while(1)迫使看门狗超时产生硬件复位。
(2)while(1){代码}
使用while(1)防止程序跑飞。因为大多数情况下执行完某程序后PC不会停止,仍会继续从ROM中读取指令并执行。
4、EXTI中断中中断与事件的区别
(1)事件:检测到某一动作(电平边沿)触发事件发生了;中断:有某个事件发生并产生中断,并跳转到对应的中断处理程序
(2)中断有可能被更优先级的中断屏蔽,而事件不会。
(3)事件的本质是一个触发信号(脉冲),用来唤醒特定的外设或者核心本身。
而中断时一个固定的电平信号。
(4)事件是中断的触发源,事件可以触发中断(开放了对应的中断屏蔽位),也可以不触发。
(5)中断一定要有中断服务函数,而事件没有
(6)事件可以在不需要CPU干涉的情况下执行操作,而中断必须要有CPU介入。
二、 功能需求
开发键控灯功能,即灯灭时,按一下按钮灯亮,灯亮时,按一下按钮灯熄灭。
三、设计思路
将PA5设置为数字推挽输出,PC13配置为数字输入和外部中断EXTI13线。当按下按钮时产生下降沿触发EXTI13中断,在中断处理函数中PA5值翻转。PA5初始化输出高电平。
四、软件流程图
五、程序设计
1、EXTI中断配置函数
采用ExIntInit函数配置EXTI信号源为PC13,下降沿触发。代码如下:
void ExIntInit(void)
{
RCC->AHB1ENR|=1<<2; //使能GPIOC时钟
RCC->APB2ENR|=1<<14; //使能SYSCFG时钟
SYSCFG->EXTICR[3]=(SYSCFG->EXTICR[3]& ~(0xF<<4))|(2<<4); //配置EXTI13信号源为PC13
EXTI->IMR|=1<<13; //取消对EXTI13信号线的屏蔽
EXTI->FTSR|=1<<13; //设定EXTI13中断触发信号为下降沿
NVIC->ISER[1]|=1<<8; //在NVIC中设置EXTI15_10中断使能
}
2、中断服务函数
中断服务函数名按照之前的约定设置为EXTI15_10_IRQHandler。中断处理代码如下:
void EXTI15_10_IRQHandler(void)
{
EXTI->PR|=1<<13; //清楚当前已经产生的EXTI13中断
LedSw(); //反转LED灯的亮灭状态
}