搞了几天了,找不到原因,不知各路大神是否有遇到类似问题,提供点建议,问题描述如下:
实现功能如下,根据外部中断EXTI0、EXTI1来改变某个IO的输出电平,当此IO输出电平持续在低电平1ms以上时,触发定时器6,当PD8为低电位时,外部电路隔一段时间后会触发EXTI1, 当PD8为高电位时,又会触发EXTI0 中断
STM32外部中断配置:
- void EXTI_Configuration()
- {
- EXTI_InitTypeDef EXTI_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- #ifdef VECT_TAB_RAM
- /* Set the Vector Table base location at 0x20000000 */
- NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
- #else /* VECT_TAB_FLASH */
- /* Set the Vector Table base location at 0x08000000 */
- NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
- #endif
- /* Configure the NVIC Preemption Priority Bits */
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- EXTI_ClearITPendingBit(EXTI_Line0);
- EXTI_ClearITPendingBit(EXTI_Line1);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource1);
- EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1; //选择中断线路0 1
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置为中断请求,非事件请求
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //设置中断触发方式为下降沿触发
- EXTI_InitStructure.EXTI_LineCmd = ENABLE; //外部中断使能
- EXTI_Init(&EXTI_InitStructure);
- EXTI->IMR&=~(1|1<<1);
- /*允许EXTI0中断 */
- NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- /*允许EXTI1中断 */
- NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
复制代码- void EXTI0_IRQHandler(void)
- {
- if (RESET!=(EXTI->PR&EXTI_Line0))
- {
- EXTI->PR = EXTI_Line0;
- if (RESET!=(EXTI->IMR&EXTI_Line0))
- {
- TAG.FbCurcuit1 = 1;
- GPIOD->BSRR = GPIO_Pin_8;
- if (0==Hall1)
- {
- EXTI->IMR&=~(EXTI_Line0);
- TIM6->SR = (uint16_t)~TIM_IT_Update;
- TIM6->CR1 &= ((uint16_t)~TIM_CR1_CEN);
- Hall1 = 1;
- }
- else
- {
- TIM6->CNT = 0;
- TIM6->SR = (uint16_t)~TIM_IT_Update;
- TIM6->CR1 |= TIM_CR1_CEN;
- }
- }
- EXTI->PR = EXTI_Line0;
- }
- }
- void EXTI1_IRQHandler(void)
- {
- if (RESET!=(EXTI->PR&EXTI_Line1))
- {
- EXTI->PR = EXTI_Line1;
- if (RESET!=(EXTI->IMR&EXTI_Line1))
- {
- GPIOD->BRR = GPIO_Pin_8;
- TIM6->SR = (uint16_t)~TIM_IT_Update;
- TIM6->CR1 &= ((uint16_t)~TIM_CR1_CEN);
- }
- EXTI->PR = EXTI_Line1;
- }
- }
复制代码
启动这个功能后,运行一段时间后,会进入定时器6的中断,跟踪发现是某个EXTI1中断没有得到执行,检查了所有相关的配置以及设计到相关IO操作的地方,没有发现异常,现贴出部分跟踪数据:
在TIM6中断服务程序入口处设置断点,从上面截图中可以看到 EXTI1 中断标志位PR1 是有被置位的, 但EXTI0 EXTI1 最后一次触发时间是418.00248863, ,而TIM6触发是在 418.00408187, , 可见是因为EXTI1未得到执行从而导致TIM6未关闭而进入了TIM6中断,此时外部中断PR1已经是置位的,为什么EXTI1有发生中断却进不了中断函数呢,而前面却一直可以进去
上图是PE0和PE1的输入,黄色是PE0
外部中断的频率大约100k,工作在72M的stm32f103vct6 应该是可以承受的吧
|