本文采用官方的库函数接口实现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, /*!<ADC1/Comparator interrupt */
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);清除中断。