处理器有一个23位系统计时器,systick。 它从重载值开始向下计时,记到0时,在下一个时钟周期重载STK_LOAD寄存器的值,并开始新的时钟周期。
Relevant Registers:
相关寄存器:
SysTick control and status register (STK_CTRL)
Address offset:
0x00
Reset value: 0x0000 0000
Required privilege: Privileged
The SysTick CTRL register enables the SysTick features.
此寄存器开启systick的功能。
Bits 31:17 Reserved, must be kept cleared.
Bit 16
COUNTFLAG:
Returns 1if timer counted to 0 since
last time this was read.
Bits 15:3
Reserved, must be kept cleared.
Bit 2 CLKSOURCE: Clock source selection
Selects the clock source.
0: AHB/8
1: Processor clock (AHB)
Bit 1 TICKINT: SysTickexception request enable
0: Counting down to zero does not assert the SysTick exception request
1: Counting down to zero to asserts the SysTick exception request.
Note: Software can use COUNTFLAG to determine if SysTick has ever counted to zero.
Bit 0 ENABLE: Counter enable
Enables the counter. When ENABLE is set to 1, the counter loads the RELOAD value from the
LOAD register and then counts down. On reaching 0, it sets the COUNTFLAG to 1 and
optionally asserts the SysTick depending on the value of TICKINT. It then loads the RELOAD
value again, and begins counting.
0: Counter disabled
1: Counter enabled
bit 0为计时使能位,bit 1位为中断使能位,bit 16位为计数标记位。
SysTick reload value register (STK_LOAD)
Address offset: 0x04
Reset value: 0x0000 0000
Required privilege: Privileged
Bits 31:24 Reserved, must be kept cleared.
Bits 23:0 RELOAD: RELOAD value
The LOAD register specifies the start value to load into the STK_VAL register when the
counter is enabled and when it reaches 0.
Calculating the RELOAD value
The RELOAD value can be any value in the range 0x00000001-0x00FFFFFF.A start value of
0 is possible, but has no effect because the SysTick exception request and COUNTFLAG are
activated when counting from 1 to 0.
The RELOAD value is calculated according to its use:
l To generate a
multi-shot timer with a period of N processor clock cycles, use
a RELOAD
value of N-1. For example, if the SysTick interrupt is required every 100 clock pulses, set
RELOAD to 99.
l To deliver a
single SysTick interrupt after a delay of N processor clock cycles,
use a
RELOAD of value N. For example, if a SysTick interrupt is required after 100 clock
pulses, set RELOAD to 99.
计数重载寄存器
存放0x00000001至0x00FFFFF之间的重载值。用作多发计时器时,将RELOAD值设为所需周期的N-1。
用作单发中断计时是,将RELOAD值设为所需周期。
SysTick current value register (STK_VAL)
Address offset:
0x08
Reset value: 0x0000 0000
Required privilege: Privileged
Bits 31:24 Reserved, must be kept cleared.
Bits 23:0 CURRENT: Current counter value
The VAL register contains
the current value of the SysTick counter.
Reads return the current value of the SysTick counter.
A write of any value clears the field to 0, and also clears the COUNTFLAG bit in the
STK_CTRL register to 0.
计时值寄存器
SysTick calibration value register (STK_CALIB)
Address offset:
0x0C
Reset value: 0x0000000
Required privilege: Privileged
The CALIB register indicates the SysTick calibration properties.
Bit 31 NOREF:
NOREF flag. Reads as zero. Indicates that a separate reference clock is provided.
The frequency of this clock is HCLK/8.
Bit 30 SKEW: SKEW flag: Indicates whether the TENMS value is exact. Reads as one. Calibration
value for the 1 ms inexact timing is not known because TENMS is not known. This can affect
the suitability of SysTick as a software real time clock.
Bits 29:24 Reserved, must be kept cleared.
Bits 23:0 TENMS[23:0]: Calibration value. Indicates the calibration value when the SysTick counter
runs on HCLK max/8 as external clock. The value is product dependent, please refer to the
Product Reference Manual, SysTick Calibration Value section. When HCLK is programmed at
the maximum frequency, the SysTick period is 1ms.
If calibration information is not known, calculate the calibration value required from the
frequency of the processor clock or external clock.
设置参考寄存器,存放设置1ms的参考RELOAD值,为只读寄存器。
在stm32的systick计时器例程中
首先使用SysTick_Config设置计时器,SysTick_Config是一个CMSIS库中的函数,它的功能有
-将函数以参数设置systick重载寄存器,
-将设置SysTick computer IRQ 优先级为最低
-重置SYStick 计数寄存器
-设置Systick为主时钟源(HCLK)
-使能systick中断
-开始systick计数
if (SysTick_Config(SystemCoreClock / 1000))
{
/* Capture error */
while (1);
}
在stm32f4xx_it.c中,systick的中断函数void SysTick_Handler(void)中调用了TimingDelay_Decrement()函数对main函数中的静态变量TimingDelay进行递减
<pre name="code" class="cpp">stm32f4xx_it.c中
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}
main.c文件中
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
void Delay(__IO uint32_t nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
即实现了较为精确的计时。