2024-11-24 01:10 PM - last edited on 2024-11-25 05:50 AM by SofLit
So I have three switches (nothing special just momentary push button) wired into the board PC2, PC3 and PA4. All are using internal pullups. PC2 and PC3 are set for rising / falling trigger IRQs and PA4 is set for falling IRQ. They all have their own ISR function and use a single callback. I am monitoring EXT -> PR register (interrupt flag) and I notice that when I push one of the buttons it will sometimes set 1, 2 or even all 3 of the flags and I never touch the other buttons. Here is an example of me pushing PC2 and 2,3,4 all went off. Sometimes only the one I want goes off as I would expect but many times multiple flags get set. There is nothing else on top of the board. It is a Nucleo-F401RE. Any ideas as to what could be going on here as I am totally confused?
Solved! Go to Solution.
2024-11-25 12:28 PM
I seemed to have solved the issue.....Not completely sure but so far no false triggers have appeared. I mimicked the blue button on the nucleo board with respect to adding 100 ohm resistor between 0.1uF cap and ground.
2024-11-24 03:09 PM
Maybe EM (capacitive) coupling between the pins, especially if the related wires/tracks are run next to each other.
The EXTI is asynchronous and it can react to pulses shorter than the system clock period.
JW
2024-11-25 05:33 AM
Good thought but no....I wired 0.1uF capacitors across both switches and shortened wiring.....This should be ridiculously simple, not sure what is going on....Low level code that clears PR suggests to set register using = instead of |= ....I set breakpoints with the handlers .... _it.c file on each switch and after pushing one switch check the PR flags to find both flags getting set???
Could it be something with the switches using both rising and falling edges? I used CubeMX to initialize this
/*Configure GPIO pins : swExpand_Pin swCompress_Pin */
GPIO_InitStruct.Pin = swExpand_Pin|swCompress_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
Here are my blocks of code if this helps (handlers in ..._it.c file) these two pins are rising / falling edges
void EXTI2_IRQHandler(void)
{
/* USER CODE BEGIN EXTI2_IRQn 0 */
/* USER CODE END EXTI2_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(swExpand_Pin);
/* USER CODE BEGIN EXTI2_IRQn 1 */
/* USER CODE END EXTI2_IRQn 1 */
}
/**
* @brief This function handles EXTI line3 interrupt.
*/
void EXTI3_IRQHandler(void)
{
/* USER CODE BEGIN EXTI3_IRQn 0 */
/* USER CODE END EXTI3_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(swCompress_Pin);
/* USER CODE BEGIN EXTI3_IRQn 1 */
/* USER CODE END EXTI3_IRQn 1 */
}
Actual IRQ handler ( ...._hal_gpio.c)
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
Callback itself (main.c) ...Pushing either swCompress or swExpand switch most times causes multiple flags to go off (PC2 and PC3). I disable the IRQ in the callback and wait for a timer to go off 100ms later (debounce) and within the timer I read the GPIO level
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == swCompress_Pin)
{
EXTI->IMR &= ~(swCompress_Pin); //disable further button action
//**********debounce routine***************
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, DEBOUNCE_TIME);
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC1);
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_CC1);
//*****************************************
}
if (GPIO_Pin == swExpand_Pin)
{
EXTI->IMR &= ~(swExpand_Pin); //disable further button action
//**********debounce routine***************
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, DEBOUNCE_TIME);
__HAL_TIM_CLEAR_FLAG(&htim1, TIM_FLAG_CC1);
__HAL_TIM_ENABLE_IT(&htim1, TIM_IT_CC1);
//*****************************************
}
if (GPIO_Pin == B1_Pin)
{
motor.upperBoundValue = 0;
motor.lowerBoundValue = 0;
ISR.program = T;
}
if (GPIO_Pin == flashErase_Pin)
{
EXTI->IMR &= ~(flashErase_Pin);
//ISR.erase = T;
}
}
Thanks
2024-11-25 05:54 AM
Hello,
Why are you setting for both edges: falling and rising?
2024-11-25 06:08 AM
What else do you do in that program?
What else do you have connected to that board?
JW
2024-11-25 07:13 AM
This will be driving a NEMA stepper motor with an IHM03A1 stacked onto the Nucleo-F401 ....HOWEVER I have removed the stack and the motor and still have the issue.... I am not running anything on the board and it LITERALLY sits there and waits for an ISR pushbutton .... One button will move motor FORWARD, the other BACKWARD. The buttons use both edges as the falling edge triggers to advance motor and the rising edge releases the motor from running.....
2024-11-25 07:13 AM
See response below to @waclawek.jan
2024-11-25 07:25 AM - edited 2024-11-25 07:50 AM
Could you please share schematics part of the buttons?
To isolate the behavior, you need to start with a very basic project with only these buttons and nothing else connected to that Nucleo-F401RE board.
2024-11-25 09:27 AM
there is no schematic to show, see picture...two momentary push buttons with a 0.1uF cap across each. Wired between ground and PCx (where x = 2 and 3)....Thats it....start debugger, run program, stop and see PR = 0, run again, push single button and see both flags being set in PR register.....Not sure what else I can say. I completely eliminated the callback and as soon as I enter the ISR I disable them....Notice breakpoint sets on the handlers and then notice the PR register....A single button push causes BOTH of these to fire off.
2024-11-25 12:28 PM
I seemed to have solved the issue.....Not completely sure but so far no false triggers have appeared. I mimicked the blue button on the nucleo board with respect to adding 100 ohm resistor between 0.1uF cap and ground.