Skip to main content
mikaeleg
Associate
September 28, 2011
Question

STM32F103T8 usart2 corrupted data

  • September 28, 2011
  • 11 replies
  • 2145 views
Posted on September 28, 2011 at 08:12

Hi,

Im trying to get the usart2 working but for some reason I get random corrupted data when I send message to the STM32F103T8. I can send messages from the STM32 to the computer without any corrupted bytes but not the other way around.

The usart2 is piping the received messages to a DMA. I've activated the usart2 in the following way:

DMA_DeInit(DMA1_Channel6);  

DMA_StructInit(&DMA_InitStructure);

DMA_InitStructure.DMA_PeripheralBaseAddr = USART2_DR_Base;    

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)gRXBuf2;      //Define in usart2.h

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_BufferSize = RX_BUF_SIZE2;               //Define in usart2.h

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;         

DMA_Init( DMA1_Channel6, &DMA_InitStructure );

       USART_InitStructure2.USART_BaudRate = 4800;

   USART_InitStructure2.USART_WordLength = USART_WordLength_8b;

       USART_InitStructure2.USART_StopBits = USART_StopBits_1;

       USART_InitStructure2.USART_Parity = USART_Parity_No;

       USART_InitStructure2.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;

     USART_InitStructure2.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

     /* Configure USART2 */

     USART_Init(USART2, &USART_InitStructure2);

     /* Enable USART2 Receive and Transmit interrupts */

     USART_ITConfig(USART2, USART_IT_TC, ENABLE);

// Enable USART2 Receive DMA requests

USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);

 

// Enable DMA1 USART RX channel

DMA_Cmd(DMA1_Channel6, ENABLE);

    

     // Enable USART2

     USART_Cmd(USART2, ENABLE);

I have also enabled the usart2 clock as following:

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

And finally enabled the usart2 interrupt:

 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

     NVIC_Init(&NVIC_InitStructure);

I've done a simple program which checks when new data have been added to the DMA memory where the received data is and send the exact same data back to the computer.

Then i connect to the STM32 with the windows xp hyperterminal and sends some chars.

For example if i send GPGGA, I might get back something like GP=GA or even worse like G?G, where some chars is ''.

Does anyone have any idea what might be wrong? I would really appriciate the help.

Cheers

Mike

#stm32-stm32f103-usart-corrupted
This topic has been closed for replies.

11 replies

Andrew Neil
Super User
September 28, 2011
Posted on September 28, 2011 at 11:09

''Does anyone have any idea what might be wrong?''

The usual reason is that your baud rate is not (quite) correct - have you checked with a scope to see exactly  what baudrate the STM32 is actually using? 

Is the STM32 reporting any Framing errors?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
mikaeleg
mikaelegAuthor
Associate
September 28, 2011
Posted on September 28, 2011 at 13:25

Thank you for such a fast answer.

Ive checked the framing error but it is never set, and I have also tested different baudrate but the same corruption occurred.

I have more or less the same code for the USART1 but with dma channel 5 and it works perfectly.

I recently discovered something which might be the problem.

I gave the DMA the memory address for a buffer gRXBuf2 which basicly is defined as:

volatile char gRXBuf2[RX_BUF_SIZE2];

The RX_BUF_SIZE2 is defined as 30. I belive that when the usart2 receives data it automaticly goes into the DMA memory, in this case the gRXBuf2, so for example if I send the message ''GPGGA'' then the buffer should look like:

gRXBuf2[0] = 'G'

gRXBuf2[

1

] = '

P

'

gRXBuf2[

2

] = 'G'

gRXBuf2[

3

] = 'G'

gRXBuf2[

4

] = '

A

'

So I tried to send the previous value in the buffer also.

Something like this:

USART2_transmit(''This: '', 6);

      USART2_transmit((char*)&gRXBuf2[gRXBufPtr2], 1);

      USART2_transmit(''\r\n'', 2);

      if(gRXBufPtr2>0)

      {

          USART2_transmit(''Prev: '', 6);

          USART2_transmit((char*)&gRXBuf2[gRXBufPtr2-1], 1);

        USART2_transmit(''\r\n'', 2);

      }

And what I got when i only send a's is the following:

This: ê

This: a

Prev: 

This: a

Prev: �?

This: <

Prev: �?

This:

Prev: <

This:

Prev:

This: €

Prev:

So even the previous value of the buffer changes. Ive searched through all the code and cant find any other places which are using the buffer, so is there maybe a problem with the dma?
Tesla DeLorean
Guru
September 28, 2011
Posted on September 28, 2011 at 14:16

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
mikaeleg
mikaelegAuthor
Associate
September 28, 2011
Posted on September 28, 2011 at 14:52

I tried added:

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

but still same corruption of data.

Tesla DeLorean
Guru
September 28, 2011
Posted on September 28, 2011 at 15:42

Does it work with polled (ie not IRQ or DMA) receive on the same USART?

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
mikaeleg
mikaelegAuthor
Associate
September 29, 2011
Posted on September 29, 2011 at 09:09

Hi again,

Im sorry for the late answer but i tried what you said .

I did a simple program like:

    while(1)

    {

        /* Loop until the USARTz Receive Data Register is not empty */

        while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == RESET)

        {

        }

        

        gRXBuf2[gRXBufPtr2++] = (USART_ReceiveData(USART2) & 0x7F); 

    

        USART2_transmit((char*)&gRXBuf2[gRXBufPtr2-1], 1);

    

        if( gRXBufPtr2 == RX_BUF_SIZE2 )

        {

              gRXBufPtr2 = 0;

        }

    }

and it worked perfectly, so i assume that something is disturbing the dma channel?

mikaeleg
mikaelegAuthor
Associate
October 4, 2011
Posted on October 04, 2011 at 08:26

Just wanted to update this thread as I found the problem.

The problem was that I were on the limits of the memory on the MCU.

So after I reduced some buffers everything worked perfectly.

When you run out of memory, strange things start to happen.
hassankasim84
Visitor II
June 12, 2012
Posted on June 12, 2012 at 14:17

Hii

I had the same problem that you had, can you please tell me how to solve that, Actually I had (chr6dm) module which contain ARM Processor and in this module they used USART1 and now I need to use USART2 for another sensor, I think you also have the same module right ????

hassankasim84
Visitor II
June 12, 2012
Posted on June 12, 2012 at 14:21

I had forgot something what is the (

USART2_DR_Base

) that you used????

Tesla DeLorean
Guru
June 12, 2012
Posted on June 12, 2012 at 15:31

He said he was reading into the wrong memory area or one used by other buffers.

C coders would probably use the following :

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR;

The address is also easy enough to figure from the reference manual.

If DMA isn't working as you expect, go back and try simple polling. For 4800 baud, DMA reception seems like overkill as managing the buffers and handling timely processing of partial buffers is non-trivial. For DMA transmit you at least have quantified amounts of data you can deal with at the TC interrupts.

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