嵌入式学习笔记——SysTick(系统滴答)

这篇具有很好参考价值的文章主要介绍了嵌入式学习笔记——SysTick(系统滴答)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

上一篇中,介绍了关于STM32F407的时钟系统,在了解了系统的时钟后,最重要的内容就是搞定定时器的操作,本文从最基本的定时器,也是内核里面自带的一个定时器——SysTick(系统滴答)来进行介绍。旨在搞清楚什么是系统滴答,系统滴答有什么用,系统滴答怎么用。

SysTick概述

SysTick这个词其实之前出现过,在介绍中断的时候,就是下面这个图,SysTick就出现了,看他的位置,在图中阴影部分内,也就是说,SysTick是内核里面的属于NVIC的一部分;不是类似USART、GPIO的片上外设,而是一个内核内的外设;看图中有个箭头指向了NVIC,说明它是可以像前面用过的EXTI、USART来产生中断的。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发

SysTick是个啥

关于是个啥这种问题,实在是不好表述,咱还是让官方来作答吧。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发
看了上面的描述,会有一个大致的概念,首先,它是一个可编程的系统定时器,其次,它被用来做延时和计时的操作,然后还可以触发中断。有一点需要纠正,上面说它是一个32位的自动递减计数器,这点有误,在STM32F407中,它是一个24位的自动递减计数器。
这里一直在说系统滴答是个定时器,那么定时器是个啥,直白点说,定时器就是一个按照时间规律递增或者递减的计数器,在STM32中这个时间规律就是时钟,例如,我们假设系统滴答的时钟是168MHZ;那么系统滴答这个定时器就会在一秒钟内,从0自增到168 000 000;同样的换个方向来理解,就是说计数器计满168000 000就是1s钟的时间。至于递减和递增,递减就是说计数器的初始有我们给定,然后计数器就从这个值开始做自减;而自增则是,我们给定值,然后计数器从0开始自增,一直增加到这个数。

好了,在有了一个大致的映像后,下面就来具体分析它的结构和功能。

SysTick结构框图

由于系统滴答是内部定时器,所以在ST公司的中文参考手册是找不到的,只有在ARM的权威指南中才可以找到相关描述,具体位置在M3和M4权威指南的第九章第五节。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发
下拉就可以看见系统框图:
还是按照老套路,把能够省略部分先噶了,这里可以很明显的看见最下面红框与上面的东西都没有联系,所以它是可以噶了的,他的作用就是校准SysTick的,一般来说,SysTick就是使用的系统时钟,如果这个不准了,那么多半这个单片机也命不久矣,所以这个东西可以直接不看。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发
去掉不需要看的,接下来就分模块一个部分一个部分的来介绍。

1. 时钟选择

如下图,左侧的红框代表的就是系统滴答的时钟输入选部分;绿色框内是一个二选一数据选择器,两个输入分别是处理器时钟以及经过上升沿检测的参考时钟;执行选择的是下方的“控制和状态寄存器的第2位”,具体的选择流程在寄存器部分会详细介绍。然后时钟就给到了计数器。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发
既然有两个输入的时钟,那么这两个时钟具体是指什么呢?
其一是处理器时钟,也就是我们说的主频,对于STM32F407来说对应168MHZ;那么另外一个参考时钟是什么呢?其实这个时钟在昨天的时钟树介绍中也出现了。如下图所示,橙色框中的到Cortex系统定时器的就是这里的参考时钟,可以发现,它经过了一个8分频的分频器,也就是说这个时钟的频率应该是168/8=21Mhz。

systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发

2.计数器部分

计数器简化后如下图所示,这是一个计数器的最基本结构,首先有三部分输入:
1.时钟基准:这个时钟直接决定了这个计数器多少时间执行一次计数;
2.重装载值:上方的重装载值直接决定了计数器的最大计数值;
3.控制部分:控制部分直接决定了计数器什么时刻开始计数,什么时候关闭计数,这里的第0位就是用来控制计数器是否计数的。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发
然后是输出部分,输出只有一个方向,就是4的位置,注意描述:当计数器从1减到0的时候会触发,而且这个触发是指向了“控制和状态寄存器”的,这就说明,当计数完成的时候,在“控制和状态寄存器”中会有对应的位,让我么来判断计时是否完成。
最后,最主要的部分,就是橙色框的24位向下计数器,它的作用就是隔一段时间将数值减一。当然,这里的明子就叫向下计数器,那么肯定还有对应的向上计数器,以及中心对齐的计数器,这个在后面基本通用和高级定时器中会碰到,遇到了再说。

3.中断部分

然后这个图还剩最后一部分,就是有关中断的了,这里有一个与门,与门的输入一个来自计数器技术完成后的标志,另一个来自“控制与状态寄存器”的第1位,也就是中断使能,说明在需要使用到中断的过程中,需要使能这个位才能开启中断。

systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发

工作一个计数周期(从重装载值减到0)的最大延时时间

弄清楚了上面的结构后,就可以计算出两个频率下,计数器工作一个周期,最长所需要花费的时间。
最大的重装载值:2^24=16777216
系统滴答具备两个时钟源:
内核时钟:主频提供时钟 168MHZ
最大的延时时长:1S16777216/168 000 000=0.09986S
0.09986s---->99.8ms
外部时钟:由AHB线提供 21MHZ
最大的延时时长:1S
16777216/21 000 000=0.7989 S
0.7989s-----》798.9ms

工作流程

根据框图的分析,可以大致总结出系统滴答的初始化流程:

{
	①选择时钟;
	②根据自己所需时间计算出重装载值;
	③使能计数器;
	④判断对应的标志位是否到了,到了说明计时到了,没到说明计时还没到
}

SysTick寄存器

其实根据框图,寄存器也已经猜的七七八八了,还是具体的看一眼,关于系统滴答一共有四个寄存器。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发

1.控制和状态寄存器SysTick->CTRL

systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发
写法:SysTick->CTRL
功能:对系统滴答定时器做控制,以及读取对应的状态
第0位:ENALEB
置1:使能计数器 一直重复工作
置0:失能计数器

第1位:中断使能位 计数标志一定会置1/中断标志
置1:使能中断
置0:失能中断

第2位:选择时钟源 默认1
置1:选择内核时钟 168MHZ
置0:外部参考时钟 21MHZ

第16位:标志位 只读
为1:计数器到0则返回1
为0:读取时清零
读取时的具体写法:

while(! (SysTick->CTRL & (1<<16)) );

2.重装载值寄存器SysTick->LOAD

systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发
写法: SysTick->LOAD
功能:提供计数器的最大值
用法:直接写入需要写入的最大计数值
不能超过最大的重装载值范围(0-1667216)
SysTick->LOAD=arr-1;
这个值具体写入多少,要结合需求,计算出大小

3.当前值寄存器SysTick->VAL

写法:SysTick->VAL
功能:存储计数器的当前值
读取这个寄存器:能够获取到计数器的当前值
写入这个寄存器:任意值都能清除计数标志位

4.校准值寄存器

在分析框图的时候提到过,这个一般不用。

配置流程

这里的配置流程分为两类:
其一是实现一个延时功能,延时功能只需要定时器工作一个周期,也就是从重装载值减到一的一个过程,执行一次后需要关闭定时器,不让他还会不停的从重装载值减到0然后又从重装载值减到0无限循环。
伪代码:

实现系统的us延时(参数)
{
   //选择时钟 建议选择外部时钟
   //写入重装载值  21*参数
   //当前值清零
   //打开计数器
   //等待标志位置1
   //关闭计数器
}

其二就是利用中断,一定时间进一次中断,以此来实现一个时间片轮询的操作方式。这时候,就需要定时器一直计数了,所以不能计数完成后就关闭计数器了。伪代码如下:

系统滴答的初始化代码
{
   //选择系统滴答的时钟
   //配置系统抵达的重装载值
   //当前值清零
   //打开中断使能
   
   //NVIC控制器

   //开启定时器   
}
中断服务函数
{
	判断标志;
	清楚标志;
	执行操作。
}

代码

#include "SysTick.h"
u16 SysTick_us;
u16 SysTick_ms;


/*******************************
函数名:SysTick_Init
函数功能:初始化系统滴答,选择外部时钟
函数形参:u32 sysclk 系统时钟168(MHZ)
函数返回值:void
备注:开启1ms中断

********************************/
void SysTick_Init(u32 sysclk) //168MHZ
{
	u32 pri;//存储优先级合成函数返回的优先级
	
	SysTick->CTRL &=~(1<<2); //选择外部时钟,必须清零默认是1内核时钟
	SysTick_us=sysclk/8;           //21     1us//外部时钟8分频
	SysTick_ms=SysTick_us*1000;            //21 000  1ms
	
	SysTick->LOAD = SysTick_ms-1;//重装载值21000-1
	SysTick->VAL=0;    //清空计数器,清标志位
	SysTick->CTRL |=1<<1;   //使能中断 

/*-----------------------配置NVIC---------------------------------------------*/	
	pri=NVIC_EncodePriority(7-2,1,2);
	NVIC_SetPriority(SysTick_IRQn,pri);
	NVIC_EnableIRQ(SysTick_IRQn);
	
		SysTick->CTRL |=1<<0;   //使能计数器  
}


/*******************************
函数名:SysTick_Delay_us
函数功能:系统滴答实现us延时
函数形参:u32 nus
函数返回值:void
备注:
//因为LOAD为24位,所以最大重装载值16,777,216
最长时间:形参最大值,798,915us

********************************/
void SysTick_Delay_us(u32 nus)//1us
{
	SysTick->LOAD =nus*SysTick_us;//传进来的参数*21  nus 传多少就是多少微秒
	SysTick->VAL=0;    //清空计数器,清标志位
	SysTick->CTRL |=1<<0;   //使能  
	while(!(SysTick->CTRL & 1<<16));//等待计数完成
	SysTick->CTRL &=~(1<<0);  //关闭计数器
	SysTick->VAL=0;     //清空计数器,清标志位
}
/*******************************
函数名:SysTick_Delay_ms
函数功能:系统滴答实现ms延时
函数形参:u32 nms
函数返回值:void
备注:
形参最大值798ms
********************************/
void SysTick_Delay_ms(u32 nms)
{
	SysTick->LOAD =nms*SysTick_ms;//传进来的参数*21  nms 传多少就是多少毫秒
	SysTick->VAL=0;    //清空计数器,清标志位
	SysTick->CTRL |=1<<0;   //使能  
	while(!(SysTick->CTRL & 1<<16));//等待标志位到
	SysTick->CTRL &=~(1<<0);  //关闭计数器
	SysTick->VAL=0;     //清空计数器,清标志位
}
//中断服务函数:

/*******************************
函数名:SysTick_Handler
函数功能:系统滴答的中断服务函数函数
函数形参:无
函数返回值:void
备注:1ms进一次中断
********************************/
void SysTick_Handler(void)
{
	static u8 i=100;
	while(SysTick->CTRL &(1<<16))//检测中断标志,同时也是清除标志位
		mtime--;
		Led_cnt++;
		_TIMER_1MS++;
		i--;
	if(i==0){
		i = 100;
		_TIMER_100MS ++;
	}
}


利用系统滴答实现时间片轮询

使用时间片轮询的方式编程,可以很好地解决之前遇见的阻塞问题,在系统滴答里面定义好对应的计时变量,然后根据这个计时变量来执行所需要的操作。
如下图所示:这里笔者一共选取了三个时间变量分别计时1S、100ms、200ms,其中一秒钟的时序对应一次串口打印输出;100ms与200ms分别对应LED1和LED2的闪烁;除此之外还有一个轮询为0的情况用来存放不需要严格时序刷新的任务。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发

效果

最终效果如下:通过时间戳可以看出来SysTick的计时还是比较准准确的。
systick,嵌入式 —M4,单片机,学习,stm32,嵌入式,arm开发

总结

系统滴答就是一个系统内的定时器,其主要作用就是提供精确延时以及计时的功能,可以借此实现时间片轮询的代码框架。

M4系列目录

1.嵌入式学习笔记——概述
2.嵌入式学习笔记——基于Cortex-M的单片机介绍
3.嵌入式学习笔记——STM32单片机开发前的准备
4.嵌入式学习笔记——STM32硬件基础知识
5.嵌入式学习笔记——认识STM32的 GPIO口
6.嵌入式学习笔记——使用寄存器编程操作GPIO
7.嵌入式学习笔记——寄存器实现控制LED小灯
8.嵌入式学习笔记——使用寄存器编程实现按键输入功能
9.嵌入式学习笔记——STM32的USART通信概述
10.嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
11.嵌入式学习笔记——STM32的USART收发字符串及串口中断
12.嵌入式学习笔记——STM32的中断控制体系
13.嵌入式学习笔记——STM32寄存器编程实现外部中断
14.嵌入式学习笔记——STM32的时钟树
15.嵌入式学习笔记——SysTick(系统滴答)
16.嵌入式学习笔记——M4的基本定时器
17.嵌入式学习笔记——通用定时器
18.嵌入式学习笔记——PWM与输入捕获(上)
19.嵌入式学习笔记——PWM与输入捕获(下)
20.嵌入式学习笔记——ADC模数转换器
21.嵌入式学习笔记——DMA
22.嵌入式学习笔记——SPI通信
23.嵌入式学习笔记——SPI通信的应用
24嵌入式学习笔记——IIC通信文章来源地址https://www.toymoban.com/news/detail-810464.html

到了这里,关于嵌入式学习笔记——SysTick(系统滴答)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【嵌入式学习笔记】嵌入式入门2——中断(外部中断)

    【嵌入式学习笔记】嵌入式入门2——中断(外部中断)

    打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断 作用1: 实时控制在确定时间内对相应事件作出响应 ——定时器中断 作用2: 故障处理检测到故障,需要第一时间处理 ——外部中断 作用3: 数据传输不确定数据何时会来 ——串口中断

    2024年02月08日
    浏览(25)
  • 软考-嵌入式系统设计师:[嵌入式系统基础:笔记(一)]

    软考-嵌入式系统设计师:[嵌入式系统基础:笔记(一)]

    大家不要只收藏不关注呀,哪怕只是点个赞也可以呀!🤣 粉丝私信发邮箱,免费发你PDF!!! 因为准备备考中级嵌入式设计师证书,所以买了一些资料回来准备复习,本书为倪奕文老师编制的书,如果大家有时间和精力还是很建议大家去买一本的,这本书反而是能够让小白很快

    2023年04月08日
    浏览(173)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(30)
  • 嵌入式学习笔记汇总

    嵌入式学习笔记汇总

    本文整理STM32、STM8和uCOS-III的所有文章链接。 源码:mySTM32-learn STM32学习笔记(1)——LED和蜂鸣器 STM32学习笔记(2)——按键输入实验 STM32学习笔记(3)——时钟系统 STM32学习笔记(4)——NVIC中断优先级管理和外部中断EXTI STM32学习笔记(5)——系统定时器SysTick STM32学习笔

    2023年04月20日
    浏览(39)
  • 嵌入式操作系统(嵌入式学习)

    嵌入式操作系统(嵌入式学习)

    嵌入式操作系统是一种专门设计和优化用于嵌入式系统的操作系统。它是在资源受限的嵌入式设备上运行的操作系统,如微控制器、嵌入式处理器和系统芯片等。 嵌入式操作系统的主要目标是提供对硬件资源的有效管理和对应用程序的调度,以实现系统的可靠性、实时性和效

    2024年02月10日
    浏览(9)
  • 嵌入式学习笔记——SPI通信

    嵌入式学习笔记——SPI通信

    之前已经介绍了STM32的ADC、DMA、EXTI、TIME、NVIC、USART以及普通IO模式,此系列笔者还打算写最后三个大的内容,分别是SPI通信、IIC通信以及看门狗,后面就看大家的需求了,需要什么可以留在评论区,本文首先来介绍SPI的有关知识。 在通信协议分类的介绍中,提到过SPI,它是一

    2023年04月09日
    浏览(13)
  • 嵌入式学习笔记——IIC通信

    嵌入式学习笔记——IIC通信

    本文接着之前的M4系列介绍,对另外一个十分常见的通信总线进行一个介绍,就是IIC总线。 首先,还是找个免费劳动力来做一个官方的介绍,下面这一段话非常全面的介绍了IIC的各个特征,用之前提到的通信特征来总结,IIC是一种串行,同步,半双工,板级有线通信。与SPI对

    2024年02月06日
    浏览(40)
  • 【计算机三级嵌入式】考试自学笔记(三)——嵌入式系统硬件组成、嵌入式处理芯片以及存储器介绍

    【计算机三级嵌入式】考试自学笔记(三)——嵌入式系统硬件组成、嵌入式处理芯片以及存储器介绍

    常考知识点: 嵌入式最小硬件组成 嵌入式处理芯片 嵌入式系统的存储器 I/O接口及常用I/O设备 ARM内核典型嵌入式处理芯片 嵌入式系统外部通信接口 嵌入式最小硬件系统的组成如下: 嵌入式硬件系统≠嵌入式最小硬件系统 电源电路 :为整个嵌入式系统提供能量 时钟电路 :

    2023年04月12日
    浏览(13)
  • 【嵌入式】Thumb指令集(学习笔记)

    【嵌入式】Thumb指令集(学习笔记)

    ARM开发工具完全支持Thumb指令,应用程序可以灵活的将ARM和Thumb子程序混合编程以便在例程的基础上提高性能或代码密度。在编写Thumb指令时,先要用伪指令CODE16声明(ADS的编译环境下),而且在ARM指令中要使用BX指令跳转到Thumb指令,以切换处理器状态。 Thumb指令集编码如下:

    2023年04月22日
    浏览(11)
  • 【嵌入式算法】学习笔记(一):数字滤波算法

    【嵌入式算法】学习笔记(一):数字滤波算法

    最近在做直流电机的毕设中,由于需要采集转速,电流,电压,温度等参数,常规的采集容易受到干扰,所以特意复习了一下关于数字滤波有关的知识,并作出相应的整理。 本文对数字滤波进行简单介绍,讲解七种常用的滤波算法并用C语言实现,并比较其优缺点 。由于篇幅

    2023年04月22日
    浏览(14)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包