2016-07-06 07:12 AM
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 dataDevice 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\n4800 br
(seen on uart buffer)
1 frame on 2, data lacking in
red
: 05 03 10 1122 0004 0004 3344 5566 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
\n19200
br
(seen on uart buffer)
every frame,
data lacking in
red
: 0
5
03
10
11
22
00
04
00
04
33
44
55
66
77
88
99
AA
0011
28
\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... 🙂Guillaume2016-07-06 07:28 AM
>- 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.
2016-07-06 07:48 AM
2016-07-06 07:51 AM
double post
2016-07-06 07:56 AM
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 buffer2016-07-06 10:12 AM
>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.
2016-07-06 10:27 AM
>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.
2016-07-06 10:32 AM
> Albeit many RS485 transceivers are only half-duplex, ...
Good guess. The MAX3485 is half-duplex anyway.
2016-07-07 01:05 AM
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.