赞
踩
SysTick 是什么?
SysTick:系统定时器,是一个 24bit 的向下递减的计数器(计数器每计数一次的时间为 1/SYSCLK,SYSCLK 为系统的是时钟频率(72M、168M等))。属于 CM3 内核中的一个外设,并且内嵌在 NVIC 中。
SysTick 的特点
SysTick 定时器可以选择不同的时钟源,可以产生中断,并且 SysTick 定时器是一个倒计数的计数器,每隔一个时钟周期计数值减一,计数至 0 后重新从计数初值处开始倒计数。因此,SysTick 也可用作精准延时。 SysTick 定时器在《STM32F10x- 参考手册》里一个屁都没放,只有在《ARM Cortex-M3 技术参考手册》和《ARM Cortex-M3 权威指南》才找到相关寄存器的介绍。
从图中可以看出 SysTick 有两种模式:一种是 8 分频模式(AHB/8),一种是 FCLK 模式(AHB)。AHB 最大频率可为 SYSCLK (在 f1系列为 72M,f4 系列为 168M )。详细参看《STM32F10x 参考手册》。
综上所述,SysTick 是一个 24 位的倒计数定时器,当技术到 0 时,会产生 “滴答” 并 将从 RELOAD 寄存器中自动重装载定时初值。只要 SysTick 控制及状态寄存器中的使能位没有清 0,SysTick 定时器就会一直运行。
在 core_cm3.h 中声明了可使用的 SysTick 的结构体,声明如下:
typedef struct
{
__IO uint32_t CTRL; /*控制和状态寄存器 */
__IO uint32_t LOAD; /*重装载数值寄存器*/
__IO uint32_t VAL; /*当前数值寄存器*/
__I uint32_t CALIB; /*校准数值寄存器*/
} SysTick_Type;
其次,在 core_cm3.h 中,将 (SysTick_Type *) 进行宏定义为 SysTick。方便后面直接访问结构体内相关成员。
SysTick 初始化编程步骤
配置 SysTick 时钟源
固件库函数:SysTick_CLKSourceConfig( );
头文件:misc.h
参数: SysTick_CLKSource_HCLK_Div8 --> AHB 的8分频
SysTick_CLKSource_HCLK --> AHB
配置 SysTick 的重装载值
开 SysTick 中断 以及 开启 SysTick 定时器
SysTick 定时器初始化脑图
SysTick 进行初始化代码
void delay_init(u8 SYSCLK)
{
u32 reload;
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
fac_us=SYSCLK; //不论是否使用 OS,fac_us 都需要使用,即 记录 1us 所需要的节拍数
reload=SYSCLK; //每 1us 的计数次数
reload*=1000000/configTICK_RATE_HZ; //根据 FreeRTOS 中的 configTICK_RATE_HZ设定溢出时间,FreeRTOS 需要每 1ms 的定时器中断,因此设置的重装载数值为 SYSCLK*1000。
fac_ms=1000/configTICK_RATE_HZ; //代表 OS 可以延时的最少单位,在 os 下,代表每个节拍的ms 数
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;//开启 SYSTICK 中断
SysTick->LOAD=reload; //因为加 入FreeRTOS,所以设置为每 1ms 中断一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启 SYSTICK
}
微妙延时函数的实现
void delay_us(u32 nus) // nus:要延时的 us 数 { u32 ticks; // 记录需要延时微妙时间的 节拍数 u32 told,tnow,tcnt=0; u32 reload=SysTick->LOAD; //LOAD的值,重装载的数值 ticks=nus*fac_us; //需要的节拍数 = 需要延时 us 数 * 1us 所需要的节拍数 told=SysTick->VAL; //通过 VAL 寄存器记录刚进入时的计数器值 while(1) { tnow=SysTick->VAL; if(tnow!=told) { if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了. else tcnt+=reload-tnow+told; told=tnow; if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出. } }; }
毫秒延时函数的实现
// 延时 nms,会引起任务调度 void delay_ms(u32 nms) //nms:要延时的ms数 { if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行 { if(nms>=fac_ms) //延时的时间大于OS的最少时间周期,即大于1ms { vTaskDelay(nms/fac_ms); //FreeRTOS延时 } nms%=fac_ms; //OS已经无法提供这么小的延时了,采用普通方式延时 } delay_us((u32)(nms*1000)); //普通方式延时,毫秒延时 = 微妙延时 * 1000 } //延时nms,不会引起任务调度 void delay_xms(u32 nms) //nms:要延时的ms数 { u32 i; for(i=0;i<nms;i++) delay_us(1000); }
【2】Systick定时器
【5】SysTick定时器
【7】《STM32F10x- 参考手册》
【8】《ARM Cortex-M3 技术参考手册》
【9】《ARM Cortex-M3 权威指南》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。