how to use EXTI interrupt with HAL library for stm32f1? - interrupt

i need to configure an exti interrupt on A1 port of my stm32f103 board.
I create a template with stm32cubemx but i'm trying to configure interrupt manually because it's a new feature of my code that i've already wrote. i'm reading many topics but i not found any solution.
In this project i use the HAL library and i follow this steps:
configure the GPIO
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
Enable IRQ
HAL_NVIC_SetPriority(EXTI1_IRQn, 3, 0);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
Customizing the callback
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == STEP_PIN)
{
GlobalMotorData.step.longint++;
}
}
i wrote The callback function in a new .c file and i do not touch the same function inside stm32f1xx_hal_gpio.c
i not enabled the macro HAL_EXTI_MODULE_ENABLED because the project not find the corrisponding .h header file but without the macro, code builds without errors.
What i forgot?
thank you

You are most likely missing the EXTI1 interrupt handler:
void EXTI1_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}

Related

STM32L4R5xx hangs when an external interrupt is enabled

I would like to use the pin PC3 as an external interrupt. Whenever I enable the interrupt I end up in the infinite loop.
This is how I init a gpio and its interrupt:
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
I have checked hardware and all signals are like they should be.
I tried PB0 and PC3 and the result is the same.
Anyone who knows how to play with stm32l4 and exti?
The infinite loop:
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
I dont even reach an interrupt here (I have a break point there)
void EXIT3_IRQnHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
if(!HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_3))
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_14);
}
EXTI_ClearITPendingBit(EXTI3_IRQn);
}
Maybe that is important to mention that I also have SPI configuration in the same project (SPI1).
If ISR name is not correct it will use some default error code (its name depends on configuration), as happens in your case.
In my code its named EXTI3_IRQHandler not EXTI3_IRQnHandler.
Check in your startup file (in my setup it is called startup_stm32l432xx.s) for ISR names to be used.

STM32L0 Stop Mode Not Working Properly

Currently, I am working on optimizing current consumption by using STOP Mode of the STM32L053C6T6 processor.
I'm facing a problem that I can not get through, and I'm very happy if you can help.
First of all, I would like to explain the algorithm in a very simplified way.
In the while loop, I print to Pc "STARTED" through the UART-Serial converter. Next, I set the RTC alarm to 10 seconds later. And the finally I sleep the MCU by using STOP MODE. After 10 seconds, MCU wakes up properly. So far everything is normal. After MCU wake up, I call the System Clock Config function. I print "woken-up" on the PC screen through UART. I can work this way forever But I do not like the current that circuit consume.
To reduce the power consumption, I set all the pins to analog before entering sleep mode. this method worked very well on reducing current consumption. But after all the pins are analog and MCU goes sleep and wake up, the MCU can not send to string to PC. I think UART Module does not work properly...
But I/O's and systick timer are running. I can understand this by toggling the LED in a certain delay(with HAL_DELAY)
Why I can not make it work with reinit all peripherals?
Here is my main code
int main(void){
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC_Init();
MX_I2C1_Init();
MX_RTC_Init();
MX_TIM22_Init();
MX_USART1_UART_Init()
MX_USART2_UART_Init();;
Init_RTC();
HAL_Delay(500);
while(1)
{
printf("Started\n\r");
for(uint16_t count1 = 0;count1<25;count1++){
HAL_GPIO_TogglePin(STATE_LED0_GPIO_Port,STATE_LED0_Pin);
HAL_Delay(25);
}
SetAlarm(10);
EnterStopMode();
printf("Woken-Up\n\r");
HAL_Delay(1000);
}
}
void EnterStopMode(void){
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_All;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
// STOP Moda girme komutu
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
HAL_Delay(1000);
SystemClock_Config();
HAL_Delay(500);
MX_GPIO_Init();
MX_USART2_UART_Init();
Solved
Well, I checked the Hal functions line by line. And I saw that after first peripheral initialization (uart,i2c,adc etc.), Hal functions do not allow re-init again by checking that particular peripherals instant state.
For example, In HAL_UART_Init(&huart2) function, In order to Init the low level hardware: (GPIO,CLOCK) the instant uart modules state must be UART_STATE_RESET.
In here
if(huart->gState == HAL_UART_STATE_RESET)
{
/* Allocate lock resource and initialize it */
huart->Lock = HAL_UNLOCKED;
/* Init the low level hardware : GPIO, CLOCK */
HAL_UART_MspInit(huart);
}
To overcome this problem, I reset that particular state of peripheral init. Because without not clearing those flags, uart init functions does not enter HAL_UART_MspInit(huart);
I know that is bulky solution, but it works for now.
void EnterStopMode(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
GPIO_InitStruct.Pin = GPIO_PIN_All;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
HAL_TIM_Base_Stop_IT(&htim22);
HAL_ADC_Stop_IT(&hadc);
/* Enter Stop Mode */
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
/* init the SYS Clocks */
SystemClock_Config();
/*Init IO's */
MX_GPIO_Init();
/* Clear Peripheral States for MspInit *7
huart1.gState = HAL_UART_STATE_RESET;
huart2.gState = HAL_UART_STATE_RESET;
hi2c1.State = HAL_I2C_STATE_RESET;
hadc.State = HAL_ADC_STATE_RESET;
MX_USART2_UART_Init();
MX_USART1_UART_Init();
MX_I2C1_Init();
MX_RTC_Init();
MX_TIM22_Init();
MX_ADC_Init();
HAL_ADCEx_Calibration_Start(&hadc,ADC_SINGLE_ENDED);
}

PIC16f877a USART Interrupt handling

I am trying to write a simple code to receive and resend data using usart but the code is not working. Can someone give suggestions on the possible flaws in the code.Please note that I am using USART at baud rate 9600 with clock frequency 4MHz.
#include<pic.h>
void main()
{ TRISB=0X00;
TXEN=1;
SYNC=0;
BRGH=1;
SPEN=1;
CREN=1;
//RCEN=1;
SPBRG=0X19;
INTCON=0X80;
TRISC7=1;
TRISC6=0;
RCIE=1;
TXIE=1;
while(1);
}
void interrupt rectrans()
{
if(RCIF==1)
{
TXREG=RCREG;
while(!TRMT);
RCIF=0;
}
else if(TXIF==1)
{TXIF=0;
}
}
I think you should enable GIE bit or Global Interrupt Enable bit for activating any interrupt as you can see from the attached diagram with this answer.. Try to add GIE=1; to enable global interrupt... You can see and AND gate to which GIE bit is connected only all any other interrupt will pass if GIE bit is high

STM32F411: is clearing an external interrupt flag really necessary?

I've bought an STM32F411 nucleo board and now I'm trying to understand various bits and pieces of the HAL. Starting with external interrupts seemed to be a good idea, because the board has a push button which is connected to PC13. So I've set up a simple toggle-the-frequency blinky. The code below is a bit simplified:
#define LED_PIN GPIO_PIN_5
#define BTN_PIN GPIO_PIN_13
static uint32_t blink_period = 250;
int main(void)
{
HAL_Init();
SystemClock_Config();
__GPIOA_CLK_ENABLE();
GPIO_InitTypeDef pinConfig;
pinConfig.Pin = (LED_PIN);
pinConfig.Pull = GPIO_NOPULL;
pinConfig.Mode = GPIO_MODE_OUTPUT_PP;
pinConfig.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOA, &pinConfig);
__GPIOC_CLK_ENABLE();
pinConfig.Pin = (BTN_PIN);
pinConfig.Pull = GPIO_NOPULL;
pinConfig.Mode = GPIO_MODE_IT_FALLING;
pinConfig.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOC, &pinConfig);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0x0F, 0x00);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
while (1)
{
HAL_GPIO_TogglePin(GPIOA, LED_PIN);
HAL_Delay(blink_period);
}
}
void EXTI15_10_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(BTN_PIN);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == BTN_PIN)
{
if (blink_period == 500)
{
blink_period = 250;
}
else
{
blink_period = 500;
}
}
}
When I push the button, an interrupt is generated and the blinky frequency changes from 1 to 2 Hz (or vice-versa). This works as intended, but why? I forgot to clear the pending interrupt flag, so the ISR should be called over and over. The datasheet clearly states that
When the selected edge occurs on the external interrupt line, an interrupt request is generated. The pending bit corresponding to the interrupt line is also set. This request is
reset by writing a ‘1’ in the pending register.
Reading a bit further reveals that this is a bit different for events:
When the selected edge occurs on the event line, an event pulse is generated. The pending bit corresponding to the event line is not set.
However, I'm not setting the button pin mode to any of the GPIO_MODE_EVT_... modes so I'm not using the event mechanism (to be honest I don't yet know what that even is - I just think that I'm not using it. Any hints are welcome).
So somewhere I should have to call void HAL_NVIC_ClearPendingIRQ (IRQn_Type IRQn), shouldn't I? It seems that clearing the flag by software is not necessary, because the ISR is not called more than once per falling edge. I've added a breakpoint in HAL_GPIO_EXTI_Callback to verify this.
Edit
As mentioned in the comments, the flag clearing code is in ST's implementation of the GPIO interrupt handler:
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);
}
}
This handler needs to be called by the actual ISR (which is done in my code) and it clears the pending flag corresponding to the GPIO_Pin argument. So I have to write an ISR which sorts out which flags are set, and call HAL_GPIO_EXTI_IRQHandler for each, which in turn calls my HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin), again with the pin as an argument. For each external interrupt, the pin number would get checked some ~3 times (in the ISR, in the handler and in the callback)!
If that is the solution, I want my problem back.
You don't have to call HAL_NVIC_ClearPendingIRQ (IRQn_Type IRQn) because the pending bit in the NVIC will be cleared automatically upon entering HAL_GPIO_EXTI_IRQHandler.
The HAL_GPIO_EXTI_IRQHandler() implementation clears the pending bit in the peripheral, not in the NVIC. If it didn't clear the pending bit by calling __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin), then the handler would be called again and again. The point is that you must distinguish between the interrupt pending bit in the peripheral and the pending bit in the NVIC.

Cortex M-0: Simple external interrupt

I'm trying to set up an external interrupt on my LPC812 uC. I've made the following code
#include "LPC8xx.h"
#define RLED 7 // red LED
bool pause = false;
void PININT0_IRQHandler(void)
{
pause = !pause;
}
int main(void) {
LPC_GPIO_PORT->DIR0 |= 1<<RLED; // set pin as output
LPC_GPIO_PORT->SET0 = 1<<RLED;
NVIC_EnableIRQ(PININT0_IRQn);
while (1)
{
if(!pause)
{
LPC_GPIO_PORT->CLR0 = 1<<RLED;
}
}
}
But it isn't working. Am I missing something?
I'm not familiar with NXP MCUs.
But at least place break piont inside PININT0_IRQHandler, to understand clearly that interrupt is not generated.
Also it will be nice to clear interrupt flag inside handler.
Some peripherals need interrupt permission in peripheral registers in addition to NVIC setup.
Did you setup input pin somewhere?
Your code only initialize GPIO 7 pin as output.