STM32学习及应用笔记一:SysTick定时器学习及应用

这几年一直使用STM32的MCU,对ARM内核的SysTick计时器也经常使用,但几乎没有仔细了解过。最近正好要在移植一个新的操作系统时接触到了这块,据比较深入的了解了一下。

1SysTick究竟是什么?

关于SysTick在STM32的资料中并没有详细的介绍,这可能由于SysTick是ARM内核的东西。在《STM32F10xxx参考手册》、《STM32F4xx参考手册》以及《STM32F7xx参考手册》中,介绍时钟的时候仅仅是在使用树上简单的画出了HCLK时钟经过8分频后送到了Cortex系统时钟。对这个时钟的描述也非常的简单。在《STM32F10xxx参考手册》中仅仅说:“RCC通过AHB时钟(HCLK)8分频后作为Cortex系统定时器(SysTick)的外部时钟。”同样在《STM32F4xx参考手册》和《STM32F7xx参考手册》中,也只是说:“RCC 向 Cortex 系统定时器 (SysTick) 馈送 8 分频的 AHB 时钟 (HCLK)。”

另外,STM32在中断部分对SysTick也有一句话的描述。如在《STM32F10xxx参考手册》中的“9.1.1 系统嘀嗒(SysTick)校准值寄存器”中提到:“系统嘀嗒校准值固定为9000,当系统嘀嗒时钟设定为9MHz(HCLK/8的最大值),产生1ms时间基准。”而在《STM32F4xx参考手册》的“10.1.2 SysTick 校准值寄存器”一节和《STM32F7xx参考手册》“10.1.1 SysTick 校准值寄存器”一节中也都有:“SysTick 校准值设置为 18750。当 SysTick 时钟设置为 18.75 MHz(HCLK/8,HCLK 设为150 MHz),会产生 1 ms 时间基准。”

仅看这些让我们觉得SysTick似乎都是定好的,但事实上并非如此,因为在库函数中有相关寄存器的操作函数。为了搞清楚这一点,我们必须查看Cortex-M3和M4的手册。在《Cortex-M3权威指南》的“第8章 NVIC与中断控制”中有比较详细的描述。首先很明确SysTick 就是一个定时器;其次SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常,主要适用于操作系统的“心跳”节律。关于SysTick的时钟来源最终还是由芯片厂商决定。

SysTick定时器能产生中断,并且是一个单独的异常类型,并且在向量表中有它的一席之地。并有四个寄存器来控制SysTick,在《Cortex-M3权威指南》中对他们的描述如下:

1)、STK_CSR控制寄存器:寄存器内有4个位具有意义

2)、STK_LOAD 重载寄存器

Systick 是一个递减的定时器,当定时器递减至0 时,重载寄存器中的值就 会被重装载,继续开始递减。STK_LOAD 重载寄存器是个24 位的寄存器最大计数0xFFFFFF。

3)、STK_VAL当前值寄存器

也是个24 位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick 控制及状态寄存器中的COUNTFLAG 标志。

4)、STK_CALRB 校准值寄存器 

2STM32中的SysTick

作为一用于系统级的24位递减计时器,在STM32中又是处理的呢?ST在手册里介绍的比较简单,但在库函数中却有比较清楚的定义。不论是标准库还是HAL库都有较为清楚的定义,如在标准库中就定义SysTick寄存器结构体机器操作函数,在misc.C文件中的SysTick_CLKSourceConfig函数,它是一个时钟源配置函数,其定义如下:

/*@功能:配置SysTick时钟源

*@输入参数:  SysTick_CLKSource:  指定 SysTick 时钟源.

*  该参数可以是以下其中一个值:

* @ SysTick_CLKSource_HCLK_Div8: AHB 时钟 8 分频作为SysTick时钟源

* @ SysTick_CLKSource_HCLK: AHB 时钟作为 SysTick 时钟源. */

void SysTick_CLKSourceConfig(uint32_t Sy sTick_CLKSource)

{

assert_param(IS_SYSTICK_CLK_SOURCE(Sy sTi ck_CLKSource));

if(SysTick_CLKSource ==  SysTick_CLKSource_HCLK)

{

SysTick->CTRL |= SysTi ck_CLKSource_HCLK;

}

else

{

SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;

}

}

由此可见,在STM32中时钟可以设置为HCLK或者HCLK的8分频,根据使用的需求而定。默认不配置的话时钟就是HCLK的8分频。同样在HAL苦衷的定义也是如此。

在core_cm3.h文件中有寄存器定义:

typedef struct

{

__IO uint32_t CTRL;

__IO uint32_t LOAD;

__IO uint32_t VAL;

__I uint32_t CALIB;

} SysTick_Type;

还定义了一个 SysTick_Config 函数

#if (!defined(__Vendor_Sy sTickConfig )) ||(__Vendor_SysTickConfig  == 0)

/**

* @功能  初始化并开启 Sy sTick 计数器及其中断

*@输入参数    ticks    两次中断间的 ticks 数值

*@返回值  1 =  失败, 0=成功

*  初始化系统滴答定时器及其中断并开启系统滴答定时器在自由运行模式下以产生周期中断*/

static __INLINE uint32_t SysTick_Config(uint32_t ticks)

{

if(ticks > SysTick_LOAD_RELOAD_Msk)  return(1);/* 重装值超过了 24 位,是不可能的。返回失败值 0 */

SysTick->LOAD  =(ticks & SysTick_LOAD_RELOAD_Msk) - 1; /*  设置重装载寄存器  */

NVIC_SetPriority(SysTick_IRQn, ( 1<<__NVIC_PRIO_BITS) - 1);  /*设置优先级for Cortex-M0系统中断*/

SysTick->VAL  = 0; /*装载计数器值(当前计数值清 0)  */

SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |

Sy sTick_CTRL_TICKINT_Msk| SysTick_CTRL_ENABLE_Msk;/* 使能 Sy sTick 中断请求和 Sy stick 定时*/

return(0);          /*成功,返回 0 */

}

#endif

经过以上分析,我们我们需要,可以很方便的在自己的软件中操作SysTick来实现一些功能。

3STM32SysTick应用举例

既然SysTick我们已经清楚了他的原理及操作,也明白了STM32库中如何来操作它,那么我们能用他来做什么呢?首先我们可以在STM32中使用嵌入式操作系统的时候使用它来,并更具实际应用来设置。其实在不考虑操作系统是我们还可以使用SysTick来实现延时计时器。

一个实现的例子如下:

//定义延时计数的变量

__IO uint32_t TimingDelay;

const uint16_t delayAdjustments=12;

//函数名:ms延时函数

//描 述:参数1即为1ms,1000即为1s;只有几us的误差;

void Delayms(__IO uint32_t nTime)

{

while(SysTick_Config(SystemCoreClock/1000));

SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;// 关闭滴答定时器

TimingDelay = nTime;

SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;// 使能滴答定时器

while(TimingDelay != 0);

SysTick->CTRL=0x00; //关闭计数器

SysTick->VAL =0X00; //清空计数器

}

//函数名:us延时函数

//描 述:参数1即为1us,1000即为1ms;只有几us的误差;

void Delayus(__IO uint32_t nTime)

{

while(SysTick_Config(SystemCoreClock/1000000));

SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;// 关闭滴答定时器

TimingDelay = nTime;

SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;// 使能滴答定时器

while(TimingDelay != 0);

SysTick->CTRL=0x00; //关闭计数器

SysTick->VAL =0X00; //清空计数器

}

//函数名:延时递减计数函数

//描 述:由systick的中断函数调用,实现延时数值的递减计数

void TimingDelay_Decrement(void)

{

if (TimingDelay != 0x00)

{

TimingDelay--;

}

}

//函数名:延时调整形式的delaynus函数

//描 述:参数1即为1us,1000即为1ms,根据时钟频率的不同时间不同

void delay_nus(uint16_t n)

{

uint16_t j;

while(n--)

{

j=delayAdjustments;//根据不同时钟频率的指令周期调整数值

while(j--);

}

}

//函数名:延时调整形式的delaynms函数

//描 述:参数1即为1ms,1000即为1s,根据时钟频率的不同时间不同

void delay_nms(uint16_t n)

{

while(n--)

{

delay_nus(1000);

}

}

4、参考文献

我们参考了一些经典的手册以及网络论坛上的一些讨论,无法一一列出,暂列出部分参考文献:

(1)、《Cortex-M3权威指南》

(2)、《STM32F10x参考手册》

(3)、《STM32F4参考手册》

(4)、《STM32F7参考手册》

(5)、《STM32F10x库函数说明》

(6)、《STM32F1 HAL库说明》

(7)、《STM32F4 HAL库说明》

(8)、《STM32F7 Hal库说明》

时间: 2024-10-10 09:39:46

STM32学习及应用笔记一:SysTick定时器学习及应用的相关文章

关于STM32的systick定时器的详细说明

SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15).在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基.例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统:或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关.因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律. Cortex‐M3处理器内部包含了一个

关于嵌入式学习随笔-&gt;5《Systick定时器》

1.什么是Systick定时器? --->Systick定时器是一个简单的滴答定时器,对于ST的M3.M4.M7内核芯片,都有滴答定时器. --->Systick滴答定时器常常用来做延迟,或者时时操作系统的心跳时钟.这样可以节省MCU的资源,不用另外浪费一个定时器.比如UCOS系统中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick滴答定时器做UCOS的心跳时钟. --->Systick定时器就是一个系统滴答定时器,一个24位的倒计数定时器,记到0时

STM32中的几个时钟SysTick、FCLK、SYSCLK、HCLK

用时钟源来产生时钟! 在STM32中,有五个时钟源,为HSI.HSE.LSI.LSE.PLL.①.HSI是高速内部时钟,RC振荡器,频率为8MHz.②.HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz.③.LSI是低速内部时钟,RC振荡器,频率为40kHz.④.LSE是低速外部时钟,接频率为32.768kHz的石英晶体.⑤.PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2.HSE或者HSE/2.倍频可选择为2~16倍,但是其输出频率最大不得超过7

SysTick 定时器的使用

SysTick是STM32中的一个24位的定时器. Cortex‐M3处理器内部包含了一个简单的定时器.因为所有的CM3芯片都带有这个定时器,软件在不同 CM3器件间的移植工作得以化简.该定时器的时钟源可以是内部时钟,或者是外部时钟.不过,STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同,你需要查找芯片的器件手册来决定选择什么作为时钟源. Cortex-M3 的内核中包含一个 SysTick 时钟.SysTick 为一个 24 位递减计数器,SysTick 设定初

《学习opencv》笔记——矩阵和图像操作——cvSetIdentity,cvSolve,cvSplit,cvSub,cvSubS and cvSubRS

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

Systick定时器详解

Systick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有Systick定时器. Systick定时器常用来做延时,或者实时系统的心跳时钟.这样可以节省MCU资源,不用浪费一个定时器.比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟. Systick定时器就是系统滴答定时器,一个24位的倒计数定时器,计到0时,将从RELOAD寄存器中自动重装载定时初值.只要不把它在SysTick 控制及状态寄存器中的使能位清

《学习bash》笔记--进程处理

1.进程ID和作业编号 当通过附加&号后运行命令时,shell会响应如下: $ ls & [1] 3318 其中[1]是作业号,3318是进程号. 一个后台进程完成时,shell会给出作业编号信息,如下: [1]+  Done                    ls --color=auto 如果作业以非0状态退出时,shell指出其退出状态. 2.作业控制 作业编号可以使它们在shell命令中进行作业控制.一旦作业在后台运行,你可以让它一直运行,或把它放到前台,或向其发送信号. 2.

【web开发学习笔记】Structs2 Action学习笔记(一)

1.org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter准备和执行 2. <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> url-pattern约定熟成只写/*,没必要写*.action 3. <

《如何高效学习》读书笔记(一)——整体性学习策略

比喻的重要性华罗庚在讲“统筹”方法时,用了“怎样泡茶最省时间”的比喻.比喻的作用常常被我们忽视,仅仅把它当作文学中的修辞手段,是文学家用来增强表达效果的点缀和修饰.其实,比喻是我们必须掌握的站在外面看知识的本领.比喻不再局限于文学领域,它是我们的思维方式,更是我们的认知工具.莱考夫把隐喻定义为“以一种事物认知另一种事物”, 而这恰恰就是学习的本质! --------------------------------------------------------------------------