Experimental setup:
STM32F103RB microcontroller, Keil uVision 4.72, USART2 on PA.2, PA.3.
Experiment:
initialize USART for 9600 baud/s, initialize PORTA, initialize SysTick (for delays, interrupt every millisecond)
then:
// delay for 5 milliseconds
1) Delay(5);
// high level on PA.4
2) GPIOA->BSRR = 1<<4;
// fixed length delay
3) for(volatile uint32_t i=0; i<1000; i++){}
// send byte
4) USART2->DR = 0x55;
// wait for transmit complete
5) while(! (USART2->SR & USART_FLAG_TC) );
// clear transmit complete flag
6) USART2->SR &= ~USART_FLAG_TC;
// low level on PA.4
7) GPIOA->BRR = 1<<4;
Here is code for Delay:
volatile uint32_t SystemTime;
void Delay(uint32_t delayTime)
{
uint32_t time = SystemTime;
while((SystemTime - time) < delayTime)
{
continue;
}
}
void SysTick_Handler(void)
{
SystemTime++;
}
Then I looked in my oscilloscope and I saw that time between line 2 (rising edge on PA.4) and start-bit on USART (line 4) is different every time. Jitter was about 150 microseconds.
If I substitide Delay (which uses systick) with an empty for-loop – there is no jitter.
I was startled. After doing some experiments I found that for-loop with fixed length causes no jitter. Even if there is access to SystemTime variable in that loop.
Then I disabled all interrupts and used this for delay:
uint8_t xorshiftRandomByte(void)
{
// seed value
static uint8_t y8 = 1;
y8 ^= (y8 << 7);
y8 ^= (y8 >> 5);
return y8 ^= (y8 << 3);
}
void Delay()
{
uint32_t r = xorshiftRandomByte() * 2 + 5000;
for(uint32_t i=0; i<r; i++)
{
;
}
}
And I saw jitter once again. Jitter between two lines (2 and 4) that DO NOT have a Delay call between them!
Can somebody please explain me what is going on here?
UPD: I tried to check a theory that jitter is caused by “beat” between CPU clock and UART clock. I thought if that’s the case, then there would be some value of delay with which there will be no jitter (cause UART clock cycle will be divided integrally by CPU clock).
And on close to integral division jitter should change slowly.
I saw something like that on oscilloscope. So, I guess, that theory is correct.
But for some reason, only for very specific delays there was no jitter – only if there was a 4 on the end. Like, 4 ms, 14 ms, 24. But not a multiple of 4!
That is weird. What’s so special about that 4? And they are not even multiple of something common.