本文采用官方的库函数接口实现STM8L51X gpio中断
STM8L51X的中断向量入口函数都放在stm8l51x_it.c里面。
不同的中断对应的中断号如下(在stm8l51x_itc.h里面):
typedef enum {
FLASH_IRQn = (uint8_t)1, /*!< Flashinterrupt */
DMA1_CHANNEL0_1_IRQn = (uint8_t)2, /*!< DMAChannels 0/1 */
DMA1_CHANNEL2_3_IRQn = (uint8_t)3, /*!< DMAChannels 2/3 */
EXTIE_F_PVD_IRQn = (uint8_t)5, /*!< GPIOE/Fand PVD interrupt */
EXTI0_IRQn = (uint8_t)8, /*!< PIN0 interrupt */
EXTI1_IRQn = (uint8_t)9, /*!< PIN1interrupt */
EXTI2_IRQn = (uint8_t)10, /*!< PIN2interrupt */
EXTI3_IRQn = (uint8_t)11, /*!< PIN3interrupt */
EXTI4_IRQn = (uint8_t)12, /*!< PIN4interrupt */
EXTI5_IRQn = (uint8_t)13, /*!< PIN5interrupt */
EXTI6_IRQn = (uint8_t)14, /*!< PIN6interrupt */
EXTI7_IRQn = (uint8_t)15, /*!< PIN7interrupt */
ADC1_COMP_IRQn = (uint8_t)18, /*! TIM4_UPD_OVF_TRG_IRQn = (uint8_t)25, /*!< TIM4Update/Overflow/Trigger interrupt */ SPI1_IRQn = (uint8_t)26, /*!< SPI1interrupt */ #if defined (STM8L15X_MD) || defined(STM8L05X_MD_VL) || defined (STM8AL31_L_MD) RTC_IRQn = (uint8_t)4, /*!< RTCinterrupt */ EXTIB_IRQn = (uint8_t)6, /*!< GPIOBinterrupt */ EXTID_IRQn = (uint8_t)7, /*!< GPIODinterrupt */ LCD_IRQn = (uint8_t)16, /*!< LCD Driverinterrupt */ SWITCH_CSS_BREAK_DAC_IRQn = (uint8_t)17, /*!< Clock switch/CSS interrupt/TIM1 Break/DAC interrupt */ TIM2_UPD_OVF_TRG_BRK_IRQn = (uint8_t)19, /*!< TIM2Update/Overflow/Trigger/Break interrupt*/ TIM2_CC_IRQn = (uint8_t)20, /*!< TIM2 inputcaptute/output compare interrupt */ TIM3_UPD_OVF_TRG_BRK_IRQn = (uint8_t)21, /*!< TIM3Update/Overflow/Trigger/Break interrupt */ TIM3_CC_IRQn = (uint8_t)22, /*!< TIM3capture/compare interrupt */ TIM1_UPD_OVF_TRG_IRQn = (uint8_t)23, /*!< TIM1 TIM1 Update/Overflow/Triggerinterrupt */ TIM1_CC_IRQn = (uint8_t)24, /*!< TIM1 capture/compare interrupt */ USART1_TX_IRQn = (uint8_t)27, /*!< USART1 TXinterrupt */ USART1_RX_IRQn = (uint8_t)28, /*!< USART1 RXinterrupt */ I2C1_IRQn = (uint8_t)29 /*!< I2C1 interrupt */ #elif defined (STM8L15X_LD) || defined(STM8L05X_LD_VL) RTC_CSSLSE_IRQn = (uint8_t)4, /*!< RTC /CSSLSE interrupt */ EXTIB_IRQn = (uint8_t)6, /*!< GPIOB interrupt */ EXTID_IRQn = (uint8_t)7, /*!< GPIODinterrupt */ SWITCH_CSS_IRQn = (uint8_t)17, /*!< Clock switch/CSS interrupt/TIM1 Break/DAC interrupt */ TIM2_UPD_OVF_TRG_BRK_IRQn = (uint8_t)19, /*!< TIM2Update/Overflow/Trigger/Break interrupt*/ TIM2_CC_IRQn = (uint8_t)20, /*!< TIM2 inputcaptute/output compare interrupt */ TIM3_UPD_OVF_TRG_BRK_IRQn = (uint8_t)21, /*!< TIM3 Update/Overflow/Trigger/Breakinterrupt */ TIM3_CC_IRQn = (uint8_t)22, /*!< TIM3capture/compare interrupt */ USART1_TX_IRQn = (uint8_t)27, /*!< USART1 TXinterrupt */ USART1_RX_IRQn = (uint8_t)28, /*!< USART1 RXinterrupt */ I2C1_IRQn = (uint8_t)29 /*!< I2C1interrupt */ #elif defined (STM8L15X_HD) || defined(STM8L15X_MDP) || defined (STM8L05X_HD_VL) RTC_CSSLSE_IRQn = (uint8_t)4, /*!< RTC / CSSLSE interrupt */ EXTIB_G_IRQn = (uint8_t)6, /*!< GPIOB / Ginterrupt */ EXTID_H_IRQn = (uint8_t)7, /*!< GPIOD / Hinterrupt */ LCD_AES_IRQn = (uint8_t)16, /*!< LCD / AESinterrupt */ SWITCH_CSS_BREAK_DAC_IRQn = (uint8_t)17, /*!< Clock switch/CSS interrupt/TIM1 Break/DAC interrupt */ TIM2_UPD_OVF_TRG_BRK_USART2_TX_IRQn = (uint8_t)19, /*!< TIM2Update/Overflow/Trigger/Break /USART2 TX interrupt*/ TIM2_CC_USART2_RX_IRQn = (uint8_t)20, /*!< TIM2capture/compare / USART2 RX interrupt */ TIM3_UPD_OVF_TRG_BRK_USART3_TX_IRQn = (uint8_t)21, /*!< TIM3Update/Overflow/Trigger/Break / USART3 TX interrupt */ TIM3_CC_USART3_RX_IRQn = (uint8_t)22, /*!< TIM3capture/compare / USART3 RX interrupt */ TIM1_UPD_OVF_TRG_IRQn = (uint8_t)23, /*!< TIM1 TIM1 Update/Overflow/Triggerinterrupt */ TIM1_CC_IRQn = (uint8_t)24, /*!< TIM1capture/compare interrupt */ USART1_TX_TIM5_UPD_OVF_TRG_BRK_IRQn = (uint8_t)27, /*!< USART1 TX/ TIM5 Update/Overflow/Trigger/Break interrupt */ USART1_RX_TIM5_CC_IRQn = (uint8_t)28, /*!< USART1 RX/ TIM5 capture/compare interrupt */ I2C1_SPI2_IRQn = (uint8_t)29 /*!< I2C1 /SPI2 interrupt */ #endif /* STM8L15X_MD */ }IRQn_TypeDef; 1、 UART 中断 UART中断相对比价简单,直接在UART初始化的时候把中断开起来就可以了,以uart1为例: voidUsartInit(void) { SYSCFG_REMAPDeInit(); SYSCFG_REMAPPinConfig(REMAP_Pin_USART1TxRxPortC, ENABLE); STM_EVAL_COMInit(COM1, (uint32_t)115200,USART_WordLength_8b, USART_StopBits_1, \ USART_Parity_No,(USART_Mode_TypeDef)(USART_Mode_Tx | USART_Mode_Rx)); //读中断 USART_ITConfig(EVAL_COM1, USART_IT_RXNE,ENABLE);//enable USART1 RX interrupt //写中断 USART_ITConfig(EVAL_COM1, USART_IT_TXE,ENABLE); } 开启中断之后,那么就去捕捉中断,然后使用。 a、读中断:当UART的RX接收到数据时,会产生一个RX中断,中断入口如下 INTERRUPT_HANDLER(USART1_RX_TIM5_CC_IRQHandler, 28) { printf("\n\r USART1_RX_TIM5_CC_IRQHandler interrupt No28 \n\r"); } b、写中断:当我们往UART的TX 发送数据时,会产生一个TX中断,中断入口如下: INTERRUPT_HANDLER(USART1_TX_TIM5_UPD_OVF_TRG_BRK_IRQHandler,27) { printf("\n\rUSART1_TX_TIM5_UPD_OVF_TRG_BRK_IRQHandler interrupt No27 \n\r"); } 2、 GPIO中断 STM8L51X 有很多组GPIO,(GPIOA、GPIOB、GPIOC 等),每组GPIO由8个pin脚组成,每个pin脚我们都可以配置它为中断脚。8个pin脚对应的中断入口函数分别如下: INTERRUPT voidEXTI0_IRQHandler(void); /* EXTI PIN0 */ INTERRUPT void EXTI1_IRQHandler(void); /* EXTIPIN1 */ INTERRUPT void EXTI2_IRQHandler(void); /* EXTIPIN2 */ INTERRUPT void EXTI3_IRQHandler(void); /* EXTIPIN3 */ INTERRUPT void EXTI4_IRQHandler(void); /* EXTIPIN4 */ INTERRUPT void EXTI5_IRQHandler(void); /* EXTIPIN5 */ INTERRUPT void EXTI6_IRQHandler(void); /* EXTIPIN6 */ INTERRUPT voidEXTI7_IRQHandler(void); /* EXTI PIN7 */ 模式类型如下: typedefenum { GPIO_Mode_In_FL_No_IT = (uint8_t)0x00, /*!< Input floating, no externalinterrupt */ GPIO_Mode_In_PU_No_IT = (uint8_t)0x40, /*!< Input pull-up, no external interrupt*/ GPIO_Mode_In_FL_IT = (uint8_t)0x20, /*!< Input floating, external interrupt*/ GPIO_Mode_In_PU_IT = (uint8_t)0x60, /*!< Input pull-up, external interrupt */ GPIO_Mode_Out_OD_Low_Fast =(uint8_t)0xA0, /*!< Outputopen-drain, low level, 10MHz */ GPIO_Mode_Out_PP_Low_Fast =(uint8_t)0xE0, /*!< Output push-pull,low level, 10MHz */ GPIO_Mode_Out_OD_Low_Slow =(uint8_t)0x80, /*!< Outputopen-drain, low level, 2MHz */ GPIO_Mode_Out_PP_Low_Slow =(uint8_t)0xC0, /*!< Outputpush-pull, low level, 2MHz */ GPIO_Mode_Out_OD_HiZ_Fast =(uint8_t)0xB0, /*!< Outputopen-drain, high-impedance level, 10MHz */ GPIO_Mode_Out_PP_High_Fast =(uint8_t)0xF0, /*!< Outputpush-pull, high level, 10MHz */ GPIO_Mode_Out_OD_HiZ_Slow =(uint8_t)0x90, /*!< Outputopen-drain, high-impedance level, 2MHz */ GPIO_Mode_Out_PP_High_Slow =(uint8_t)0xD0 /*!< Outputpush-pull, high level, 2MHz */ }GPIO_Mode_TypeDef; 触发条件体如下: typedefenum { EXTI_Trigger_Falling_Low =(uint8_t)0x00, /*!< Interrupt on Falling edge and Low level */ EXTI_Trigger_Rising = (uint8_t)0x01, /*!< Interrupt onRising edge only */ EXTI_Trigger_Falling = (uint8_t)0x02, /*!< Interrupt onFalling edge only */ EXTI_Trigger_Rising_Falling= (uint8_t)0x03 /*!< Interrupt onRising and Falling edges */ } EXTI_Trigger_TypeDef; 优先级如下: typedef enum { ITC_PriorityLevel_0 =(uint8_t)0x02, /*!< Software priority level 0 (cannot be written) */ ITC_PriorityLevel_1 =(uint8_t)0x01, /*!< Software priority level 1 */ ITC_PriorityLevel_2 =(uint8_t)0x00, /*!< Software priority level 2 */ ITC_PriorityLevel_3 =(uint8_t)0x03 /*!< Software prioritylevel 3 */ } ITC_PriorityLevel_TypeDef; 如何配置GPIO中断呢?以GPIOB组的pin3脚为例: a、 首先需要重置一下外部中断: EXTI_DeInit() b、 初始化GPIO GPIO_Init(GPIOB, GPIO_Pin_3, GPIO_Mode_In_PU_IT); 这里模式类型我配置为GPIO_Mode_In_PU_IT类型 c、 配置中断触发条件: EXTI_SetPinSensitivity(EXTI_Pin_3,EXTI_Trigger_Falling_Low) 这里配置为下降沿触发 d、 设置中断优先级 ITC_SetSoftwarePriority(EXTI3_IRQn, ITC_PriorityLevel_1); 经过上述配置过后,当GPIOB组的第3个pin脚电平由高电平向低电平跳变时,会产生一个中断,然后就会调中断处理接口函数INTERRUPT void EXTI3_IRQHandler(void); /* EXTI PIN3 */ 记得在INTERRUPTvoid EXTI3_IRQHandler(void)接口里面调用: EXTI_ClearITPendingBit(EXTI_IT_Pin3);清除中断。