1-Wire timing using UART different from expected on STM32-476RG.
I made a driver for 1-Wire communication using UART in Single Wire Half Duplex mode.
The communication is started by sending a RESET pulse that should last 480us. I read that to do it using UART I should set it up to 9600 baud, 8N1, then send 0xf0. Long story short - I've done that, all using DMA and interrupts, it works. I communicate with my DS18B20 thermometer with no problems. However - I was curious what goes over the wire and I connected an oscilloscope to the TX line. And I see something weird. My reset pulse lasts exactly 520us instead of 480. Then I see DS18B20 doesn't mind that timing and responds with a presence pulse of 120us, that is read over UART as 0xe0. Then the baud rate is changed to 115200 and everything works. However - that 520us is bothering me. WHY?
BTW, it's stable. The sensor is read continuously, when it finishes the last reading it starts the next one. When the reading differs from the previous one it is sent to another UART as text to show the reading on debugging console. But most of the time - the second UART is not used, since the reading doesn't change. So no other interrupts should interfere, except maybe the timer interrupt used for delay, but the code in the handler only watches the counter and nothing else. Also - the timing difference is constant and stable. It's ALWAYS 520us on each measurement. It seems like it's not the code's fault, at least - not because it lags. Maybe I misunderstood how sending bits via UART with 9600 baud rate translates to the pulse width?
The state machine for UART interrupts works like this:
- set the baud rate to 9600
- TX: 0xf0
- RX: test for 0xe0
- set the baud rate to 115200
That's only the RESET part, then goes the data part, but I'm curious about the reset timing.
EDIT:
OOPS, I did the math, it came out like 520us is what I get from the perfect 9600. It seems like the recommended baud rates were bent to match "standard" UART speeds, but as I can set just anything for my STM32, I set 10416 for REST pulse, and I get the perfect 480us. I set 142857 for the data bits and I get the perfect 70us for a bit. Good to see nothing lags in my code and the UARTS provide exactly what is requested from them. Of course my test 1-Wire sensor works with that slightly higher speeds but now what I see on the oscilloscope is exactly what I would expect.
