cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 - USART3 Sending problem

guitest02
Associate II
Posted on April 14, 2013 at 20:30

Dear everyone,

I want to use the USART3 to send strings, but I don't know why it doesn't work. I saw multiple examples here on the forum and I think my code is quite good, I can't seem to make it works... Well, I want to send the data using the Wifly, I see the light on this one that it is receiving something, but when I receive it one my computer, I just see that I receive a one byte word. If I connect the USART3 Tx to another microcontroller that I know is working to send to a hyperterminal on my computer, I see nothing. So I think I'm only sending NULL messages. Here is the code:

/*=========================================================================================*/
/* main.c
/**
* @brief Main program.
* @param None
* @retval None
*/
int main(void)
{
RCC_ClocksTypeDef RCC_Clocks;
/* SysTick end of count event each 10ms */
RCC_GetClocksFreq(&RCC_Clocks);
SysTick_Config(RCC_Clocks.HCLK_Frequency / 100); 
SystemCoreClock = RCC_Clocks.HCLK_Frequency;
// USART3 configuration to send data
USART3_Config();
while(1)
{} 
}
/**
* @brief Initializes the USART3 to send data (tx => pin PD8 ; rx => pin PD9)
* @param None
* @retval None
*/
void USART3_Config(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
/* USART3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
/* GPIOC clocks enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
//configure AF
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3); // Tx
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3); // Rx
/* Configure USART Tx and Rx as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // before: GPIO_PuPd_NOPULL UP
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* NVIC configuration ------------------------------------------------------*/
/* Enable the interrupt Rx and Tx USART3 */
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; // we want to configure the USART3 interrupts
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the priority group of the USART3 interrupts
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART3 interrupts are globally enabled
NVIC_Init(&NVIC_InitStructure); 
/* USARTx configuration ------------------------------------------------------*/
/* USARTx configured as follow:
- BaudRate = 9600 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control not enabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_DeInit(USART3);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART3, &USART_InitStructure); 
USART_Cmd(USART3, ENABLE);
}
/*=========================================================================================*/
/* stm32f4xx_it.c
/* Private variables ---------------------------------------------------------*/
__IO uint8_t Counter = 0x00;
__IO uint8_t CounterUSART3 = 0x00;
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
Counter ++;
if (Counter == 10){
Counter = 0x00; 
char data[] = ''/MessageToSend'';
char *d = data;
while(*d){
//while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
USART_SendData(USART3, *d);
}
}
void USART3_IRQHandler(void) 
{ 
CounterUART3 ++;
if (CounterUART3 == 10){ 
USART_SendData(USART3, 'D');
CounterUART3 = 0x00;
}
}

I commented the

while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);

since it seems to go into an endless loop. Also, my USART3_IRQHandler doesn't want to work. So am I having problem with interrupt ? Maybe worth noting, this is only part of my code. I'm also using 9 ADC with DMA (pins: PA0, PA1, PA2, PA3, PA4, PB0, PB1, PC0, PC2), 6 PWM outputs (pins: PC6, PC7, PC8, PC9, PE5m PE6) and one digital input (pin: PB4) and this is on the STM32F4DISCOVERY. So maybe something with all this give problem to my USART3 ? Thanks a lot for any input ! That would be well appreciated !! G #stm32-discovery #stm32 #usart
2 REPLIES 2
Posted on April 14, 2013 at 21:20

There seem to be a number of misconceptions about how interrupts work, how to initialize them (order) and how to service them (check the status, and clear the condition). This is then compounded on the M3 architecture, because if you fail to service them properly they will keep re-entering.

The use of C++ syntax might suggest other issues with name mangling and the vector table pointing to the routine you want. You can review the .MAP / .LST file for confirmation.

You should only ever send data when TXE is asserted, jamming data in there will result in undesired operation. If RXNE is asserted you must read the data out to clear the condition. If TXE is asserted you must provide data to clear the condition. Failure to clear conditions will result in re-entrance (tail chaining), if you have no data you need to disable the interrupt source.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
guitest02
Associate II
Posted on April 15, 2013 at 09:23

Dear clive1, thanks for your input ! I tried to make it fast by collecting multiple example to make my own, but yeah I should have thought a little more before. I'm trying to learn programming and working with microcontroller on my own since I'm more of a musician than a programmer, but habitually I can find my way.

However, I did a new program, that only deal with the usart to be sure that I get everything working before putting in inside my main program. I based it on one of your example you put on this forum and by changing some things there and there... Right now, this is ''working''! I'm trying to send an OSC message. Everything works, but if I send it with the wifly, I see a message arriving on my computer every about 800ms. This is very slow for what I want to do and the message have some problem... I mean, I want to receive every time: ''/oscillator/4/frequency, 440'' but I get: /oscillator/4/frequency, 440 4/frequency, 440 illator/4/frequency, 440 ency, 440 ... But if I read the message directly using a uart from another microcontroller to a hyperterminal on my computer, the message is very fast and everything is there. I think this could be a problem with the Baudrate between my STM32 and Wifly, but both should be at 9600 Or could it be that the message is continually sending and I would need to have a pause between messages to separate them ? If you have any other clue, please let me know! Here is the code:

// STM32 USART IRQ TX/RX Loop (USART3 Tx PD.8, Rx PD.9) STM32F4 Discovery - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
uint16_t i = 0;
//volatile char StringLoop[] = ''The quick brown fox jumps over the lazy dog

'';
//volatile char OscMess[] = ''/oscillator/4/frequency\0,11\0\0'';
volatile char OscMess2[] = {0x2f, 0x6f, 0x73, 0x63, 0x69, 0x6c, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x34, 0x2f, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x00, 0x2c, 0x66, 0x00, 0x00, 0x43, 0xdc, 0x00, 0x00};
/**************************************************************************************/
void RCC_Configuration(void)
{
/* --------------------------- System Clocks Configuration -----------------*/
/* USART3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
/* GPIOD clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
}
/**************************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*-------------------------- GPIO Configuration ----------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Connect USART pins to AF */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);
}
/**************************************************************************************/
void USART3_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
/* USARTx configuration ------------------------------------------------------*/
/* USARTx configured as follow:
- BaudRate = 9600 baud
- Word Length = 8 Bits
- One Stop Bit
- No parity
- Hardware flow control disabled (RTS and CTS signals)
- Receive and transmit enabled
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_RXNE |USART_IT_TXE, ENABLE);
USART_Cmd(USART3, ENABLE);
}
/**************************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART3 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************************/
void USART3_IRQHandler(void)
{
// USART Sending
if (USART_GetITStatus(USART3, USART_IT_TXE) != RESET) // Transmit the string in a loop
{
for(i = 0; i < (sizeof(OscMess2)); i++){
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET); // Wait for Empty
USART_SendData(USART3, OscMess2[i]);
}
}
}
/**************************************************************************************/
int main(void)
{ 
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
USART3_Configuration();
while(1){}; // Don't want to exit
}
/**************************************************************************************/

Thanks again ! G