cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103ZE USART1 interrupt issue

dusan
Associate II
Posted on August 07, 2012 at 15:13

Hi,

I have problem with USART1 interrupt implementation. In pooling mode, everything works, but when I try to setup interrupt, there's nothing on the output? How to enable USART1 interrupt? Do I need to setup some other stuff? Thanks

#include <
stm32f10x_nvic.h
>
#include <
stm32f10x_gpio.h
>
#include <
stm32f10x_rcc.h
>
#include <
stm32f10x_flash.h
>
#include <
stm32f10x_usart.h
> 
#define MAX_STRLEN 10 
volatile char received_string[MAX_STRLEN+1];
void USART1_Initialization(void);
void USART_Puts(USART_TypeDef* USARTx, volatile char *s);
void USART1_IRQHandler(void);
//********** USART1 INITIALIZATION **************
void USART1_Initialization(void)
{ 
// ******** RCC Config **************
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); // Enables clock for USART1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // Enable clock for port A

// ******** GPIO Config **********
GPIO_InitTypeDef GPIO_InitStructure;
// Configure USART1 Tx (PA.09) as alternate function push-pull 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
GPIO_Init(GPIOA, &GPIO_InitStructure); 
// Configure USART1 Rx (PA.10) as input floating 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
GPIO_Init(GPIOA, &GPIO_InitStructure);
// ********* NVIC Config ***********
NVIC_InitTypeDef NVIC_InitStructure; // Configure the NVIC (nested vector interrupt controller) 
#ifdef VECT_TAB_RAM 
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); // Set the Vector Table base location at 0x20000000 
#else // VECT_TAB_FLASH
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); // Set the Vector Table base location at 0x08000000
#endif 
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; // we want to configure the USART1 interrupts
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // this sets the priority group of the USART1 interrupts
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled
NVIC_Init(&NVIC_InitStructure); 
// ******** USART Config **********
USART_InitTypeDef USART_InitStruct; // this is for the USART1 initilization
USART_InitStruct.USART_BaudRate = 9600; // the baudrate is set to 9600
USART_InitStruct.USART_WordLength = USART_WordLength_8b; // want the data frame size to be 8 bits (standard)
USART_InitStruct.USART_StopBits = USART_StopBits_1; // want 1 stop bit (standard)
USART_InitStruct.USART_Parity = USART_Parity_No; // don't want a parity bit (standard)
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // don't want flow control (standard)
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // enable the transmitter and the receiver
USART_Init(USART1, &USART_InitStruct);
USART_Cmd(USART1, ENABLE); // enable USART1 peripheral
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable Receive Data register Not Empty interrupt
USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // enable Transmit Data register Empty interrupt
}
//************ USART_PUTS FUNCTION **********
void USART_Puts(USART_TypeDef* USARTx, volatile char *s)
{
while(*s)
{ 
while( !(USARTx->SR & 0x00000040) ); // wait until data register is empty
USART_SendData(USARTx, *s);
*s++;
}
}
//******** USART1_IRQHandler *************
void USART1_IRQHandler(void) 
{
static unsigned int cnt = 0; // counts number of characters
unsigned int i;
if(USART_GetITStatus(USART1, USART_IT_RXNE)) // check if the USART1 receive interrupt flag was set
{
char t = USART1->DR; // character from data reg is stored into t
if (t != '\r') // if not CR (carriage return)
{ 
received_string[cnt] = t; // character is stored into receive buffer
cnt++; // increase number of character
}
else // if there's no more characters
{
received_string[cnt++] = '\0'; // put terminator character in the end of buffer
cnt = 0; // reset character counter
USART_Puts(USART1, received_string); // send character to printing
for (i = 0; i <= MAX_STRLEN+1; i++) // flush buffer
received_string[i] = '\0'; 
} 
}
}
//*********** MAIN FUNCTION ************
int main(void) 
{
NVIC_SETPRIMASK(); // Disable ALL interrupts 
USART1_Initialization(); // Initialization of all parameters and enabling USART1 interrupt
NVIC_RESETPRIMASK(); // Enable ALL interrupts
USART_Puts(USART1, ''Welcome \r\n''); // just send a message to indicate that it works
while(1)
{ 
// waiting for USART1 interrupt to occur
}
}

#stm32-usart-interrupt
4 REPLIES 4
Posted on August 07, 2012 at 15:43

USART_ITConfig(USART1, USART_IT_TXE, ENABLE); 

If you enable the TX interrupt, you'd better have some data to supply otherwise it will get stuck in the interrupt state. Using USART_Puts() under interrupt is also a bad plan.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dusan
Associate II
Posted on August 07, 2012 at 15:55

Ok, TX interrupt is disabled.

What is your suggestion about USART_Puts() function? How can I change it, and how it affects code?

Main problem is that the program never enters USART1_IRQHandler?
Posted on August 07, 2012 at 16:27

I don't know what toolchain you're using, but it looks like you're using an old version of the firmware library.

If you're using CPP, then your IRQ handler will have the wrong name, and it won't match the one in the vector table, and consequently won't get called. Look at your map and listing files.

You should buffer your output data, not spin in a while loop for 1000's of microseconds in an interrupt routine.

Suggest you get a current version of the library, and review the examples.

STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\USART\HyperTerminal_Interrupt\main.c
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dusan
Associate II
Posted on August 07, 2012 at 20:46

Thanks for your help.

I'm using IAR Embedded Workbench.

Yes, I have old version of firmware library (V2.0.3) and now I downloaded 3.5.0. Can you please wrote small how to about using all files in the library, because I see there some startup files? Are these files mandatory? Do I need to use CMSIS library? Other than that, and stuff you mentioned in your previous posts, are other settings ok?

Sorry for this beginer questions, I'm new in this area :).