Usart receive interrupt sends program to UsageFault_Handler() infinite loop
No, usart irq handler never executes.
Probbably the problem is that void USART2_IRQHandler(void) is not definened in startup file, since
it is handled like unexpected interrupt.
Whole code is here (Maybe i forgot to call some specific stm32 workbench interrupt enable command 😀 ):
- include "stm32f4xx_gpio.h"
- include "stm32f4xx.h"
- include "stm32f4xx_rcc.h"
- include "stm32f4xx_usart.h"
- include "stm32f4xx_exti.h"
//GPIO's defines and functions
- define LEDG GPIO_Pin_12
- define LEDO GPIO_Pin_13
- define LEDR GPIO_Pin_14
- define LEDB GPIO_Pin_15
- define LEDPORT GPIOD
- define LEDPORTCLK RCC_AHB1ENR_GPIODEN
- define BUTTON GPIO_Pin_0
- define BUTTONPORT GPIOA
- define BUTTONPORTCLK RCC_AHB1ENR_GPIOAEN
- define DELAY 900000
- define BAUD_115200 115200
- define BAUD_9600 9600
- define BAUD_4800 4800
//These are the prototypes for the routines
void usart2_Init(int baudrate);
void usart2_Send(uint8_t data);
uint16_t usart2_Recieve(void);
void usart2_confInterrupt(void);
void usart2_SendString(char* string);
char* usart2_RecieveString(char* String);
void initializeLeds(void);
void initializeButton(void);
int main(void)
{
initializeLeds();
usart2_Init(BAUD_9600);
//initializeButton();
GPIO_ToggleBits(LEDPORT,LEDG);
usart2_confInterrupt();
for(;;){
usart2_SendString("BEEF\n");
}
}
// Serial data interrupt handler
void USART2_IRQHandler(void){
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){
usart2_Send(USART_ReceiveData(USART2));
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
}
}
void EXTI0_IRQHandler(void){
if(EXTI_GetITStatus(EXTI_Line0) == SET){
GPIO_ToggleBits(LEDPORT,LEDG);
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
void initializeLeds(){
GPIO_InitTypeDef GPIO_InitStructure;
//Enable clock on APB2 pripheral bus where button and LEDs are connected
RCC_AHB1PeriphClockCmd(LEDPORTCLK, ENABLE);
//select pins to initialize LED
GPIO_InitStructure.GPIO_Pin = LEDG|LEDB|LEDR|LEDO;
//select output push-pull mode
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//highest speed available
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LEDPORT, &GPIO_InitStructure);
}
void initializeButton(void){
GPIO_InitTypeDef GPIO_InitStructure;
//Enable clock on APB2 pripheral bus where button and LEDs are connected
RCC_AHB1PeriphClockCmd(BUTTONPORTCLK, ENABLE);
//select pins to initialize LED
GPIO_InitStructure.GPIO_Pin = BUTTON;
//select output push-pull mode
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
//highest speed available
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(BUTTONPORT, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2ENR_SYSCFGEN, ENABLE);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line= EXTI_Line0;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_Init(&NVIC_InitStructure);
}
void usart2_Init(int baudrate){
GPIO_InitTypeDef GPIO_InitStruct;
// Enable clock for GPIOA
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/**
* Tell pins PA9 and PA10 which alternating function you will use
* @important Make sure, these lines are before pins configuration!
*/
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
// Initialize pins as alternating function
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
/**
* Enable clock for USART1 peripheral
*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
/**
* Set Baudrate to value you pass to function
* Disable Hardware Flow control
* Set Mode To TX and RX, so USART will work in full-duplex mode
* Disable parity bit
* Set 1 stop bit
* Set Data bits to 8
*
* Initialize USART1
* Activate USART1
*/
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = baudrate;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART2, &USART_InitStruct);
USART_Cmd(USART2, ENABLE);
}
void usart2_Send(uint8_t data)
{
USART_SendData(USART2,data);
while(USART_GetFlagStatus(USART2, USART_FLAG_TC ) == RESET){
}
}
void usart2_SendString(char* string){
while(*string != 0){
usart2_Send(*string++);
}
}
char* usart2_RecieveString(char* String){
while(*String != '\r'){
while(USART_GetFlagStatus(USART2,USART_FLAG_RXNE) == RESET);
*String++ = USART_ReceiveData(USART2);
}
return String;
}
uint16_t usart2_Recieve(void){
while(USART_GetFlagStatus(USART2,USART_FLAG_RXNE) == RESET);
return USART_ReceiveData(USART2);
}
void usart2_confInterrupt(void){
NVIC_InitTypeDef NVIC_InitStruct;
/**
* Set Channel to USART1
* Set Channel Cmd to enable. That will enable USART1 channel in NVIC
* Set Both priorities to 0. This means high priority
*
* Initialize NVIC
*/
NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
// 0 priority is the highest
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
}