完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
SysTick定时器适用所有的STM32开发板,这节课讲解SysTick定时器产生的 延时函数,STM32开发指南5.1小节有有关SysTick相关的 介绍,在程序中在delay文件夹中,SysTick定时器是内核级别的,这个定时器很简单,主要用来延时和用作实时系统里面的心跳时钟 可以节省单片机资源,SysTick定时器就是系统滴答定时器,是一个24位的倒计数定时器,当他计数到0时就会从RELOD寄存器(重装载寄存器)重新装载计数初值,由此循环。只要 不把他的使能 位清除,他就会永不停息的工作,即使在睡眠模式下也能正常工作。
SysTick定时器它是捆绑在NVIC中,可以产生SysTick异常,SysTick也可以产生中断 ,可以设置中断优先级,可编写中断服务函数 , SysTick有四个寄存器,前面3个比较常用,LOAD放重装载值,VAL寄存器一个时钟周期会减一,一直减到0之后又会从这个LOAD寄存器重新加载到VAL寄存器, 这样去循环 1. SysTick控制和状态寄存器 CTRL 下面这个表在Cortex M3权威指南里有。用来配置systick相关的一些使能位和时钟。 位0 (ENABLE)SysTick定时器的使能位, 位1 (TICKINT) 当VAL寄存器计数到0时是否要产生中断 为1 产生中断 为0不产生中断 位2(CLKSOURCE)时钟源,为 0使用外部时钟源(STCLK) 为1 使用内核时钟(FCLK) 对于STM32而言 0.使用外部时钟源是HCLK(AHB总线时钟的1/8) 1.内核时钟是HCLK时钟 这里M3经过 Systeminit()后系统时钟是72M,那么SysTick时钟就是72/8=9M M4经过 Systeminit()后系统时钟是168M 那么SysTick时钟就是168/8=21M SysTick定时器的时钟源可以由SysTick_CLKSourceConfig()配置,由这个函数的入口参数确定使用哪一个作为时钟源。这里 对于M3M4都是一样的,因为它是属于内核级别的,都是属于同一 SysTick定时器。 位16 (COUNTFLAG) 如果SysTick计数到0,该位为1,如果读取该位,该位将自动清零 第二寄存器叫做 重装载数值寄存器-LOAD,是一个24位寄存器 能装2的24次方的数 第三个寄存器是 SysTick当前值寄存器-VAL,一个周期减一 Systick相关库函数 SysTick_CLKSourceConfig(); 是配置CTL寄存器的,用于时钟源的选择 SysTick_Config(uint32_t ticks) 这个函数会开启SysTick 中断, ticks是一秒钟产生中断的次数 这里的中断函数 void SysTick_Handler(void); 对于M3/M4都是一样的 下面看代码 这个 函数有一个入口参数叫 Systick_CLKSource 实际上是配置CTRL寄存器位2(CLKSOURCE), 为0 就是配置为外部时钟 HCLK(AHB总线时钟)的1/8 为1就是配置为内核时钟,就是HCLK 还有一个函数在core_cm4.h/core_cm3.h里面的SysTick_Config(uint32_ticks)这个代码的作用;初始化SysTick相关的寄存器,并且开启SysTick相关的寄存器,入口参数ticks.,也就是说ticks个时钟周期产生一次中断。 ticks 代表 两个systick中断之间的时间长短,如果将 ticks设置为 1000,也是就1000个systick时钟周期, 代码的第一行对这个ticks的值进行一个有效性判断,因为这个ticks的值不能是无限大,因为ticks最终是要写到LOAD寄存器的,从LOAD寄存器被加载到这个VAL寄存器,ticks的值 不能大于 我们可以看到是6个F(就是2的24次方-1),也就是ticks不能大于2的24次方。 将 ticks-1赋值给这个load寄存器(也就是重装载寄存器的值设置为ticks-1),那么他就会加载到这个VAL寄存器当中,当VAL的值计数到0,LOAD寄存器又从新将初值装载到VAL当中。 接下来 是设置优先级,那么设置优先级在NVIC相关的视频会去讲解 接着把这个VAL设置为0, 为什么要设置为0呢?因为当我们这个VAL值为0的时候他会从新去加载计数初值,所以这里初始化的时候把它设置为0,后面如果开启了SysTick定时器,第一次他就会把初值加载到VAL当中。 上图代码就是就是开启这个SysTick定时器,1设置 时钟源 2开启中断 3使能SysTick定时器。 对于Systick库函数,有一个·SysTick_Config(uint32_ticks)利用中断实现的delay函数 这里函数的备注错了,应该是200ms的延时 上面这段代码作简单讲解 1.首先 在主函数里面他会调用一个SysTick_Config(uint32_ticks)这样的一个函数,入口参数是ticks,这里SysTick的时钟是HCLK是168M,因为要定时1ms,那么通过计算就是:168000000/1000,然后是 上面写的一个delay函数,在这个函数前面定义了一个全局变量,TimerDelay(168M时钟,1s计数168000 000次,那么1ms就计数计数168 000次,所以168M时钟/1000=1ms 延时) 上面的代码中入口参数是200,就等待他为0才能够结束。 函数功能:每1ms产生一次中断,进一次中断TimingDelay就-1,直到TimingDelay为0就延时了200ms。 正点原子的系统文件夹 的delay.c是是使用查询的方式实现延时的,在delay.h里面有三个函数 1,。delay_init(u8 SYSCLK) 这是对SysTick进行初始化,然后是两个 毫秒和微秒的延时。因为正点原子的delay.c里面支持ucos操作系统,所以有一部分代码是通过宏定义来支持的。 上图中 的两个变量在初始化函数当中我们会设置他的值,假如系统时钟是 168M,SysTick的时钟频率是系统时钟的8分频,也就是21M,那么 fac_us 含义就是我们要延时1us要用多少个SysTick时钟周期? 因为系统时钟是21M,所以就是21时钟周期是1us。 那么延时1ms要多少个时钟周期? 就是21000个时钟周期 这里SYSCLK和HCLK是一样的为168, 这一行代码是UCOS相关的,暂时不看。 上图入口参数, 选择HCLK的8分频作为SysTick的时钟频率,那么SysTick的时钟频率就是21M, 这里SYSCLK/8=168/8=21,所以fac_us=21,也就是说1us需要21个时钟周期。 上图这一段代码也是ucos相关的暂时不看。 到最后这个就是设置ms的因子。下面就开始写我们的ms、us的延时函数,有3个函数 delay_us这个函数他就有一个入口函数叫nus。就告诉我们调用这个函数输入100就是100us 怎么实现呢? 也就是让初值LOAD=nms*fac_ms 使能SysTick计数器,让LOAD寄存器的值加载到VAL寄存器,并开始计数,当计数到0时,CTRL寄存器就有一个位16标志位,计数到0就会置1.之后我们就关闭计数器。然后再清空计数器。 注意:延时时间是有一个范围的,怎么来确定这个范围呢?LOAD寄存器是一个24位的寄存器,也就是说他的最大值是2的24次方-1,所以nus*fac_us不能大于79815us这个值 这里将入口参数除以540是为什么呢?,目的是增加延时时间的范围,比如说我们要延时一个任意长度的延时时间,那么我们这里实际上就把他切成了540毫秒一份,比如说你要延时1000ms,他就先延时540ms再延时460ms这样就延时了1000ms。 这个函数和微秒 的配置是一样的。这里不在介绍。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1754 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1613 浏览 1 评论
1053 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1667 浏览 2 评论
1931浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
718浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
562浏览 3评论
587浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
546浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 17:30 , Processed in 0.868601 second(s), Total 77, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号