This short video will explain how the system timer work.
The system timer, also called System Tick or SysTick, is to generate SysTick interrupts
at a fixed time interval.
Here I give two example applications of the system timer.
The first example is that the system timer can measure time elapsed.
For instance, software can use the system timer to implement a time delay function.
The second example is that we can execute some specific tasks periodically.
For instance, we can use system timer to implement periodic polling to check peripheral status
or read external inputs with a regular timed interval.
In addition, operating systems rely on the system timer to implement CPU scheduler.
In order to support multitasking and improve the CPU utilization, the CPU scheduler periodically
selects a new process from the ready queue to run next.
The system timer is a standard hardware comp1nt built into ARM Cortex processors.
Almost all ARM Cortex processors have the system timer comp1nt.
If enabled, the system timer can periodically generate SysTick interrupt requests.
The Nested Vectored Interrupt Controller (NVIC) monitors and handles all interrupt requests
based on their priority levels.
For SysTick interrupts, NVIC forces the core to execute, the interrupt service routine
named SysTick_Handler().
The system timer is a 24-bit down counter.
The counter decrements from the reload value to 0.
After the counter reaches 0, the system timer copies the reload value stored in the reload
value register.
Then, the system timer starts to count down again.
This diagram shows, how the counter value change, when the reload value is 6.
The reload value is stored in the SysTick load register.
The counter counts down from 6 to 0.
The counter has a total of 7 unique values.
When the counter makes transition from 1 to 0, the system timer generates an interrupt
request.
On the next clock cycle, the counter is re-initialized to 6.
The counter counts down again on subsequent clock cycles.
This counting process repeats.
The interval of the system timer interrupts equals to the reload value plus 1 times the
period of the source clock.
Let's first take a look at the SysTick control and status register.
In this register, only four bits are used, including 1 status bit, and three control
bit.
The status bit is the count flag bit.
The three control bits include the clock source selection bit, the tick interrupt enable bit,
and the timer enable bit.
As discussed previously, the 24-bit counter counters down from the reload value to 0.
When the counter decrements from 1 to 0, the count flag is set to 1.
Now, let's take a look at the control bits in the SysTick control and status register.
First of all, the clock source bit, selects the clock source for the counter.
If the clock source bit is 1, the processor clock is selected.
If the clock source bit is 0, the external clock is selected.
For STM32L4, the processor clock is the AHB clock.
The external clock is the AHB clock slowed down by a frequency divider 8.
Next, let's take a close look at the enable bit.
Software can set or clear this bit to enable or disable the system timer.
Specifically, the enable bit can enable or disable the clock signal by using this and
gate.
If the enable bit is 1, the system timer is enabled, because the signal of the clock source
can pass through the AND gate.
The interrupt enable bit (TICKINT) enables the interrupt.
A SysTick interrupt request is generated, if both the interrupt enable bit and the Count
flag bit are 1.
In other words, if the interrupt enable bit is 1, a SysTick interrupt request is generated,
every time the time counter decrements from 1 to 0.
The system timer is controlled by four registers, including the control and status register
we just described, the reload value register (SysTick_Load), the current-value register
(SysTick_VAL), and the calibration register (SysTick _CALIB).
Next, we will take a close look at these registers.
Even though the reload value register has 32 bits, the top 8 bits are not used.
It can hold a 24-bit value, with a maximum value of FFFFFF in hex, or 16,777,215 in decimal.
The counter counts down from the reload value to 0.
Writing 0 to the reload value register disables the counter on the next wrap, independently
of the timer enable bit (TICKINT).
The SysTick counter logic maintains this counter value of 0 after the wrap.
The interval of two consecutive SysTick interrupts is reload plus 1 times the source clock period.
For example, if 100 clock cycles are needed between two consecutive SysTick interrupts,
the reload value should be 99.
Here is the, current value register.
Reading this register returns the value of the counter, at the time the register is accessed.
When the counter makes a transition from 1 to 0, the system timer generates a SysTick
interrupt.
Writing any value to the current value register, clears this register, and also clears the
COUNTFLAG bit in the control and status register.
This causes the system timer to reload from the reload value register, on the next timer
clock.
Writing to the current value register does not trigger SysTick interrupts.
Pay attention.
The counter has a random value on reset.
Therefore, software should always clear the counter to 0 in the initialization code.
This can be achieved by writing 0 to the current value register.
The SysTick calibration register is a read-only register.
It contains the value TENMS, which holds the reload value yielding a period of 10 milliseconds.
TENMS stands for ten milliseconds.
However, many chips do not implement this feature, or have a different definition in
this field.
For example, STM32L4 defines this field as the reload value for 1 millisecond, instead
of 10 milliseconds.
Here is the example code, which initializes and enables the system timer.
First, software disables SysTick by clearing the control and status register.
Then, software initializes the reload value register, based on the function's input
argument ticks.
In order to have N ticks between two consecutive SysTick interrupts, the reload value should
be N minus 1.
Next, we give the SysTick interrupts the largest priority value, making the systick interrupt
the least urgent.
Then, software clears the current value register.
The SysTick counter has a random value on reset.
Software should always clear the counter during the initialization.
Then, we select the processor clock as the source clock of the SysTick counter.
We can use either the processor clock or the external clock.
After that, software has to enable the SysTick interrupts, by setting the TICKINT bit in
the control and status register.
At the end, software enables SysTick by setting the enable bit to 1 in the control and status
register.
This example demos, how to use the SysTick to implement a delay function.
We first define a global, volatile variable, named TimeDelay.
The interrupt service routine of system timer, SysTick_Handler(), decrements the TimeDelay
variable by 1, each time a SysTick interrupt takes place.
The Delay function initializes the TimeDelay variable, and waits until TimeDelay is decremented
to 0 by SysTick_Handler().
Suppose the clock source that drives the timer counter has a frequency of 80 MHz.
We want to generate a SysTick interrupt every 10 milliseconds.
What is the reload value?
Here is the diagram of SysTicks.
This is the clock signal, which has a frequency of 80 MHz.
A SysTick interrupt is generated every 10 milliseconds.
An interrupt is generated when the counter makes the transition from 1 to 0.
It takes a total of reload plus 1 cycles to count down from the reload value to 0.
The reload value is calculated in this way.
Reload value equals to 10 milliseconds divided by the clock period minus 1.
This is equivalent to 10 milliseconds multiply the clock frequency minus 1.
The final result is 799999.
Please visit the book website for tutorials and project templates.