2
\$\begingroup\$

1) How do you determine the baud rate that you want for your application while considering the clock of the MCU?

Baud rate = number of bits / second. The most common baud rates used are:

  • 9600 = up to 9600bps = 104uS per bit

2) So if I were to send out a data stream higher than 9600Hz, I would be better off using a baud rate higher than 9600 to avoid data corruption? I feel there's more to it than just that.

3) if we use USART with a clock, isn't data sampled at each clock pulse (rising/falling etc)? If you've got a 16MHz MCU clock, meaning you're putting out clock pulses every 62.5ns, and if you were to use a baud rate of 9600 for data, how do 104us and 62.5ns work out? Or as long as I'm using a faster clock than the TX data speed, I'm good cause MCU is capable of sending as fast as the clock?

4) What's the essence of oversampling (8,16) of the data on the RX side? if the baud rates are the same on both TX and RX, the data received is at the same speed as it's being sent. Or it has more to do with external noise that might corrupt the data? Even then, where does parity come into play then?

Follow up:

4.1) why are 3 middle out of the N samples are sampled and considered for noise detection, as shown in the image? enter image description here

4.2) With oversampling, you're technically reducing the resultant baud rate since you're taking only three samples?

4.3) Does oversampling by 8 have more receiver tolerance to clock deviation cause it generates a higher speed than oversampling by 16 mechanism?

\$\endgroup\$
11
  • \$\begingroup\$ For how clocks work out in STM32s I strongly suggest downloading CubeMX and looking at the clock tree diagram in the app - this will show you how specific frequencies are generated. \$\endgroup\$ – Jan Dorniak Apr 19 '20 at 20:56
  • 1
    \$\begingroup\$ Always go as fast as you can. I recommend 115200 because sometimes that is the highest standard baud rate that is generally accepted by every device. The baud rate does not depend on how many X you oversample. That is just a noise reduction strategy. It does help with speed mismatch but devices with quartz oscillators are not going to have much speed mismatch anyway. \$\endgroup\$ – mkeith Apr 19 '20 at 21:03
  • \$\begingroup\$ @mkeith - if baud rate isn't affected by oversampling, then what does this formula indicate then? imgur.com/a/B2TNOBq \$\endgroup\$ – xyf Apr 19 '20 at 21:11
  • \$\begingroup\$ The baud rate is the baud rate. If it is 9600 then it is 9600. You can sample it as many times as you want but the TX waveform will still have one bit every 1/9600 seconds during the data part. There is still the start and stop conditions to consider and parity (rarely used). But if you are using 9600 baud, then no matter what sampling you use, the data rate is not affected. I didn't write that equation and don't know what all the terms are. It looks like it is designed to calculate baud rate from register settings on a specific processor. \$\endgroup\$ – mkeith Apr 19 '20 at 21:19
  • \$\begingroup\$ I agree with whatever you said about baud rate, and to me it doesn't make for oversampling to affect baud rate either but I'm trying to get an understanding of this equation which clearly is a function of OVER8 \$\endgroup\$ – xyf Apr 19 '20 at 21:21
3
\$\begingroup\$

1) There's only two points, how much data you must send within some given time frame, and which baud rates your microcontroller is capable of with the master clock they have. Some have only simple baud rate generators that divide with an integer, some have more complex ones that have a fractional baud rate generator. For example, an AVR running at 4 MHz crystal can't go up to 38400 baud unless you switch the oversampling from 16x to 8x with U2X bit. Even then, the baud rate will be 0.16% off from 38400 baud, but the error is insignificant.

2) You can't send more bits per second than what your bits per second rate is! It defines the rate of bits you can send. If you need to send more, then increase baud rate.

3) Synchronous serial does use a bit clock for the data. But it does not mean that a 16 MHz CPU uses 16 MHz clock for everything. You can still use a divided down baud rate clock for example for 9600 baud rate, just as you would with only an internal clock except it stays within the chip and does not come out.

4) Baud rates have to match, but only to a certain degree that is within tolerance limits. By oversampling you have only one sixteenth of time difference between the sampled start bit edge and the real received edge, so you can start counting when to sample the middle of the data bits. So the clocks only need to be sufficiently close to each other during transmission of one byte, and depending on a lot of factors, it does not need to be more than 1% to 2% percent accurate. Which means devices with less precise clocks can be used and make them cheaper.

4.1) That is how it is in general done. Sample the middle, but to avoid a spike of noise just at the sampling moment, majority logic takes in 3 samples and gives out the result.

4.2) Of course you could change oversampling from 16 to only 8, but then you need tighter tolerance baud rate clocks, because you can be almost up to one eighth of a bit already wrong when detecting the start bit edge, instead of only one sixteenth. The sampling of three bits is for combating a noise spike at the sampling instance, if there would only be one sampling instance.

\$\endgroup\$
5
  • \$\begingroup\$ 1) aren't you able to go up ~42KHz baud rate with oversampling of 16 for 4MHz clock? div = 4M/(16*38400) ≈ 6. baud = 4M/(6*16)=41666. it's just error difference 8% whereas with oversampling of 8, it's 0.15%. So I don't know if it's legit to say you can't reach a baud rate of 38400 with 4MHz clock at 16x oversampling. 2) sure, but the baud rate is constrained by clock, isn't it? 4.2) okay so the idea behind 8x oversampling having more error difference b/w sampled and actual clock edge than 16x is cause you could be 1/8 apart than 1/16 in case of 16x oversampling. \$\endgroup\$ – xyf Apr 21 '20 at 0:03
  • \$\begingroup\$ okay just realized I rounded off the value wrongly, so instead of 6, it should be 7 and then I get 35714, which indeed is smaller than 38400 \$\endgroup\$ – xyf Apr 21 '20 at 0:22
  • \$\begingroup\$ Yes with 4 MHz clock you can reach or go up to 250kbps with 16x and up to 500kbps with 8x if you like. But with 16x mode and 4MHz clock, you can't get within tolerance limits for 38400 to work. With 8x you can. \$\endgroup\$ – Justme Apr 21 '20 at 0:49
  • \$\begingroup\$ so oversampling rate is a deciding factor as to what baud rate you could be using. like you mentioned, if you need 500kbps with 4MHz clock, you can't use 16x oversampling. don't you have lesser deviation from the actual clock with 16x than with 8x though? \$\endgroup\$ – xyf Apr 21 '20 at 15:09
  • \$\begingroup\$ Because for integer divisors, the baud rate changes in larger steps when using the 16x sampling, than with 8x sampling, so with some rates, you can get closer to nominal baud rate. But because 8x oversamples less, it tolerates less error between devices. \$\endgroup\$ – Justme Apr 21 '20 at 19:19
1
\$\begingroup\$

1) How do you determine the baud rate that you want for your application while considering the clock of the MCU?

Usually the baud rate you pick is determined by the following factors. a) The device you are connecting to. It may only support certain rates, and you must use one of those.

b) The length of the cable. Longer cables may only work with slower baud rates, controlled impedance cables, and termination.

c) Baud rate accuracy. Usually the bit timing needs to be better than ±5% to avoid bit errors. You can always achieve this if your baud rate divisor is at least 20. There is an exception to this if your clock source happens to be a close to a multiple of the baud rate. In that case you might get very accurate timing even with faster baud rates.

2) So if I were to send out a data stream higher than 9600Hz, I would be better off using a baud rate higher than 9600 to avoid data corruption? I feel there's more to it than just that.

a) At a minimum, your baud rate should be fast enough that you can send all your data as fast as it comes in. You should probably add in some margin to account for the fact that your MCU must actually process the data.

3) if we use USART with a clock, isn't data sampled at each clock pulse (rising/falling etc)? If you've got a 16MHz MCU clock, meaning you're putting out clock pulses every 62.5ns, and if you were to use a baud rate of 9600 for data, how do 104us and 62.5ns work out? Or as long as I'm using a faster clock than the TX data speed, I'm good cause MCU is capable of sending as fast as the clock?

The MCU hardware would usually use the faster 16MHz clock to look for the falling edge of the start bit. After that it would use a delay (based on your baud rate divisor) to sample the center of each data bit and sample at that point. For example divisor was 10 then the MCU would wait for 16 * 1.5 * 10 clock cycles and then sample the next bit. After that point, it would wait 10*16 clocks to sample the next bit and so on.

4) What's the essence of oversampling (8,16) of the data on the RX side? if the baud rates are the same on both TX and RX, the data received is at the same speed as it's being sent. Or it has more to do with external noise that might corrupt the data? Even then, where does parity come into play then?

a) The 16X 8X (or even 4X) are not really over-sampling. They are just a multiplier that is added to the baud rate divisor. The MCU just samples each bit once (or three times) near its center. The only exception to that is start bit edge detection, which may be done at the full clock rate.

b) The historic reason for using 16X is that the 16550 UART chips used that.

b) Baud rates are often much slower than MCU clock rates. This makes sense because the MCU usually needs multiple clock cycles to process each byte, even if that processing is as simple as putting them in a buffer to process later. Baud rates near the MCU frequency are rarely usable, so putting a divisor up front allows for a wider selection of baud rates using the same 8-bit or 16-bit divisor.

c) The UART hardware itself needs some clock cycles to process each bit (this includes having three separate clock cycles when using the 3X sampling mode).

d) This allows for more accurate edge detection with low baud rate divisors. For example, using a baud rate divisor of 1 in 16X mode allows you to detect the edge of the start bit to within 6.25% of a bit time. Using a 4X would allow detection to within 25% of a bit time. On the other hand, when using large baud divisors (say 100) the difference between using 4X vs 8X vs 16X mode become negligible for edge detection purposes.

4.1) why are 3 middle out of the N samples are sampled and considered for noise detection, as shown in the image?

Any tolerance in the clocks causes the sample point to drift left or right. Bits are sampled near the center because it allows the system to work with the highest clock tolerances. Sampling anywhere else would require more accurate baud rates. Sampling three times near the center does create some noise immunity for high frequency noise.

4.2) With oversampling, you're technically reducing the resultant baud rate since you're taking only three samples?

No, the baud rate remains the same. Its not three bits being sampled, its the same bit being sampled three times.

4.3) Does oversampling by 8 have more receiver tolerance to clock deviation cause it generates a higher speed than oversampling by 16 mechanism?

a) Using an 8X over multiplier allows you to use a higher baud rate divisor, so you can potentially get more accurate timing. For example, to make 115200bps at 16X with a 16MHz clock you would need a baud rate divisor of 8.68. Since you can only pick integers, picking 9 yields 111111bps (3.6% error). At 8X you would need a divisor of 17.36. Picking the nearest integer, 17, yields 117647bps (2.1% error).

b) Alternatively, it can allow you to achieve higher baud rates. For example, at 16X with a 16MHz clock you are limited to 1Mbps. At 8X you could go as high as 2Mbps.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ I'd like to correct at least one wrong claim. The 16x really is oversampling, not a raandom multiplier. The receive data line really is sampled at 16 times faster clock than the baud rate, to determine the edge of start bit at higher resolution and thus being able to sample the data at the three midde clocks of the 16 clocks that the single bit lasts. Also the 8x sampling mode is mainly there to achieve 2x higher baud rates which would not be possible to achieve at 16x sampling mode at all. It will tolerate somewhat less error in the baud rate in 8x mode. \$\endgroup\$ – Justme Apr 19 '20 at 22:30
  • \$\begingroup\$ Even the corrected answer to 4.3 has issues. STM32 is not limited to integer divisors. It has a fractional baud rate generator. So divisor of 8.6875 is possible. At 16 MHz clock, and with 16x oversampling, it can achieve baud rate of 115108, which has only 0.08% error. Some other MCUs only support integer divisors. \$\endgroup\$ – Justme Apr 20 '20 at 6:32
  • \$\begingroup\$ Where are you getting 8.6875 from? USARTDIV = 16e6/(115200*16) = 8.68055556. Does the fractional baud rate generator take up to 2 decimal places? (that's what I've seen in the examples). other than that, what could cause deviation in baud rate with fractional bit generator? @Justme \$\endgroup\$ – xyf Apr 26 '20 at 3:06
  • \$\begingroup\$ @xyf You should be able to find such information in the reference manual. The value is taken straight from the baud rate tables in the reference manual of your MCU. The reference manual also explains that the fractional baud rate generator has four fractional bits so it can specify divisors with precision of 1/16 in decimal in 16x mode and with 1/8 precision in 8x mode. \$\endgroup\$ – Justme Apr 26 '20 at 7:01
  • \$\begingroup\$ I was trying to get the math right. I know there’s a table that enlists actual/desires Baud rate for different peripheral clicks and oversampling. So one of them is for 9600bps at 8MHz with 16x oversampling. DIV=8MHz/(9600*8) = 104.16666. Baud = 8M/(104.16666*8) = almost 9600.000. \$\endgroup\$ – xyf Apr 26 '20 at 7:14
1
\$\begingroup\$

4) What's the essence of oversampling (8,16) of the data on the RX side? if the baud rates are the same on both TX and RX

They are not the same rates and that is the point.

Even if both sides were using a 1.843200 MHz or a multiple of, there would be error as no two crystals are exactly the same and they are affected by temperature, etc. Just put two on the same scope at the same time, trigger on one and watch the other drift. It is generally more of a problem for ethernet than uart, but depends on how you are using the uart (rarely would you have a problem). And the (clock drift) problem is related to long periods of sustained data not so much trying to get from one edge to another on the receiver.

It is more of a case that say 8000000/(16*115200) = 4.34. 4 * 115200 * 16 = 7372800. 8000000 / (16*4) = 125000. So you think you set for 115200 but instead 125000. The other side may for the same reasons be set for some other speed, like lets say 115200. 8.68 us vs 8.00 us. or 0.5425 vs 0.5 per sample at 16x. should be able to survive 10 bit cells (8N1). 125000/115200 = 1.08

What about 12000000/(16*115200) = 6.5...so we put 7 in there 12000000/(16*7) = 107142. 125000/107142 = 1.1666. 17 percent difference. 16x will be able to track the mid bit cell of the incoming better than 8x (naturally the higher the oversampling the better) and adapt adjust sooner (assuming there are edges close enough together).

If you were to just go straight 1x mid bit cell of your divided clock you can see where you can start to get into trouble, the higher the oversampling the better. The receiver can only adjust where there are edges, so if the payload is all zeros or all ones then you cant have it drift more than a half bit cell over that period otherwise the receiver will sample at the wrong place and be one bit short or long (relative to the clock that generated it). Then depending on what is on the line next determines if the receiver sees a fault or keeps going because of what is coming in. Eventually and periodically it should fault when it doesnt see a start or stop bit in the right place. 2x, 4x, 8x ... gives you more tolerance of drift relative to your clock and the other side (since they are assumed to not be going the same speed).

The 8x is simply so that you can go slower and still have a decent divisor.

16*115200 = 1843200 8x115200 = 921600

Assuming the uart doesnt support fractions:

1843200/(16*115200) divisor of 1 2000000/(16*115200) divisor of 1 3000000/(16*115200) divisor of 2 (rounded up, rounded down is much worse) 115200 vs 125000 vs 93750 <- that is pretty bad

but if that same uart supported 8x as well

1843200/(8*115200) divisor of 2 2000000/(8*115200) divisor of 2 3000000/(8*115200) divisor of 3 115200 125000 125000 <- much higher chance of it working

Much less error at 3MHz using 8x vs 16x a trade off but generally worth it.

That is the bigger problem trying to be solved with the oversampling is that often one or both sides is not on the mark for the rate, they are off by some amount, so even if one side is off and the other isnt or worse they are both off in different directions you want some oversampling to attempt to survive the worst case of a character with no state changes.

16 is best if you can afford it, but 8x will do in a pinch. Where I do see tables (might not be ST might be TI) they are basically computing the above for you, this oscillator this serial bit rate this is the divisor and the error. You should do the above math just like I did where possible when these choices are available. If your divisor gets to be a small single digit number you certainly want to do the math and you may want to re-think that baud rate. Or where possible use a PLL to up the system clock rate if that makes sense for the application so that the uart has a better chance of working. (PLLs introduce jitter which creates issues, but jittery with oversampling and a bigger divisor value is still more accurate and gives better odds).

\$\endgroup\$
4
  • \$\begingroup\$ sorry for the late response. It is more of a case that say 8000000/(16*115200) = 4.34. 4 * 115200 * 16 = 7372800. this rounding off is still valid for MCUs with fractional baud rate generator though? in the examples in the datasheet, I do see USARTDIV has a fractional part and it doesn't get rounded off. though the fractional part is rounded off when computing USART_BRR \$\endgroup\$ – xyf Apr 26 '20 at 2:48
  • \$\begingroup\$ @old_timer There are some flaws in your answer. First of all, an UART only synchronizes its reception to the start of frame, i.e. the falling edge of start bit, not to other bits. Therefore with 8N1 settings one frame is ten bits, or exactly 160 oversampling clocks in 16x mode. From the middle of a bit there is only +/- 8 clocks to the bit edge. Therefore a theoretical maximum baud rate error can be 8/160 or 5%, and in practice it is below 7/160, and the error is generally divided by 2 to allow both devices to have same error tolerance. Which is why many datasheets suggest max error of 2%. \$\endgroup\$ – Justme Apr 26 '20 at 7:17
  • \$\begingroup\$ UART synchronization is implementation defined, I have no access, nor do you I assume, to the source code to this IP therefore we can only guess...And yes the docs may have clues, if the docs were written by the designer or from information directly from the designer and not yet another assumption. \$\endgroup\$ – old_timer Apr 26 '20 at 14:58
  • \$\begingroup\$ "They are not the same rates and that is the point." is the answer, the rest is ideas on how to try to understand that. \$\endgroup\$ – old_timer Apr 26 '20 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.