cancel
Showing results for 
Search instead for 
Did you mean: 

USART doesn't transmit first character

lorbek
Associate II
Posted on March 25, 2013 at 12:30

Hi,

I have a problem with transmitting character through USART3 port in STM32F207.

Here there is the USART configuration code:

--------------

USART_DeInit(USART3);

USART_InitStructure.USART_BaudRate = 115200;

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(USARTx, &USART_InitStructure);

------------

The problem occurs when sending characters, USART doesn't send the first one (checking with hyperterminal), and then it goes on with sending the others correctly. It just misses the first one. If I debug the code, this trouble doesn't occur and the transmission is correct. 

At the moment I'm sending a ''\r'' character at first, in order to send the correct string later, but this is not so reliable.

Does anybody knows something about that?

Thanks 

Stefano
11 REPLIES 11
Posted on March 25, 2013 at 12:37

How, and where do you set up the pins? Do you wait for a couple of bit times for the lines to get into a normal state prior to sending the first character so the receiving side can frame the data properly? It is not unusual to receive line noise as the transmitter first turns on.

Show your sending and pin configuration code?
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lorbek
Associate II
Posted on March 25, 2013 at 12:48

This is the complete conf code:

-------

void USART_Config(void)

{

  USART_InitTypeDef USART_InitStructure;

  GPIO_InitTypeDef GPIO_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

DMA_InitTypeDef  DMA_InitStructure;

  

  /* Enable GPIO clock */

  RCC_AHB1PeriphClockCmd(USARTx_TX_GPIO_CLK | USARTx_RX_GPIO_CLK, ENABLE);

  

  /* Enable USART clock */

  USARTx_CLK_INIT(USARTx_CLK, ENABLE);

   

  /* Connect USART pins to AF7 */

  GPIO_PinAFConfig(USARTx_TX_GPIO_PORT, USARTx_TX_SOURCE, USARTx_TX_AF);

  GPIO_PinAFConfig(USARTx_RX_GPIO_PORT, USARTx_RX_SOURCE, USARTx_RX_AF);

  

  /* 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_UP;

  

  GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN;

  GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure);

  

  GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN;

  GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure);

  /* USART3 configuration ----------------------------------------------------*/

USART_DeInit(USART3);

  USART_InitStructure.USART_BaudRate = USART_BAUD_RATE;

  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(USARTx, &USART_InitStructure);

  /* Configure DMA controller to manage USART TX and RX DMA request ----------*/

  /* Enable the DMA clock */

  RCC_AHB1PeriphClockCmd(USARTx_DMAx_CLK, ENABLE);  

  

/* DMA USART3 Configuration */

DMA_DeInit(USARTx_RX_DMA_STREAM);

  DMA_Cmd(USARTx_RX_DMA_STREAM, DISABLE);

  DMA_InitStructure.DMA_PeripheralBaseAddr = USARTx_DR_ADDRESS;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;

  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

  /* Prepare the DMA to transfer the ACK command from the USART to the memory */

  DMA_InitStructure.DMA_Channel = USARTx_RX_DMA_CHANNEL;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;  

DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)AckBuffer1;

DMA_InitStructure.DMA_BufferSize = (uint16_t)0x09;

DMA_Init(USARTx_RX_DMA_STREAM, &DMA_InitStructure); 

// // /* Enable the DMA RX Stream */

// DMA_Cmd(USARTx_RX_DMA_STREAM, ENABLE);

// USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE);

  /* Enable the USARTx Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

/* Enable the USARTx DMA Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = USARTx_DMA_RX_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

  /* Enable USART */

  USART_Cmd(USARTx, ENABLE);

//   DMA_ITConfig(USARTx_RX_DMA_STREAM, DMA_IT_TC, ENABLE);

// /* Enable Rs232 RX Interrupt */

//   USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);

}

-------

When the micro powers on, at first the RS232 interrupt is enabled and then after 1 second it starts sending characters 

Posted on March 25, 2013 at 13:47

I might have ordered that a bit differently.

Make sure you wait of TXE before sending initial char.

Confirm diagnosis with better terminal app, like RealTerm in hex mode.

Confirm diagnosis with analyzer/scope to see if issue is actually with transmitted data, and not receiver side.

Consider sending a junk byte at initialization.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lorbek
Associate II
Posted on March 25, 2013 at 14:14

I'm already sending a junk byte before the real string, but I don't like this solution.

I don't see this behaviour in debug mode.

I am sure that the issue is with transmitted data.

I also tried to wait more time before starting sending bytes.

Any idea?

Posted on March 25, 2013 at 15:36

''

I don't see this behaviour in debug mode

.''

 

What, exactly, do you mean by that?

There is a clue there:  you need to think carefully about the difference(s) between running in ''debug mode'' (whatever that may mean in your particular case) and ''non-debug'' mode...

Also pay attention to clive1's suggestions...
lorbek
Associate II
Posted on March 25, 2013 at 15:52

Debug mode = Running code in a debug session.

I paid attention to clive1's suggestions, as I said before, I am sure that the trouble is in TX and the pin TXE is enabled.

Posted on March 25, 2013 at 17:06

I can run this code at 115200 8N1, and get the string I want to see

int main(void)
{
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
USART1_Configuration();
puts(''FLASH Test'');

...


 int fputc(int ch, FILE *f)
 {
 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
 USART_SendData(USART1, ch);
 return(ch);
 }

Not doing anything clever with the USART1, running directly from a flashed image. If it is a receiver side framing issue, you could use 2 stop bits, and see if that helps. I'd need to see the analyzer output to convince me there is an issue with the TX side of the STM
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
lorbek
Associate II
Posted on March 26, 2013 at 16:54

Thanks, it works. 

I took the ''fputc'' definition from an example, and I saw the same in tens of other examples. 

Here you swapped the ''while'' and ''USART_SendData'' positions, how can it affect the behaviour of a transmission?

Thanks

Posted on March 26, 2013 at 17:32

Yeah, there are a lot of bad examples out there.

You really need to forward test the Transmit Empty flag, not doing so will potentially destroy the currently pending content of the holding register if the data register is blindly written.

It's also more efficient to do this, if the register is empty you can immediate send the character and leave. If it is busy you wait just long enough for the holding register to be moved to the shift register.

I've seen people also use the TC (Transmit Complete) flag, this is the most inefficient as it waits for the last bit of the current data to be shifted out, assume TXE would flag 9-10 baud clocks earlier.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..