2021-10-17 12:02 PM
Hi,
In my application running on a Nucleo F446RE I notice that EXTI interrupts from GPIOA are not arriving in the EXTI15_10_IRQHandler() when the Nucleo board is connected to external power on E5V, JP5 on E5V and the ST-LINK is disconnected from USB. When the board is on external power E5V, JP2 on E5V, and the ST-LINK is connected to USB, the interrupts from GPIOA pins arrive fine.
For GPIOC the EXTI interrupts arrive fine in EXTI15_10_IRQHandler() in all settings
I bareboned the application to a simple Blink program, with all default board and clock settings (from STM32CubeIDE version 1.7.0), some buttons connected to PC13, PA11 and PA12, and the issue remains.
Unfortunately I cannot debug the software when the ST-LINK is not connected to investigate what makes the difference between these two settings.
It does not seem to make any difference if I have STM32CubeIDE opened or not at the moment I connect ST-LINK to USB.
In the RM0390 STM32F446 Reference Manual I cannot find the solution to this issue. Can anyone please help me with this?
The entire source code for main.c is attached.
Regards, Koen
2021-10-17 12:32 PM
> some buttons connected to PC13, PA11 and PA12, and the issue remains.
> GPIO_InitStruct.Pull = GPIO_NOPULL;
And how are these buttons connected exactly? Is there an external pullup/pulldown so the level in specified in both the pressed and not pressed conditions? Your code applies no internal pullups.
The flag variable should be volatile since it is modified in an interrupt.
2021-10-17 02:50 PM
Thanks for your rapid response.
You are right about the volatile flag. However, that does not make any difference, the issue remains.
volatile int flag = 0;
The button on PC13 is the Nucleo onboard blue button.
The buttons on PA11 and PA12 actually are the contacts of a rotary encoder (WPI435), with their own 10k pull-up resistors.
So I think specifying all these pins as "no pull-up and no pull-down" is correct.
2021-10-17 03:45 PM
What is the primary clock source? Is the program running at all? Modify it to blink all the time, stop blinking when the interrupt occurs.
Read out and check/post relevant GPIO, EXTI, SYSCFG registers content.
I personally wouldn't handle encoder or button inputs using EXTI. Some timers have hardware to handle encoders, their inputs incorporate adjustable filters.
JW
2021-10-17 04:58 PM
Ultimately, the chip doesn't know how it's being powered and will respond consistently as long as its power rail is sufficient, regardless of the source. That means the likely issue is in your hardware, somewhere, perhaps how these pins are connected and how it's different in each configuration. Ensure the onboard (unpowered) ST-Link isn't holding the chip in reset. Ensure the voltage on each pin is actually changing by monitoring them with a multimeter or monitoring the IDR register.
2021-10-18 02:35 AM
Problem is solved!
For the rotary encoder I was taking the 5V from CN10 pin 8, which is U5V. This pin does not have 5V on it when the ST-LINK is disconnected. Connecting the encoder to CN7 pin 18 solved the problem.
@Community member I tried using a timer in encoder mode, but I got too many problems with bouncing. For using an encoder on EXTI I have got a very simple debouncing function, which works like a treat.
volatile int encoder = 0;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
static GPIO_PinState A, B, prevA = GPIO_PIN_SET, prevB = GPIO_PIN_SET;
switch (GPIO_Pin) {
case (ENCODER_A_Pin):
B = HAL_GPIO_ReadPin(ENCODER_B_GPIO_Port, ENCODER_B_Pin);
if (B != prevB) {
if (B == GPIO_PIN_SET && A == GPIO_PIN_RESET)
encoder++;
prevB = B;
}
break;
case (ENCODER_B_Pin):
A = HAL_GPIO_ReadPin(ENCODER_A_GPIO_Port, ENCODER_A_Pin);
if (A != prevA) {
if (A == GPIO_PIN_SET && B == GPIO_PIN_RESET)
encoder--;
prevA = A;
}
break;
default:
break;
}
}
Thanks to all for helping me, very much appreciated!
2021-10-18 06:53 AM
Thanks for coming back with the solution. Please select your post as Best so that the thread is marked as solved.
> I tried using a timer in encoder mode, but I got too many problems with bouncing.
Then you did something incorrectly. But it's true that in 'F446 the timer has only x2 and x4 modes, whereas you obviously use x1 (your encoder has probably detents, hasn't it).
One of the problems with the EXTI is, that with bouncy input you can easily exhaust the processing capability of the mcu. (Timers, if properly used, can work with no or almost no software overhead at all.) A relatively simple change but potentially big improvement in your case is to disable the "current" interrupt and enable the "other" in EXTI, at each edge detection. As a further optimization, you can also enable detection of only one edge (rising, if I correctly understood your algorithm).
JW