Files
CHJ/user/MCU/lhl_exti.c
2026-03-20 21:19:04 +08:00

111 lines
4.0 KiB
C

#include "../main/SystemInclude.h"
/**------------------------------------------------------------------------
* @brief 外部中断初始化
* @note
* @param
* @example:
GPIO_EXTI_Init(GPIO1,GPIO_PIN_7,EXTI_LINE_7,EXTI4_7_IRQn);
GPIO_EXTI_Init(GPIO0,GPIO_PIN_3,EXTI_LINE_3,EXTI2_3_IRQn);
GPIO_EXTI_Init(GPIO1,GPIO_PIN_0,EXTI_LINE_0,EXTI0_1_IRQn);
**/
void GPIO_EXTI_Init(GPIO_TypeDef* EXTI_GPIOx ,uint16_t EXTI_PINx ,EXTI_LINE_t EXTI_LINEx,IRQn_Type EXTI_IRQx)
{
GPIO_InitTypeDef GPIO_InitStructure;// GPIO配置结构体
EXTI_InitTypeDef EXTI_InitStructure;// EXTI配置结构体
/* 1. 配置引脚参数 */
GPIO_InitStructure.Pin = EXTI_PINx; // Pinx
GPIO_InitStructure.Mode = GPIO_MODE_INPUT; // 输入模式
// GPIO_InitStructure.Pull = GPIO_NOPULL; // 无上拉/下拉电阻 GPIO_NOPULL
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.SchmittTrigger = ENABLE; // 开启施密特触发器输入
GPIO_InitStructure.Alternate = GPIOx_AF_GPIO;
LHL_GPIO_Init(EXTI_GPIOx, &GPIO_InitStructure); // 初始化Pin为输入
LHL_GPIO_SetEXTILine(EXTI_GPIOx, EXTI_PINx); // 设置Pin为EXTI0
/* 2. 配置EXTI参数 */
EXTI_InitStructure.Line = EXTI_LINEx;
EXTI_InitStructure.Mode = EXTI_MODE_INTERRUPT; // EXTI中断模式
EXTI_InitStructure.Trigger = EXTI_TRIGGER_RISING_FALLING; // 上升下降沿触发
EXTI_InitStructure.LineCmd = ENABLE; // 使能EXTI
LHL_EXTI_Init(&EXTI_InitStructure); // 设置EXTI
NVIC_EnableIRQ(EXTI_IRQx); // 开启NVIC中断
NVIC_SetPriority(EXTI_IRQx, 0); // 设置EXIT3优先级
}
/*-=====================================================================================================
//中断
-=====================================================================================================*/
/**------------------------------------------------------------------------
* @brief 中断回调函数注册
* @note
* @param
* @example: void Exti_irq_callback(void){} Exti_register_irq_callback(EXTI_LINE_7,Exti_irq_callback);
**/
static exti_irq_callback_t exti_callbacks[EXTI_MAX_LINES] = {NULL};
// 注册回调
void Exti_register_irq_callback(EXTI_LINE_t exti_linex, exti_irq_callback_t exti_irq_callback)
{
if (exti_linex == 0) return;//防止传0 或者不是EXTI_LINE_t的参数
uint8_t index = (uint8_t)__builtin_ctz((unsigned int)exti_linex); //获取exti_linex 索引编号
if (index >= EXTI_MAX_LINES) return;
exti_callbacks[index] = exti_irq_callback;
switch (index) { //获取 EXTI 线对应的 IRQ 号
case 0:
case 1:
NVIC_EnableIRQ(EXTI0_1_IRQn);
break;
case 2:
case 3:
NVIC_EnableIRQ(EXTI2_3_IRQn);
break;
case 4:
case 5:
case 6:
case 7:
NVIC_EnableIRQ(EXTI4_7_IRQn);
break;
default:
// 不支持的线
break;
}
}
void EXTI0_1_IRQHandler(void)
{
// 检查 EXTI0 和 EXTI1
if (LHL_EXTI_GetPending(EXTI_LINE_0) == SET) {
LHL_EXTI_ClearPending(EXTI_LINE_0);
if (exti_callbacks[0]) exti_callbacks[0]();
}
if (LHL_EXTI_GetPending(EXTI_LINE_1) == SET) {
LHL_EXTI_ClearPending(EXTI_LINE_1);
if (exti_callbacks[1]) exti_callbacks[1]();
}
}
void EXTI2_3_IRQHandler(void)
{
if (LHL_EXTI_GetPending(EXTI_LINE_2) == SET) {
LHL_EXTI_ClearPending(EXTI_LINE_2);
if (exti_callbacks[2]) exti_callbacks[2]();
}
if (LHL_EXTI_GetPending(EXTI_LINE_3) == SET) {
LHL_EXTI_ClearPending(EXTI_LINE_3);
if (exti_callbacks[3]) exti_callbacks[3]();
}
}
void EXTI4_7_IRQHandler(void)
{
for (int i = 4; i <= 7; i++) {
EXTI_LINE_t line = (EXTI_LINE_t)(1U << i);
if (LHL_EXTI_GetPending(line) == SET) {
LHL_EXTI_ClearPending(line);
if (exti_callbacks[i]) exti_callbacks[i]();
}
}
}