-
Notifications
You must be signed in to change notification settings - Fork 154
Time
Time on the ch32v003 is kept by the SysTick counter (32bit).
By default, SysTick will operate at (SYSTEM_CORE_CLOCK / 8) = 6MHz
.
To unlock 48MHz, you need to #define SYSTICK_USE_HCLK
before including ch32v003fun.h
and call the SETUP_SYSTICK_HCLK
macro once afterwards.
formula | 6MHz | 48MHz | |
---|---|---|---|
rollover | ((2^32)-1)/f | 715s | 89.5s |
time resolution | 1/f | 167ns | 20.8333...ns |
To handle rollover correctly, it is recommended to keep all the times in your program in Ticks since the lack of division allows for correct rollover of subtraction and addition.
To calculate how many ticks lie between two events, you can use us * DELAY_US_TIME
or ms * DELAY_MS_TIME
.
Alternatively, the Ticks_from_Us(n)
and Ticks_from_Ms(n)
may be used, they achieve the same.
If the interval is known at compile time, no multiplication will need to take place on the micro controller at all:
#define INTERVAL_EVENT Ticks_from_Us(817)
There are four ways to use SysTick to keep time.
uint32_t future_event = 0;
if (((int32_t)SysTick->CNT - future_event) > 0) {
// do something
future_event = SysTick->CNT + interval;
}
The trick here is that both SysTick->CNT
and future_event
are uint32_t
, while the calculation is performed as int32_t
via typecast, resulting in correct rollover behavior.
Additionally, the compiler knows optimized instructions for comparisons against 0.
Most will know this method from Arduino.
uint32_t last_time = 0;
if ((SysTick->CNT - last_time) > interval) {
}
The trick here is that, when SysTick->CNT
rolls over, so does the subtraction and the result is correct again.
You may rig SysTick to fire an interrupt at a specified tick.
SysTick->CMP = SysTick->CNT + interval
This requires that you provide an ISR that does something.
You may also increment a variable every us or ms from the SysTick ISR.
uint32_t millis = 0;
And in the SysTick ISR:
SysTick->CMP += DELAY_MS_TIME;
millis++;