嵌入式学习笔记 | 您所在的位置:网站首页 › tick的英语 › 嵌入式学习笔记 |
系统滴答
前言SysTick概述SysTick是个啥SysTick结构框图1. 时钟选择2.计数器部分3.中断部分工作一个计数周期(从重装载值减到0)的最大延时时间工作流程
SysTick寄存器1.控制和状态寄存器SysTick->CTRL2.重装载值寄存器SysTick->LOAD3.当前值寄存器SysTick->VAL4.校准值寄存器
配置流程
代码利用系统滴答实现时间片轮询效果
总结M4系列目录
前言
上一篇中,介绍了关于STM32F407的时钟系统,在了解了系统的时钟后,最重要的内容就是搞定定时器的操作,本文从最基本的定时器,也是内核里面自带的一个定时器——SysTick(系统滴答)来进行介绍。旨在搞清楚什么是系统滴答,系统滴答有什么用,系统滴答怎么用。 SysTick概述SysTick这个词其实之前出现过,在介绍中断的时候,就是下面这个图,SysTick就出现了,看他的位置,在图中阴影部分内,也就是说,SysTick是内核里面的属于NVIC的一部分;不是类似USART、GPIO的片上外设,而是一个内核内的外设;看图中有个箭头指向了NVIC,说明它是可以像前面用过的EXTI、USART来产生中断的。 SysTick是个啥关于是个啥这种问题,实在是不好表述,咱还是让官方来作答吧。 看了上面的描述,会有一个大致的概念,首先,它是一个可编程的系统定时器,其次,它被用来做延时和计时的操作,然后还可以触发中断。有一点需要纠正,上面说它是一个32位的自动递减计数器,这点有误,在STM32F407中,它是一个24位的自动递减计数器。 这里一直在说系统滴答是个定时器,那么定时器是个啥,直白点说,定时器就是一个按照时间规律递增或者递减的计数器,在STM32中这个时间规律就是时钟,例如,我们假设系统滴答的时钟是168MHZ;那么系统滴答这个定时器就会在一秒钟内,从0自增到168 000 000;同样的换个方向来理解,就是说计数器计满168000 000就是1s钟的时间。至于递减和递增,递减就是说计数器的初始有我们给定,然后计数器就从这个值开始做自减;而自增则是,我们给定值,然后计数器从0开始自增,一直增加到这个数。 好了,在有了一个大致的映像后,下面就来具体分析它的结构和功能。 SysTick结构框图由于系统滴答是内部定时器,所以在ST公司的中文参考手册是找不到的,只有在ARM的权威指南中才可以找到相关描述,具体位置在M3和M4权威指南的第九章第五节。 下拉就可以看见系统框图: 还是按照老套路,把能够省略部分先噶了,这里可以很明显的看见最下面红框与上面的东西都没有联系,所以它是可以噶了的,他的作用就是校准SysTick的,一般来说,SysTick就是使用的系统时钟,如果这个不准了,那么多半这个单片机也命不久矣,所以这个东西可以直接不看。 去掉不需要看的,接下来就分模块一个部分一个部分的来介绍。 1. 时钟选择如下图,左侧的红框代表的就是系统滴答的时钟输入选部分;绿色框内是一个二选一数据选择器,两个输入分别是处理器时钟以及经过上升沿检测的参考时钟;执行选择的是下方的“控制和状态寄存器的第2位”,具体的选择流程在寄存器部分会详细介绍。然后时钟就给到了计数器。 既然有两个输入的时钟,那么这两个时钟具体是指什么呢? 其一是处理器时钟,也就是我们说的主频,对于STM32F407来说对应168MHZ;那么另外一个参考时钟是什么呢?其实这个时钟在昨天的时钟树介绍中也出现了。如下图所示,橙色框中的到Cortex系统定时器的就是这里的参考时钟,可以发现,它经过了一个8分频的分频器,也就是说这个时钟的频率应该是168/8=21Mhz。 2.计数器部分计数器简化后如下图所示,这是一个计数器的最基本结构,首先有三部分输入: 1.时钟基准:这个时钟直接决定了这个计数器多少时间执行一次计数; 2.重装载值:上方的重装载值直接决定了计数器的最大计数值; 3.控制部分:控制部分直接决定了计数器什么时刻开始计数,什么时候关闭计数,这里的第0位就是用来控制计数器是否计数的。 然后是输出部分,输出只有一个方向,就是4的位置,注意描述:当计数器从1减到0的时候会触发,而且这个触发是指向了“控制和状态寄存器”的,这就说明,当计数完成的时候,在“控制和状态寄存器”中会有对应的位,让我么来判断计时是否完成。 最后,最主要的部分,就是橙色框的24位向下计数器,它的作用就是隔一段时间将数值减一。当然,这里的明子就叫向下计数器,那么肯定还有对应的向上计数器,以及中心对齐的计数器,这个在后面基本通用和高级定时器中会碰到,遇到了再说。 3.中断部分然后这个图还剩最后一部分,就是有关中断的了,这里有一个与门,与门的输入一个来自计数器技术完成后的标志,另一个来自“控制与状态寄存器”的第1位,也就是中断使能,说明在需要使用到中断的过程中,需要使能这个位才能开启中断。 工作一个计数周期(从重装载值减到0)的最大延时时间弄清楚了上面的结构后,就可以计算出两个频率下,计数器工作一个周期,最长所需要花费的时间。 最大的重装载值:2^24=16777216 系统滴答具备两个时钟源: 内核时钟:主频提供时钟 168MHZ 最大的延时时长:1S16777216/168 000 000=0.09986S 0.09986s---->99.8ms 外部时钟:由AHB线提供 21MHZ 最大的延时时长:1S16777216/21 000 000=0.7989 S 0.7989s-----》798.9ms 工作流程根据框图的分析,可以大致总结出系统滴答的初始化流程: { ①选择时钟; ②根据自己所需时间计算出重装载值; ③使能计数器; ④判断对应的标志位是否到了,到了说明计时到了,没到说明计时还没到 } SysTick寄存器其实根据框图,寄存器也已经猜的七七八八了,还是具体的看一眼,关于系统滴答一共有四个寄存器。 1.控制和状态寄存器SysTick->CTRL写法:SysTick->CTRL 功能:对系统滴答定时器做控制,以及读取对应的状态 第0位:ENALEB 置1:使能计数器 一直重复工作 置0:失能计数器 第1位:中断使能位 计数标志一定会置1/中断标志 置1:使能中断 置0:失能中断 第2位:选择时钟源 默认1 置1:选择内核时钟 168MHZ 置0:外部参考时钟 21MHZ 第16位:标志位 只读 为1:计数器到0则返回1 为0:读取时清零 读取时的具体写法: while(! (SysTick->CTRL & (1LOAD 功能:提供计数器的最大值 用法:直接写入需要写入的最大计数值 不能超过最大的重装载值范围(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 &=~(1VAL=0; //清空计数器,清标志位 SysTick->CTRL |=1 SysTick->LOAD =nms*SysTick_ms;//传进来的参数*21 nms 传多少就是多少毫秒 SysTick->VAL=0; //清空计数器,清标志位 SysTick->CTRL |=1 i = 100; _TIMER_100MS ++; } } 利用系统滴答实现时间片轮询使用时间片轮询的方式编程,可以很好地解决之前遇见的阻塞问题,在系统滴答里面定义好对应的计时变量,然后根据这个计时变量来执行所需要的操作。 如下图所示:这里笔者一共选取了三个时间变量分别计时1S、100ms、200ms,其中一秒钟的时序对应一次串口打印输出;100ms与200ms分别对应LED1和LED2的闪烁;除此之外还有一个轮询为0的情况用来存放不需要严格时序刷新的任务。 效果最终效果如下:通过时间戳可以看出来SysTick的计时还是比较准准确的。 总结系统滴答就是一个系统内的定时器,其主要作用就是提供精确延时以及计时的功能,可以借此实现时间片轮询的代码框架。 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通信 |
CopyRight 2018-2019 实验室设备网 版权所有 |