Electronic – Jitter of UART TX pin

clockoscilloscopestm32cubemxstm32l

I'm developing a small robot using the STM32L152C Discovery board. I'm currently trying to configure the board using the STM32CubeMX. I've never worked at this very-low level (my experience is much more about algorithms), therefore I started doing simple things, like sending few characters to the UART port. The board doesn't have an external oscillator. Therefore I'm using the internal RC oscillator.

After doing this I wrote a very easy software that sends continuously a character to the UART port:

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART2_UART_Init();
    unsigned char msg = '@';

    while (1)
    {
        HAL_UART_Transmit(&huart2,&msg,1,1);
    }
}

Using a 100 MHz oscilloscope this is what I get out of the pin:

serial drift

The character that I'm sending is clearly visible, but it seems that the output is something like unstable. I've pressed the AUTO button on the scope many times, but nothing changes.

I thought that maybe it could be a problem with the RC oscillator. After setting the clock frequency to 4.194 MHz (the maximum) with the STM32 configurator, I've measured the clock but the output is not what I would expect.

This is what I get:

Clock measurement using oscilloscope

First I've noticed that the wave is not so "squared", and also the frequency is slightly different: 4.202 MHz instead of 4.194 MHz.

I would like to understand better why I get this output.

Concerning the shape, since the oscilloscope is 100 MHz and the clock has a frequency of ~4 MHz, I guess that the measuring tool is not the issue.
Concerning the frequency, I would say that the problem is in the accuracy of the RC oscillator itself. Can these be the cause of the problem I'm getting on the UART?

Best Answer

So there are a few answers here, I will start from easiest to explain simply (for me anyway) to more fuzzy answers.

First, The wave form you posted is not "squared" due to a couple of factors, namely parasitic electronic effects that are affecting the pin that you are probing such as capacitance, improper grounding to your scope, series resistance on the trace, parasitic inductance and the like. Basically all of these parasitic effects are limiting how fast the pin can change state. A true square wave is impossible in practice since it would require a circuit to change state instantaneously (if that were the case our computers would be running MUCH faster than they do). There is also an added "gotchya" with the STM32 microcontrollers and others where the output drive strength can be changed. That is, you can, in firmware, dictate how much current you are shoving down the pin into the rest of the circuit therefore changing the speed at which it can change state. The code you posted shows no mention of this, so most likely the micro is running at the default 20MHz, which is supported by your scope screenshot (rise time of ~50ns).

Second, You are correct in assuming that the discrepancy in output frequency is due to the internal RC oscillator. enter image description here From the STM32L152C datasheet, page 75, you can see that the internal RC shows a worst case accuracy of -4% to +3% across the operating temperature range, and +/- 1% at room temperature. So (4.202 - 4.194) / 4.194 * 100 = 0.19% difference, which is within spec.

Lastly, The jitter is most likely due to the piss-porr HAL libraries (I know this is not a great explanation, but I have run into so many problems with this b/s since they stopped supporting the SPL library that we have been writing our own HAL in house for the various STM32's). If you look at the HAL code, more often than not they are passing around gigantic and bloated data structures that represent the automatically configured HAL code with every function call. What could normally be done by sending 4 bytes to the appropriate register (a few if not 1 cpu cycles) compiles down to many, many MANY lines of assembly. Combine that with a few ISR's kickin it here and there there is going to be some jitter. The main bottle neck here is how long it takes the processor to grab the next few instructions from flash, its actually a wacky involved process when the processor is doing stuff with pipelined instruction fetches. You can read the Manual for the processor here Section 3. I would try loading your program to the dev board to execute from RAM and see if the problem goes away, if it doesn't then I am being an idiot and completely missing something simple. But my recommendation would be to ditch the HAL libraries if you can, unfortunately ST hasn't released their SPL for the L1 and L4 series of parts, so you may have to do some digging.

Finally... :) Is this even an issue? Can your computer receive the char's correctly or can you decode them with your scope?