CH2-EXIT
EXIT理论
EXTI
EXTI(Extern Interrupt)外部中断EXTI可以监测指定GPIO口的电平信号,当其指定的GPIO口产生电平变化时,EXTI将立即向NVIC发出中断申请,经过NVIC裁决后即可中断CPU主程序,使CPU执行EXTI对应的中断程序支持的触发方式:上升沿/下降沿/双边沿/软件触发支持的GPIO口:所有GPIO口,但相同的Pin不能同时触发中断通道数:16个GPIO_Pin,外加PVD输出、RTC闹钟、USB唤醒、以太网唤醒触发响应方式:中断响应/事件响应
中断:要进入NVIC,有相应的中断服务函数,需要CPU处理
事件:不进入NVIC,仅用于内部硬件自动控制的,如:TIM、DMA、ADC
EXTI基本结构
AFIO简介
中断触发流程
中断触发流程
CubeMX配置
时钟配置

时钟配置
下载配置

下载线配置
中断配置
1.IO口先选择EXTI

先选择一个IO口进行配置EXTI
2.GPIO配置触发方式
GPIO触发方式配置
3.NVIC寄存器使能
NVIC使能
代码编写
中断配置流程
设置步骤
流程1-5
gpio.c文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(GPIOA, RELAY1_Pin|RELAY2_Pin, GPIO_PIN_RESET); GPIO_InitStruct.Pin = USER_KEY_Pin; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(USER_KEY_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = RELAY1_Pin|RELAY2_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 1, 0); HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
|
中断逻辑
1.当外部中断触发的时候程序会判断优先级,当在前的优先级处理过后,程序会执行如下函数void EXTI4_15_IRQHandler(void)

2.中断函数之后会运行HAL_GPIO_EXTI_IRQHandler(USER_KEY_Pin)
中断公用函数中的变量为我们设置的IO口变量名称
3.编写中断回调函数
主函数编写
function.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| #include "function.h" #include "gpio.h"
void RELAY(unsigned int flag_relay_p,unsigned int flag_relay_state) { if(1 == flag_relay_p) { if(1==flag_relay_state) HAL_GPIO_WritePin(GPIOA, RELAY1_Pin, GPIO_PIN_SET); if(0==flag_relay_state) HAL_GPIO_WritePin(GPIOA, RELAY1_Pin, GPIO_PIN_RESET); } if(2 == flag_relay_p) { if(1==flag_relay_state) HAL_GPIO_WritePin(GPIOA, RELAY2_Pin, GPIO_PIN_SET); if(0==flag_relay_state) HAL_GPIO_WritePin(GPIOA, RELAY2_Pin, GPIO_PIN_RESET); } }
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { static int flag_user_key_num=0; if(GPIO_Pin == USER_KEY_Pin) { flag_user_key_num++; } if(1==flag_user_key_num) RELAY(1,1); if(2==flag_user_key_num) RELAY(1,0); if(3==flag_user_key_num) RELAY(2,1); if(4==flag_user_key_num) RELAY(2,0); if(flag_user_key_num>4) flag_user_key_num=1; }
|
function.h
1 2 3 4 5 6
| #ifndef __FUNCTION_H__ #define __FUNCTION_H__
void RELAY(unsigned int flag_relay_p,unsigned int flag_relay_state);
#endif
|