2020-03-08 11:20 AM
while (1)
{
GPIOA->BSRR = 0x0040; // PA6
Delay_us(100);
GPIOA->BRR = 0x0040; // PA6
Delay_us(100);
} //while(1)
Hello ST after a lot programming with STM32F103 I startet with the STM32F030 and the STDPERIPH-Lib. Just an "easy example" of using a timer delay to blink an GPIO-Output.
I noticed a strange behaviour on the oscilloscope: Sometimes the timing of the delay switches to a very small delay. First I thougt of som integer overflow effects but when I switched to 32Bit delay function the strange jitter still exists.
After initializing STM32 with 48MHZ only GPIO and TIMER 14 is initialized. I thougt of a watchdog function but this is als disabled . What on earth hits this wrong timing in between the 100us delays???
//##### TIMER 14 Init ########
void TIMER14_Init(void)
{
TIM14->PSC = (uint16_t) 0x47 ; // Prescale 48.000.000 / 48 = 1MHz // Prescale 48
TIM14->ARR = (uint16_t)0xFFFF; //Autoreload 0xFFFF
TIM14->CR1 |= 0x0001; // Timer enable
}
void Delay_us(uint16_t us) // microseconds
{
volatile uint32_t start = 65536; // offset for not running in negative integer
start += TIM14->CNT; // read Counter register
while( ( (TIM14->CNT + 65536 ) - start) < us ); // compare old with new
}
Picture: smaller delay at the timeline center
thanks in advance for your help.
Henry
2020-03-08 11:27 AM
Offcourse the timer prescaler is 47 dec and not 0x47 hex for a 1 usecond timer clock. But this doesnt change the jitter problem .
Regards Henry
2020-03-08 02:47 PM
To get good deterministic timing you need to use a timer and its update event interrupt. Don't use HAL callbacks, write your own ISR. Blocking delays like you are using are unnecessay & i bet if you scaled out on the scope you will find some periodicity of the short pulses, which is not jitter.
Don't know if your processor has DMA, but if it does you can use the timer update event to trigger the DMA that could write an alternating on/off pattern to the proper GPIO. So yes, it is possible to blink an led with the core doing nothing....
Try it and let us know what you find!
2020-03-08 03:08 PM
The overflow of the counter is causing the problem. Your offset to avoid negative numbers is not doing what you think it is doing.
void Delay_us(uint16_t us) // microseconds
{
uint32_t start = TIM14->CNT;
while ((TIM14->CNT - start) % 65536U < us);
}
Note that since CNT is volatile, you don't need to declare start as volatile as well.
Edit: changed the code. Pretty sure this will work, did not test it though.
2020-03-08 03:42 PM
Hello TDK,
thanks a lot. This works without jitter.!!. Well done !!!
There are so many examples in the web, which do not consider timer overflow. I wonder how any of these softwares run strable. Of course most of the time the delay works but the wrong delays inbetween can cause a lot of trouble when needed for pulse shaping or simple display control software.
Regards Henry
2020-03-12 04:19 PM
> I wonder how any of these softwares run strable.
No wonders - they don't.