STMCU小助手
发布时间:2023-3-8 13:00
|
滴答定时器: 定时器的本质就是计数器。我们设置一个定值,然后计数器开始计数,从我们给的定值开始往下一直数,当数到0时,就做相应的动作(也可以不做什么,当把它用作延时计时的时候)。 滴答定时器systick是一个内核外设(即:内核自带的) Systick是一个24bit的系统定时器(stm32F407的寄存器名字与位数都与f103一样,但是有些芯片定时器位数不同),向下计数(从定值开始数到0),当计数到0时,在下一个时钟边沿,会重复计数。所以如果我们用完定时器后,不再继续使用它时,记得要将定时器关掉,否则它就一直在重复计数,增加了功耗。 Systick的作用 1.产生一个精准的定时 2.FreeRTOS时基由Systick提供 在说定时器前,我们先来看一看如何计数?
配置滴答定时器:
红框中就是滴答定时器的时钟,我们可以看到分频系数为8,所以滴答定时器的频率为:72M/8 = 9Mhz 配置滴答定时器我们需要下面几个寄存器:
注意:第16位,是定时完成标志位,每当计数到0时,该标志位就会置1。
注意:由于定时器是24位的,所以给定时器装载的定值是有一个范围的,红框中就是范围,范围为0x000001 ~ 0xFFFFFF 即:1~ 也就是:1 ~ 16,777,215,如果填入的定值不是在0x000001 ~ 0xFFFFFF这个范围,则无法定时计数。
编程 产生Nms定时编程步骤: 1》配置时钟源---AHB8分频,并且关闭定时器-----初始化(while(1)之前) 2》设置计数值---N*9000 3》清除当前值寄存器----注意:清除当前值寄存器,STK_CTRL寄存器的第16位会自动清0 4》打开定时器 5》等待定时器结束 6》关闭定时器 代码:
解析: 1.我们先来看程序,定时器程序为什么被分成 Systick_Config(uint32_t Sysclk) 、Systick_NmsDelay(uint32_t Nms)两部分来写? 因为,Systick_Config(uint32_t Sysclk) 中的配置,在整个程序中只需要被初始化一次就行了,而Systick_NmsDelay(uint32_t Nms)是延时函数,它会被多次使用。如果将Systick_Config(uint32_t Sysclk)与Systick_NmsDelay(uint32_t Nms)写在一起的话,那么多次调用该函数时,原本只需要被初始化一次的语句,就会被多次执行,浪费CPU资源。 2.为什么程序中的这部分需要用do.....while而不用while()?
这里需要用do....while而不用while,是因为需要先执行temp = SysTick->CTRL; 将SysTick->CTRL寄存器中的值赋值给变量temp,然后再对temp进行真假判断,即:!(temp&(1<<16))。temp&(1<<16)为读取SysTick->CTRL中的第16位是1还是0,如果第16位是1,则为真,但是由于非 "!" 的存在,所以 ! (temp & (1<<16))就为假,所以此时do.....while循环不再循环下去。如果第16位是0,则为假,但是由于非 "!" 的存在,所以 ! (temp & (1<<16))为真,所以此时do.....while循环将继续循环下去。等到第16位变为1,也就是定时完成标志位置1时,如上所述,while循环将不再循环下去,此时计数器计数完成。 3. 由上面知滴答定时器的计数器是24位的,其计数范围为 0x000001 ~ 0xFFFFFF ,即:1 ~ 16,777,215,那么如果我需要计的数超过了这个范围呢?我该怎么办? 由前面知,计数9000下,延时1ms。所以,16,777,215可以延时1864ms,即: = 1864 。也就是说,在9Mhz频率下,将计数器计满,可以实现延时1864ms。 的确,如果我想要延时2000ms,那么由于超过计数器的计数范围,那么滴答定时器就不会正常工作了。 所以,我们改下一下程序:
这样的话,就解决了1864问题了。 4.us级的延时程序是什么?
注意: 在FreeRTOS操作系统中,不能使用我们自己设置的Systick来进行延时,因为FreeRTOS时基是由Systick提供(裸机的时基是由晶振提供的)。这是什么意思? FreeRTOS时基是由Systick提供,时基是需要保持不变的,所以Systick寄存器中的值必须是固定的,是不允许被修改的。但是,如果我们在FreeRTOS中用我们手动设置的Systick来进行延时,我们必定会去修改Systick寄存器中的值来得到我们需要的延时。所以,此时如果在FreeRTOS中使用我们手动设置的Systick去进行延时,那么就会卡死。解决办法:使用软件延时,delay()函数来代替Systick延时。代码如下:
———————————————— 版权声明:无敌小小雷 如有侵权请联系删除 |
STM32固件库分享,超全系列整理
经验分享 | 利用STM32 TIMER实现同频跟随输出示例
【MCU实战经验】基于STM32F103的二轮平衡车(6轴上位机 源代...
经验分享 | 一个基于TIMER事件的中断响应话题_续
经验分享 | 一个基于TIMER事件的中断响应话题
11张图学会STM32定时器!
10张图带你完全掌握STM32 GPIO,从入门到精通,收藏就够了!
如果你解决了这些问题,就可以直接学STM32
STM32的分类和选型
学习STM32很简单?
微信公众号
手机版