在ST官方的文檔RM0091中
友情翻譯:
擴展中斷和事件控制器(EXTI)
- 擴展中斷和事件控制器(EXTI)管理外部和內部的異步事件/中斷,並生成事件請求到CPU/中斷控制器和一個喚醒請求到電源管理器。
- EXTI允許管理多達32個外部/內部事件行(23個外部事件行和9個內部事件行)。
- 每個外部中斷線的活動邊緣可以獨立選擇,而內部中斷的活動邊緣總是上升的。
- 一個中斷可能被保留:在外部的情況下,一個狀態寄存器被實例化,並指示中斷的源;
- 一個事件總是一個簡單的脈沖,它被用來觸發核心喚醒(例如,cortex-m0rxev pin)。
- 對於內部中斷,生成的IP保證掛起的狀態,因此不需要特定的標記。
- 每個輸入行可以獨立地屏蔽,用於中斷或事件生成,此外,內部的行也只在停止模式下進行采樣。
- 該控制器還允許通過軟件模擬(僅)外部事件,並通過寫入專用寄存器來對相應的硬件事件行進行復用。
1.1 硬件中斷選擇
1.2 硬件事件選擇
1.3 軟件中斷/事件的選擇

1.4 外部和內部中斷/事件行映射
GPIOs連接到16個外部中斷/事件行
剩余的行連接:
輸出16連接到PVD EXTI行
EXTI第17行連接到RTC報警事件
EXTI第18行內部連接到USB喚醒事件
EXTI線19連接到RTC篡改事件和時間戳
EXTI第20行連接到RTC喚醒事件(只有STM32F07x和STM32F09x設備)
EXTI第21行與比較器1的輸出
EXTI第22行與第二比較器輸出
EXTI第23行連接到內部I2C1喚醒事件
EXTI第24行保留(內部低)
EXTI第25行連接到內部USART1喚醒事件
EXTI第26行連接到內部USART2喚醒事件(只有STM32F07x和STM32F09x設備)
EXTI線27連接到內部CEC喚醒事件
EXTI 線28是連接到內部USART3喚醒事件(只有STM32F09x設備)
EXTI第29行保留(內部低)
EXTI線30保留(內部低)
EXTI第31行連接到VDDIO2供應比較器輸出(只有STM32F04x,STM32F07x和STM32F09x設備
2.GPIO口配置(基於LL庫)
void CanBusCANWakeupConfig(void) { LL_EXTI_InitTypeDef EXTI_InitStruct; /* GPIO Ports Clock Enable */ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA); /**/ LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTA, LL_SYSCFG_EXTI_LINE11); /**/ LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTA, LL_SYSCFG_EXTI_LINE12); /**/ LL_GPIO_SetPinPull(CAN_TX_GPIO_Port, CAN_TX_Pin, LL_GPIO_PULL_NO); /**/ LL_GPIO_SetPinPull(CAN_RX_GPIO_Port, CAN_RX_Pin, LL_GPIO_PULL_NO); /**/ LL_GPIO_SetPinMode(CAN_TX_GPIO_Port, CAN_TX_Pin, LL_GPIO_MODE_INPUT); /**/ LL_GPIO_SetPinMode(CAN_RX_GPIO_Port, CAN_RX_Pin, LL_GPIO_MODE_INPUT); /**/ EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_11; EXTI_InitStruct.LineCommand = ENABLE; EXTI_InitStruct.Mode = LL_EXTI_MODE_IT; EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING_FALLING; //觸發升降模式
LL_EXTI_Init(&EXTI_InitStruct); /**/ EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_12; EXTI_InitStruct.LineCommand = ENABLE; EXTI_InitStruct.Mode = LL_EXTI_MODE_IT; EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING_FALLING; LL_EXTI_Init(&EXTI_InitStruct); /* EXTI interrupt init*/ NVIC_SetPriority(EXTI4_15_IRQn, 3); NVIC_EnableIRQ(EXTI4_15_IRQn); DebugPrint("TX And Rx Weak Up Pin Set..."); }
這里使用CAN_TX_Pin和CAN_RX_Pin作為中斷觸發IO口:
#define CAN_RX_Pin LL_GPIO_PIN_11
#define CAN_RX_GPIO_Port GPIOA
#define CAN_TX_Pin LL_GPIO_PIN_12
#define CAN_TX_GPIO_Port GPIOA
中斷函數:
/* USER CODE BEGIN 1 */
/** * @brief This function handles EXTI line0_31 interrupt. */
void EXTI4_15_IRQHandler(void) { #if 1
if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_11) != RESET) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_11); /* USER CODE BEGIN LL_EXTI_LINE_11 */ HAL_GPIO_EXTI_Callback(CAN_RX_Pin); /* USER CODE END LL_EXTI_LINE_11 */ } if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_12) != RESET) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_12); /* USER CODE BEGIN LL_EXTI_LINE_12 */ HAL_GPIO_EXTI_Callback(CAN_TX_Pin); /* USER CODE END LL_EXTI_LINE_12 */ } #endif DebugPrint("System Weak Up ..."); // FLySystemReset();
} /* USER CODE END 1 */
注:
HAL_GPIO_EXTI_Callback(CAN_TX_Pin)這個函數可自己重寫,添加自己的效果;
DebugPrint()打印函數自己重新定義;
再將CanBusCANWakeupConfig()函數放進初始化或某個函數中,上升沿或下降沿觸發試試。
