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



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

1、SysTick究竟是什么?

关于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.2SysTick 校准值寄存器”一节和《STM32F7xx参考手册》“10.1.1SysTick 校准值寄存器”一节中也都有:“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 校准值寄存器 

 

2、STM32中的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(SysTi 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文件中有寄存器定义:

typedefstruct

{

__IOuint32_t CTRL;

__IOuint32_t LOAD;

__IOuint32_t VAL;

__Iuint32_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 |

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

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

 }

 #endif

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

3、STM32中SysTick应用举例

既然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库说明》

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499513.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Atom快速打造好用的Markdown编辑器

使用Atom快速打造好用的Markdown编辑器 Atom当前主流的跨平台的三大编辑器(Atom,sublime,vscode)之一 今天尝试了使用Atom来打造Markdown编辑器&#xff0c;快速上手且易用&#xff0c;墙裂推荐&#xff01; 下面直接进入正题&#xff0c;一步步介绍如何使用Atom快速打造好用…

PID控制器开发笔记之一:PID算法原理及基本实现

&#xfeff;&#xfeff; 在自动控制中&#xff0c;PID及其衍生出来的算法是应用最广的算法之一。各个做自动控制的厂家基本都有会实现这一经典算法。我们在做项目的过程中&#xff0c;也时常会遇到类似的需求&#xff0c;所以就想实现这一算法以适用于更多的应用场景。…

十分钟能学会的简单python爬虫

简单爬虫三步走&#xff0c;So easy~ 本文介绍一个使用python实现爬虫的超简单方法&#xff0c;精通爬虫挺难&#xff0c;但学会实现一个能满足简单需求的爬虫&#xff0c;只需10分钟&#xff0c;往下读吧~ 该方法不能用于带有反爬机制的页面&#xff0c;但对于我这样的非专业…

PID控制器开发笔记之二:积分分离PID控制器的实现

前面的文章中&#xff0c;我们已经讲述了PID控制器的实现&#xff0c;包括位置型PID控制器和增量型PID控制器。但这个实现只是最基本的实现&#xff0c;并没有考虑任何的干扰情况。在本节及后续的一些章节&#xff0c;我们就来讨论一下经典PID控制器的优化与改进。这一节我们首…

利用python实现短信和电话提醒功能

有时候&#xff0c;我们需要程序帮我们自动检测某些事件的发生 这个需求是广泛存在的 因此&#xff0c;这里整理了利用python实现短信和电话提醒功能的方法 主要需要完成以下4个步骤&#xff1a; - 安装核心库&#xff1a;twilio - 注册账号及配置 - 发送短信示例 - 电话…

PID控制器开发笔记之三:抗积分饱和PID控制器的实现

积分作用的引入是为了消除系统的静差&#xff0c;提高控制精度。但是如果一个系统总是存在统一个方向的偏差&#xff0c;就可能无限累加而进而饱和&#xff0c;极大影响系统性能。抗积分饱和就是用以解决这一问题的方法之一。这一节我们就来实现抗积分饱和的PID算法。 1、抗积…

如何获取STM32 MCU的唯一ID

前段时间由于应用需要对产品授权进行限制&#xff0c;所以研究了一下有关STM32 MCU的唯一ID的资料&#xff0c;并最终利用它实现了我们的目标。 1、基本描述 在STM32的全系列MCU中均有一个96位的唯一设备标识符。在ST的相关资料中&#xff0c;对其功能的描述有3各方面&#x…

SHA256算法原理详解

1. SHA256简介 SHA256是SHA-2下细分出的一种算法 SHA-2&#xff0c;名称来自于安全散列算法2&#xff08;英语&#xff1a;Secure Hash Algorithm 2&#xff09;的缩写&#xff0c;一种密码散列函数算法标准&#xff0c;由美国国家安全局研发&#xff0c;属于SHA算法之一&…

学习笔记:区块链概念入门

本文是100天区块链学习计划的第二篇学习笔记&#xff0c;其实就是按照阮一峰的网络日志-区块链入门教程的讲解进行的简单梳理。也是时间有点紧张的原因&#xff0c;相比于上一篇SHA256算法原理详解&#xff0c;个人感觉质量和原创程度明显下降。待对区块链有了更深的理解后&…

PID控制器开发笔记之四:梯形积分PID控制器的实现

从微积分的基本原理看&#xff0c;积分的实现是在无限细分的情况下进行的矩形加和计算。但是在离散状态下&#xff0c;时间间隔已经足够大&#xff0c;矩形积分在某些时候显得精度要低了一些&#xff0c;于是梯形积分被提出来以提升积分精度。 1、梯形积分基本思路 在PID控制…

SHA256 的C语言实现

前几天总结了SHA256的算法原理一文 SHA2系列的原理并不复杂&#xff0c;但是需要注意细节还是挺多的。不少中文博客贴出的代码都有错&#xff0c;这两天也踩了几个坑。 代码在这里&#xff01;&#xff01;&#xff01;SHA256的C Code 代码实现主要依照的这个git仓库crypto-…

信息摘要算法之一:MD5算法分析及实现

MD5即Message-DigestAlgorithm 5&#xff08;信息-摘要算法5&#xff09;&#xff0c;用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一&#xff08;又译摘要算法、哈希算法&#xff09;&#xff0c;主流编程语言普遍已有MD5实现。 1、MD5算法简介 MD5在90年代初由…

非对称加密概述

非对称加密概述 前言 在阅读《精通比特币》的过程中&#xff0c;我发现比特币系统中有两个重要的概念需要利用非对称加密技术&#xff1a; 比特币地址的生成 交易合法性的验证 因此&#xff0c;我用了几天时间学习了密码学基础知识&#xff0c;尤其是非对称加密技术的原理…

信息摘要算法之二:SHA1算法分析及实现

SHA算法&#xff0c;即安全散列算法&#xff08;Secure Hash Algorithm&#xff09;是一种与MD5同源的数据加密算法&#xff0c;该算法经过加密专家多年来的发展和改进已日益完善&#xff0c;现在已成为公认的最安全的散列算法之一&#xff0c;并被广泛使用。 1、概述 SHA算法…

2018数学建模A题的简单指导

之前写过一篇博客&#xff0c;介绍如何使用差分格式求解热传导方程 今天打开博客&#xff0c;突然发现评论区被这篇文章霸屏了 询问实验室的小伙伴才知&#xff0c;原来是被可爱的建模学子们攻占了 经过简单的了解&#xff0c;发现今年建模的A题的核心就是求解一个热传导方程…

PID控制器开发笔记之五:变积分PID控制器的实现

在普通的PID控制算法中&#xff0c;由于积分系数Ki是常数&#xff0c;所以在整个控制过程中&#xff0c;积分增量是不变的。然而&#xff0c;系统对于积分项的要求是&#xff0c;系统偏差大时&#xff0c;积分作用应该减弱甚至是全无&#xff0c;而在偏差小时&#xff0c;则应该…

使用SIFT匹配金馆长表情包

python使用opencv计算SIFT特征点的示例前言潜在的问题记录demo1&#xff1a;计算并绘制特征点demo2&#xff1a;使用SIFT匹配两幅图像参考文章地址前言 SIFT&#xff08;Scale-invariant feature transform&#xff09;是2004年提出的&#xff0c;至今已经经受住各种考验&…

PID控制器开发笔记之六:不完全微分PID控制器的实现

从PID控制的基本原理我们知道&#xff0c;微分信号的引入可改善系统的动态特性&#xff0c;但也存在一个问题&#xff0c;那就是容易引进高频干扰&#xff0c;在偏差扰动突变时尤其显出微分项的不足。为了解决这个问题人们引入低通滤波方式来解决这一问题。 1、不完全微分的基…

使用Python实现简易的数据标注工具

使用Python实现简易的数据标注工具 以增加工作效率为目的&#xff0c;最近一直在着手构建一个AI ToolBox 这两天&#xff0c;我为其中的预处理工具目录添加了数据标注模块&#xff0c;本文所介绍内容的代码见这里 该数据标注模块包含以下几个demo gui_tkinter_exercise.py …

PID控制器开发笔记之七:微分先行PID控制器的实现

前面已经实现了各种的PID算法&#xff0c;然而在某些给定值频繁且大幅变化的场合&#xff0c;微分项常常会引起系统的振荡。为了适应这种给定值频繁变化的场合&#xff0c;人们设计了微分先行算法。 1、微分先行算法的思想 微分先行PID控制是只对输出量进行微分&#xff0c;而…