cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L476ER - USART Frame Error, Overrun, Baudrate issue?

guillaume-dugast
Associate II
Posted on July 06, 2016 at 16:12

Hello all,

Here my system specification:

Device 1:

- STM32L476ER/ZG

- system clock = 4MHz

- tick period = 100ms, (shortest irq possible, just pulling data)

- usart

- Transceiver MAX3485

- modbus master

- expected request = '': 05 03 0001 0008 \r\n''

Line between device 1 and 2:

- rs485 half duplex

- 9600 baud

- 8N1, no flow control

- modbus

- analyzer on it: scanaplus sniffing for rs485 data

Device 2:

- PC

- labview

- modbus slave

- expected response = '': 05 03 10 1122 0004 0004 3344 5566 7788 99AA 0011 28 \r\n''

Here my issues:

1/ the reception is good when I test it with very short response.

2/ when i test it with this response size (number of data 16bit register = 8 --> 43 bytes), i get some error, which defers depend at which baudrate system is configurated:

 message config  message result

  real data

 (seen on analyzer)

 every frame, every data

: 05 03 10 1122 0004 0004 3344 5566 7788 99AA 0011 28 \r\n

  4800 br 

(seen on uart buffer)

1 frame on 2, data lacking in

red

: 05 03 10 1122 0004 0004 3344 556

6 7788 99AA 0011 28 \r\n

  9600

br

 

(seen on uart buffer)

 

every frame,

data lacking in 

red

: 05 03 10 1122 0004 0004 3

34

4 5566 7788 99AA 0011 28

\r

\n

  19200

br

(seen on uart buffer)

 

every frame,

data lacking in 

red

: 0

5

0

3

1

0

1

1

2

2

0

0

0

4

0

0

0

4

3

3

4

4

5

5

6

6

7

7

8

8

9

9

A

A

0011

2

8

\r

\n

The ORE and FE are set as often as data is lacking.

strange no? any idea?

Please note i've changed xtral from 4MHz to 8MHz with no improvement on results.

thanks for helping!!

sorry for my bad english... 🙂

Guillaume

 

8 REPLIES 8
AvaTar
Lead
Posted on July 06, 2016 at 16:28

>- system clock = 4MHz

 

> Please note i've changed xtral from 4MHz to 8MHz with no improvement on results.

 

Does that mean you are running directly with the quartz frequency, without PLL ?

> - tick period = 100ms, (shortest irq possible, just pulling data)

Which interrupt ? I would guess SysTick.

How do you receive UART characters, per interrupt or polling ?

> The ORE and FE are set as often as data is lacking.

The ORE flag tells you that you lost characters, because you missed to read them out in time. Perhaps you need to review your UART reception and processing method.

Presenting some relevant code would be helpful.

guillaume-dugast
Associate II
Posted on July 06, 2016 at 16:48

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6kK&d=%2Fa%2F0X0000000buW%2F0dVW2gIWfIf_wuL8CEfXo7YCZzAjERr7aIkkuZcQvTA&asPdf=false
guillaume-dugast
Associate II
Posted on July 06, 2016 at 16:51

double post

guillaume-dugast
Associate II
Posted on July 06, 2016 at 16:56

corrections to the shown code:

at line 51:

--> sendData((uint16_t)RBF_ring_buffer_pull(&tx_buf));

and line 47:

--> USART1->ISR &= ~ USART_ISR_TXE;  

Note that the code shown is a little bit different from the real code but very very similar.

- I changed the ''usart[id].reg'' by USART1.

- renamed the tx/rx buf for clarity.

the RBF is a ring buffer module.

- the push function puts a char at the end of the buffer

- the pull function read and delete a char at the beggining of the buffer
AvaTar
Lead
Posted on July 06, 2016 at 19:12

>SystemInit() (from system_stm32l4xx.c) is called at startup >by system_stm32l476xx.s,

 

>before calling main.

 

>So I add at the beginning of main: ...

 

I bet the clock setup in SystemInit() is roughly identical to the code you added to main, so it would be redundant in the best case.

The PLL is used, but I don't know from memory what the resulting sysclock frequency is - either consult the reference manual, or check the systemcoreclock variable with the debugger.

AvaTar
Lead
Posted on July 06, 2016 at 19:27

>the RBF is a ring buffer module.

 

>- the push function puts a char at the end of the buffer

 

>- the pull function read and delete a char at the beggining of the buffer

 

Not sure if a ring buffer is the proper abstraction for Modbus ASCII.

The packets have a known maximal length, and distinct start- and stop characters.

I would organize the receive packet-based, and pass on a packet to further processing once the termination character(s) '\r\n' are received.

(In fact, that's the method I implemented it on an industrial PLC.)

 

>  

RBF_ring_buffer_push(&rx_buf,(uint8_t)receiveData());

 

I would check if this function(s) do not call other, lengthy package-analyzing functions. If run in the interrupt context, that could delay other RX interrupts, and cause loss of characters.

RS4_delay()

;

 

Delays are also potentially harmful in the interrupt context.

Albeit many RS485 transceivers are only half-duplex, so send and receive could never occure concurrently. AFAIK, serial Modbus is not full-duplex by definition.

AvaTar
Lead
Posted on July 06, 2016 at 19:32

> Albeit many RS485 transceivers are only half-duplex, ...

 

Good guess. The MAX3485 is half-duplex anyway.

guillaume-dugast
Associate II
Posted on July 07, 2016 at 10:05

thanks for your reply.

- RCC_CFGR is changed so i bet the clock is changed.

- i tried with a linear buffer, buf the same happends

- then i changed the interrupt handler by:

if

(RX_IRQ)

{

RBF_ring_buffer_push()

}

else

{

if

(TX_IRQ)

{

clear_TX_IRQ

if

(TX_BUF_buffer_is_empty == FALSE)

{

RS4_transmit(id);

sendData(TX_BUF));

}

else

{

Disable_TX;

RS4_delay();

RS4_listen(id);

}

}

}

and this works 🙂

what trying to read and write at the same time...

thanks for helping.