中断的现场保护和恢复现场

3. 结合上图作者来讲解一下:

当边沿检测电路检测到引脚上产生用户设置的触发沿时边沿检测电路会输出高电平给标号 1 部分,由于 1 是或门所以输入有一个是 1 输出就是 1, 此时 1 号或门的输出给请求中断挂起寄存器,并让该寄存器对应中断线挂起位为 1,如果此时中断屏蔽寄存器使能,即该中断线中断使能位为 1 时, 2 号与门输出 1,并传给 NVIC,如果此时 NVIC 使能了该中断线中断,则外部中断发生,外部中断服务函数得以执行。 同时,如果事件屏蔽寄存器中的对应位设置为 1,即开放来自该中断线的事件时, 3 号与门输出 1,进而使得脉冲发生器产生脉冲给对应外设,对应外设在收到脉冲后执行相应的联动触发动作,如触发 ADC 采集。

同理如果设置软件中断寄存器相应位为 1, 即通过软件产生外部中断时也会触发上面所述动作

中断屏蔽寄存器(EXTI_IMR)

当对应中断屏蔽位为 1 时,如果此时挂起寄存器对应位也为 1,则产生 NVIC 中断

事件屏蔽寄存器(EXTI_EMR)

当事件屏蔽寄存器对应位为 1 时, 一旦有触发信号产生,就会生成事件脉冲给其他外设

上升沿触发选择寄存器(EXTI_RTSR)

设置触发外部中断/事件的信号为上升沿触发。 上升下降沿寄存器可以同时配合使用来产生上升下降沿触发

下降沿触发选择寄存器(EXTI_FTSR)

设置触发外部中断/事件的信号为下降沿触发。上升下降沿寄存器可以同时配合使用来产生上升下降沿触发

挂起寄存器(EXTI_PR)

当外部信号/或软件产生了触发请求(即 1 号或门的输出为 1),则挂起寄存器对应位被设置为 1,通过写 1 清零

外部中断配置寄存器 1-4(AFIO_EXTICR1-4)

这里只列出 AFIO_EXTICR2,这样的 32 位寄存器一种有 4 组,每组用于设置 4 个外部中断,该寄存器用于指定外部中断的输入信号来自于那组 GPIO 的引脚,目的是将外部中断线和某个对应引脚连接在一起

按键中断实例

按键中断编程步骤分析

使能相应的时钟

配置GPIO管脚为中断功能

设置中断优先级

使能相应的中断

实现中断服务程序

中断配置程序

1 void MX_GPIO_Init(void)

2 {

3 GPIO_InitTypeDef GPIO_InitStruct = {0};

4

5 /* GPIO Ports Clock Enable */

6 __HAL_RCC_GPIOA_CLK_ENABLE();

7

8 /*Configure GPIO pin : PA8 */

9 GPIO_InitStruct.Pin = GPIO_PIN_8;

10 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;//上升沿触发

11 GPIO_InitStruct.Pull = GPIO_NOPULL;

12 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

13

14 /* EXTI interrupt init*/

15 HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);

16 HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

17 }

串口中断实例

串口中断编程步骤分析

使能相应的时钟

配置GPIO管脚为串口功能

设置中断优先级

使能相应的中断

实现中断服务程序

2. 程序

更改printf函数为串口传输使用

1 int fputc(int ch, FILE *fp)//更改printf函数,使之可为串口传输使用

2 {

3 while(!(USART1->SR & (1<<7)));//判断发送寄存器是否为空

4 USART1->DR = ch;//若不为空,则将数据传输到数据发送寄存器

5 return ch;

6 }

7

8 // 串口发送中断程序

9

10 HAL_UART_Transmit_IT(&huart1, "Transmit INIT\n", 14);//main.c文件中编写//调用此函数发送字符串,发送完成产生串口发送完成中断,并调用HAL_UART_TxCpltCallback函数

11 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)//usart.c文件中编写

12 {

13 if(huart->Instance == USART1)

14 {

15 printf("uart transmit end\n");//串口发送完成

16 }

17 }

18

19 // 串口接收中断程序

20

21 uint8_t RX[10] = {0};//定义接收数组HAL_UART_Receive_IT(&huart1, RX, 1);//接收一个字符数据,编写在main.c文件extern uint8_t RX[10];//声明外部变量,编写在usart.c文件

22 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//调用接收回调函数

23 {

24 if(huart->Instance == USART1)

25 {

26 printf("RX: %x\n",RX[0]);//打印接收到的字符

27 HAL_UART_Receive_IT(&huart1, RX, 1);

28 }

29 }