1:系统滴答定时器Systick
Systick简介
SysTick—系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bit的向下递减的计数器, 计数器每计数一次的时间为1/SYSCLK,例如CPU频率为4000000,那么跳动4000000代表过去1s.当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。
因为SysTick是属于Arm Cortex-M内核的外设,所以所有基于Arm Cortex-M内核的单片机都具有这个系统定时器,使得软件在Arm Cortex-M单片机中可以很容易的移植。 系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。
Systick寄存器
Systick一般如下有四个寄存器.
| 地址 | Name |
|---|---|
| 0xE000E010 | SysTick控制及状态寄存器 |
| 0xE000E014 | SysTick重装载数值寄存器 |
| 0xE000E018 | SysTick当前数值寄存器 |
| 0xE000E01C | SysTick校准数值寄存器 |
SysTick控制及状态寄存器(地址:0xE000_E010)
表资料来源:ARM-Cortex-M3权威指南,ARM-Cortex-M0权威指南
| Bit | 名称 | 类型 | 复位值 | 描述 |
|---|---|---|---|---|
| 16 | COUNTFLAG | R | 0 | 如果在上次读取本寄存器后,SysTick 已经数到 了 0,则该位为 1。如果读取该位,该位将自动清 零. |
| 2 | CLKSOURCE | R/W | 0 | 0=外部时钟源(STCLK) 1=内核时钟(FCLK) |
| 1 | TICKINT | R/W | 0 | 1=SysTick 倒数到 0 时产生 SysTick 异常请求 0=数到 0 时无动作. |
| 0 | ENABLE | R/W | 0 | SysTick 定时器的使能位. |
[!NOTE]
值得注意的是,CLKSOURCE位表示时钟来源,但是不同公司在使用ARM内核会将外部时钟源接在不同时钟中,内核时钟一般会接在系统频率(CPU频率中).例如stm32f103x系列,将外部时钟源接AHB时钟(HCLK)8分频后作为Sysitck系统外部时钟源.无论是ST或者是其他公司的产品,大多情况下只使用内核时钟就可以.所以在使用stm32f10x时,可以认为CLKSOURCE位,0=AHB/8,1=CPU时钟.
RCC通过AHB时钟(HCLK)8分频后作为Cortex系统定时器(SysTick)的外部时钟。通过对SysTick控制与状态寄存器的设置,可选择上述时钟或Cortex(HCLK)时钟作为SysTick时钟.---原文来STM32F10xxx参考手册.
SysTick重装载数值寄存器(地址:0xE000_E014)
| 位段 | 名称 | 类型 | 复位值 | 描述 |
|---|---|---|---|---|
| 23:0 | RELOAD | R/W | 0 | 当倒数至零时,将被重装载的值. |
SjysTick当前数值寄存器(地址:0xE000_E018)
| 位段 | 名称 | 类型 | 复位值 | 描述 |
|---|---|---|---|---|
| 23:0 | CURRENT | R/Wc | 0 | 读取时返回当前倒计数的值,写它则使之清零, 同时还会清除在SysTick控制及状态寄存器中的 COUNTFLAG 标志. |
[!NOTE]
SysTick24bit的向下递减的计数器的原因是,SysTick当前数值寄存器和SysTick重装载数值寄存器均为24Bit有效位,所以在设置CURRENT和RELOAD的值时,不应将所设置的值大于24bit(0~16777214).
SysTick校准数值寄存器(地址:0xE000_E01C)
| 位段 | 名称 | 类型 | 复位值 | 描述 |
|---|---|---|---|---|
| 31 | NOREF | R | - | 1=没有外部参考时钟(STCLK 不可用) 0=外部参考时钟可用. |
| 30 | SKEW | R | - | 1=校准值不是准确的 10ms 0=校准值是准确的 10ms. |
| 23:0 | TENMS | R/W | 0 | 10ms 的时间内倒计数的格数。芯片设计者应该通 过 Cortex-M3 的输入信号提供该数值。若该值读 回零,则表示无法使用校准功能. |
关于校准数值寄存器,手册中只写了这么多描述,也没有细致的去做实验研究,打算大多情况下不会用到该寄存器.
如何使用SysTick
Systick使用简述
在MSPM0系列芯片中明确说明了如何使用Systick,
Application software must only use 32-bit word-aligned word accesses to the SysTick registers. To initialize the SysTick, follow the steps below:
- Program the desired reload value (example: to generate a flag every 1000 MCLK cycles, program 999) to SYST_RVR
- Clear the current value by writing to the SYST_CVR register
- Program the SYST_CSR register to enable SysTick
机翻+个人理解为.
在使用软件配置时必须使用32为字节对齐访问Systick寄存器,若要初始化Systick,请按照以下步骤操作:
1:将所需重新加载的值写入重装载数值寄存器中,(例如每1000个MCLK周期生成一个标志,程序中写入999)
2:通过写入当前数值寄存器清除当前值.
3:对控制及状态寄存器进行编程启用Systick.
一般有两种使用方法,一种是设定固定时间.将预设时间写入重装载数值寄存器然后在控制及状态寄存器中打开中断,在中断中处理时间到了的程序.另一种为不开启中断,将装载数值寄存器写入数值,清空当前数值寄存器.然后程序一直查询控制及状态寄存器中16位(COUNTFLAG)是否为1,若为1则代表时间到,这种方法一般作为Delay函数提供更准确的延时时间.
STM32使用Systick
在stm32的启动文件中中st公司已经封装好了关于Systick寄存器配置.使用Systick定时器实现堵塞Delay功能不推荐使用此方法写程序,以下程序实现Systick实现固定时间.
/**
* @brief 初始化并启动SysTick计数器及其中断
*
* @param ticks 两个中断之间的滴答数
* @return 1 = failed, 0 = successful
*
* 初始化系统滴答定时器及其中断,并在自由运行模式下启动系统滴答定时器/计数器,以产生周期性中断。
*
*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* 检查传入的参数是否超出预设 */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* 设置重载寄存器 */
// 配置中断优先级为 1<<4 -1 = 15,优先级为最低
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* 设置Cortex-M0系统中断的优先级 */
SysTick->VAL = 0; /* 清零当前计数器寄存器的值 */
// 配置systick 的时钟为内核时钟
// 使能中断
// 使能systick
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* 启用SysTick IRQ和SysTick定时器 */
return (0); /* Function successful */
}
/*该程序延时了在CPU频率为72Mhz情况下启用Systick并定时1ms.
*实现主程序1ms循环
*
*/
uint8_t u8_Systick_1ms;
int main(void)
{
SysTick_Config(72000); //配置Systick相关寄存器.
while(1)
{
if(1==u8_Systick_1ms){
LED_Toggle; //演示用
}
}
}
//函数:SysTick中断服务处理
//st的所有中断函数都在startup_stm32f10x_hd.s复制名字即可.
//Systick自动重装,无需程序操作.
void SysTick_Handler(void)
{
u8_Systick_1ms = 1;
}
浙公网安备 33010602011771号