和记娱乐


网站导航

联系我们

和记娱乐

联系人: 

电 话:021-64057486

公司网址:http://www.happy123456789.com

   址:成都市松江区漕河泾松江新兴产业园区研展路丰产支路55号B座803室

邮编:201165


通信科技

您的当前位置: 和记娱乐主页 > 通信科技 >

STM32F030 Nucleo-做个准确的延时SysTick

发布日期:2020-01-30 07:17 来源:和记h88 发布人:和记娱乐 点击:

  写过单片机程序的人都知道,软件延时是不准确的,当然,当在我们可接受的情况下,很多地方还是用软件延时的!但是在情况允许的条件下,我们还是希望延时越准确越好,这样可以我们Demo的一些精度或者时候准确性。

  在所以的ST32位MCU中,基本上都存在这么一个定时器,很多人都叫它“滴答定时器”,也就是SysTick,在我移植过的好几个实时操作系统中,这个滴答定时器都用来作为操作系统调度的定时器了。其实这个定时器的使用非常简单,但是基本上很多人又觉得它是神秘的!为毛呢??打开MCU的DadaSheet,参考手册,都很少提到SysTick,并且提到的地方也就是一句话带过,库手册也就是说明一下操作它的接口!然后!然后!然后就没有然后了。

  那么我们怎么样使用它呢??有可能我们根本就不了解这个定时器,就算它再简单,没资料,呵呵!玩起来也是很费劲的啊!这个疑问先放起来!看看下一个疑问??

  文章的开头不是“做个准确的延时”么??那么它和SysTick有毛关系呢??(可能多远单片机程序员来说,延时就是:delay_ms(x)这种),其实我就想用SysTick来给我做延时,因为MCU的运行时钟在配置好之后,就基本上是稳定的了!稳定的时钟数山羊,那就可以计算出每数一次山羊所用的时间,更可以算出在一定时间内能数多少只山羊了(还记得小时候的数山羊游戏吗?)。所以就是利用这么个思想来干这种事。

  当然,问题又来了,STM32有那么多个通用定时器和特殊定时器,干嘛非得用SysTick啊??我个人给的答案就是:(1)只要你开心,想怎么样都好。(2)对于通用定时器和特殊定时器而言,他们除了定时功能之外,还有其他的很多特殊复用功能,比如说PWM的输出等等,非得这么干的话你这是在浪费资源(当然,你若开心,便是晴天),然而,SysTick据我本人所知,它就是ARM核用来数山羊的,就这么个定时计时功能,不用它用谁??

  还记得在准备资料的时候,特别提示,一点要将MCU的编程手册下载下来吗???在这里就用到它了!

  第一章从技术角度来说,可能不是那么重要,但是对于不了解ST说档的布局的童鞋而言,我个人认为还是必须浏览第一章的,因为他介绍了,本文档的格式和关键词使用还有必要的说明格式等,再就是简单的介绍了文章的布局,和所包含的内容,这对于阅读文档,找到想要的资料是最快速的方法。

  第二章基本上就是对Cortex-M0内核的简单介绍了,比如模式,堆栈,内核寄存器,数据类型,内存,低功耗模式等等的介绍了。

  第四章,哈哈哈哈哈哈!看到标题没??Core peripherals 我想英语水平再差的人都知道这是Cortex-M0的核心外设了,那就是说这是ARM架构Cortex-M0核有的东西,并不只有ST的才有。OK!SysTick就是核心外设之一啦!这就是为毛找它的原因了啊!哈哈!!等等,还有第五章,得装完B再说。

  首先,我觉得这个手册是写给程序员看的!它不是真正的Cortex-M0手册,因为从手册的内容来看,它再教我们怎么使用,怎么写程序配置,而不是解释Cortex-M0内核(当然,从名字就知道了!哈哈!)。这一点很重要,所以它常重要的手册,比库函数手册重要N倍。

  从注释上来分析,要让SysTick跑起来使用这两函数的确足够了,但是想想哪里不对劲啊??咱的目的是做个延时程序,希望能够精确的延时,并且咱随时指定延时多久,这怎么还玩起中断来了,不对,不对,这不靠谱(我说的不靠谱是和我们的目的不靠谱,并非这个库不靠谱,哈哈!),唉!没办法,只能对ST的攻城狮说,你不给咱写好,咋就自己玩了!哈哈!那砸门就自己玩!

  那么怎么玩呢???这就是为毛在开篇的时候一大堆废话谈《Cortex-M0编程手册》的原因了,咱自己玩,得靠它啊!OK!继续--0------>

  看到上图,我想再不明白的人也要明白了!这就清清楚楚的介绍了SysTick的使用了哈!(翻译就算了,水平太菜了,不恶心人了)。

  哈哈哈!看到了没??SysTick的寄存器被我看到了!既然看到了寄存器,那要搞它就不难了。哈哈!继续再往下!再往下!再往下!

  嘎嘎!你看到的没错,你没眼花,这里清清楚楚的说明了SySTick的第一个寄存器STK_CSR的功能和使用了。东西比较少,我就解释一下:

  Bit 1-----1位,SysTick的异常开关,其实就是中断开关,置1,当SysTick计时到0时,产生中断

  注意:SysTick数山羊的方式和咱小时候玩的不太一样,人家要倒着数,到0说明完成一次数山羊

  Bit 2-----2位,SysTick的时钟资源选择,置0,使用外部参考时钟;置1,使用处理器的时钟

  看到这个,就知道了,STK_RVR寄存器就是SysTick的装载寄存器了,用来装山羊的个数的嘛,哈哈!但是注意哦,因为SysTick是24位的定时器(前面文档有介绍),所以别越界了哦!越界就像是用个吃饭的碗来装一桶水,肯定装不完啦!肯定会溢出啦!不懂啥事溢出的话,就想想水从碗里溢出来的现象哈哈!只是在这里是数据溢出而言!

  在头文件里直接定义这三个寄存器的物理地址(特别注意:寄存器是32位的),相应操作寄存器的某一位只需要操作TK_CSR、STK_RVR和STK_CVR的相应的某一位即可。就是这么简单!

  SysTick的地址就是0xE000E010了,而根据结构体的贴心,第一个的地址和结构体的地址值是相等的,所以就有了上图(要是不懂的话,好好的去补补C语言,把基本功打扎实了,没点肿么能玩转物理地址呢??),所以,结构体的和SysTick的寄存器就对应上了。哈哈!其实ST的库里面的寄存器的结构都是这么干的,定义寄存器的方法都是一样的!

  当然,喜欢玩寄存器的童鞋,我就应该用以上的方法1的方法,这才是玩寄存器啊,!直接使用ST定义好的结构,多没意思!!哈哈!!

  首先,先定义两个本文件全局变量(记住这两个全局变量只适用在本文件),分别是:c_ms和c_us,啥意思呢??它俩就是分别用来记录1ms和1us时间内SysTick能计的数。

  OK!初始化解决了!那么,这个初始化函数还有一个参数,干啥的呢??其实就是系统时钟啦!比如,咱的系统时钟已经配置成48MHz,那么调用的时候,直接SysTick_Init(48);即可,其实这个参数就是用来计算c_ms和c_us的值的,公式如下:

  有了以上两个公式(对于哪来的公式,别问我,问手册去),那么计算c_ms和c_us的值就不难了!哈哈!OK!初始化结束。

  函数的意思就是:延时nms,比如需要延时100毫秒,就调用:delay_ms(100);即可。

  注意一点啊:SysTick->CTRL = 0x01;计时器时是对寄存器直接赋值,而不是操作某一位啊!所以这样的话,是不会产生中断的!因为中断被关了啊!

  调用就如上图了!记住哦,先配置好系统时钟哦!要是顺序搞反了,搞不出来就该打屁屁了哦!哈哈哈!

  纵观IT界,一个简单的东西内说个20页可能也就是我这种逗逼了!哈哈!不过呢!我只是想解决一些初学者迷茫或者的问题!高手的问题咱不敢解决!

      和记娱乐,和记h88,h88平台官网