4
\$\begingroup\$

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?

\$\endgroup\$
  • \$\begingroup\$ Your clock looks fine for this application. Have you tried single shot on the UART output? It seems you are getting multiple transmissions overlaid. \$\endgroup\$ – David May 16 '17 at 22:15
  • 2
    \$\begingroup\$ There may be no problem at all. UARTs are character-asynchronous. Does loop-back (TX connected to RX) give you problems with wrong characters? \$\endgroup\$ – glen_geek May 16 '17 at 22:37
  • 1
    \$\begingroup\$ I agree no issues displayed. 10% clock error vs baud rate , I recall is limit for 10 bits centre sampled incl,. start /stop Jitter is just the latency on the idle duration. Problem is trigger delay setting. on scope. \$\endgroup\$ – Sunnyskyguy EE75 May 17 '17 at 0:30
  • \$\begingroup\$ Add some idle time between characters and some hold off time on your scope, or trigger on serial decode if available \$\endgroup\$ – sstobbe May 17 '17 at 0:46
  • \$\begingroup\$ this is by design, you only need to be close enough for the other side to work through a character, so your jitter and/or clock speed error can be relatively large. This is an asynchronous interface, so by design the two sides are not expected to use the same clock, thus start bits and stop bits to insure edges that can be used to find the bit cells in the next character. \$\endgroup\$ – old_timer May 17 '17 at 2:56
5
\$\begingroup\$

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?

\$\endgroup\$
1
\$\begingroup\$

Do you see where the trigger point of the scope trace is? It is in the middle of the trace. The jitter is before the trigger and is occurring between one character and the next. This will not affect reception of the character as asynchronous communication does not assume any character to character timing.

If you change your scope setup so the trigger is at the left side and so you can see two characters it will be more obvious what is happening.

Do you have any timer interrupt service routines running? For example in the "SystemClock_Config()" function - does it enable the a periodic timer.

If so there is an ISR that is periodically stealing time away from main() and causing the delay between characters to vary.

\$\endgroup\$

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.