这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 第九篇 系统滴答定时器

共9条 1/1 1 跳转至

第九篇 系统滴答定时器

高工
2016-05-22 01:23:56     打赏

第九篇  系统滴答定时器

在所有的ST32MCU中,基本上都存在SysTick,也就是滴答定时器,这篇我们就来讲讲怎么配置滴答定时器。

首先,第一件事就是找到它的时钟树的位置,时钟的配置在第四篇 时钟树的分析已经讲过了,如下图:

 

上图还是时钟树(Clock Tree)从上图我们可以得到这么几个信息:

(1)SysTick就是内核系统定时器(滴答定时器)

(2)SysTick的时钟源来自HCLK

(3)SysTick的时钟为HCLK8分频,即Fsystick = HCLK/8

 

我们找到我们的相应的编程手册

 

看到上图,我想再不明白的人也要明白了!这就清清楚楚的介绍了SysTick的使用了哈!继续晒图:相应寄存器的信息

 

 

这里清清楚楚的说明了SySTick的第一个寄存器STK_CSR的功能和使用了。东西比较少,我就解释一下:

Bit 0 ----- 0位,SysTick的开关,置1使能

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

注意:SysTick计数倒着数,到0说明完成一次周期

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

Bit 16---16位,定时器计数到0的时候,返回1

 

看到这个,就知道了,STK_RVR寄存器就是SysTick的装载寄存器了,用来装计数的个数的嘛,哈哈!但是注意哦,因为SysTick24位的定时器(前面文档有介绍),所以别越界出轨了哈!据说出轨的硕士都被打死了,何况你还不是硕士对吧?

看看下一个:

 

看标题就知道了,SysTick的当前计数值寄存器,想知道此时计数到哪里了,读它就好了!

下一个!!!

 

SysTick的校准定时器!!!!咱不校准,想校准的童鞋自己看看!多么简单的东西!

 

到这里,我们得到的信息是:

(1)我们需要操作的寄存器:STK_CSRSTK_RVRSTK_CVR

(2)寄存器的地址:如下图

 

 

现在要干的第一件事是,我们应该怎样才能操作寄存器:

方法1:直接操作

 

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

方法2:使用库的定义

core_m0.h文件中,有如下定义:

 

从注释来看,它说这就是SysTick的寄存器结构体!OK!怎么证明呢??

再往下:

 

有这么几个信息:

(1)基地址为 SCS_BASE            (0xE000E000UL) ,即基地址就是0xE000E000

(2)SysTick的基地址为:(SCS_BASE +  0x0010UL),即为:0xE000E010 咦是不是和STK_CSR寄存器地址一样了呢??对的,就是一样的,再往下

(3)宏#define SysTick             ((SysTick_Type   *)     SysTick_BASE  ),首先SysTick的基地址SysTick_BASE被强制转换为结构体SysTick_Type类型的指针(也就是以这个地址为起点sizeof(SysTick_Type)大小的空间成为这个结构体类型),然后定义成宏SysTick,所以宏SysTick就成为了SysTick_Type的指针。再往下分析:

(4)分析得下图:

 

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

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

好的!完事具备!只欠程序了!如下:

 

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

变量定义玩了,就是初始化SysTick了!其实初始化SysTick就是一句话SysTick->CTRL = 0xfffffffb;,就是操作TK_CSR寄存器。至于为毛是这个值,那就自己看手册了!

但是,其实适用库函数接口也是可以的:就是这个:

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),这个函数的注释是选择SysTick的时钟,其实就是初始化了,但是必须注意:参数必须是:SysTick_CLKSource_HCLK_Div8HCLK8分频,证据就是前面的时钟树。但是将到这里咱不放看看这个函数的原型,

 

从函数中,也可以看出也是操作TK_CSR寄存器,因为参数必须是SysTick_CLKSource_HCLK_Div8,所以我们可以看看SysTick_CLKSource_HCLK_Div8的定义值如何:

 

看到没:SysTick_CLKSource_HCLK_Div8的值也是0xFFFFFFFB

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

SysTick的时钟:Fsystick = HCLK/8

SysTick计数一次的时间:Tsystick = 1/Fsystick

咱们来个毫秒延时:

 

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

那么实现是怎么样的呢??

 

其实在编程手册里面就教了我们怎么使用:

 

哈哈!人家明明白白的告诉了咱怎么使用,并且列出了1,2,3,那咱就不能客气了!哈哈!

1.将计数值装载到装载寄存器

2.清空计数器

3.计数开始

4.等等计数到达

5.关闭计数器

6.清空计数器

过程就如上6步了。

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

OK!毫秒延时就这样!!

下面就是微秒延时了!哈哈!

 

毫秒延时都讲的这么清楚了,微秒延时就不说了,都是一个妈生的!

 

来看看主函数吧!

 

 




关键词: SysTick          定时器    

工程师
2016-05-22 17:14:32     打赏
2楼
挺好!!!!!!!!!!

院士
2016-05-22 18:19:52     打赏
3楼
楼主真棒

助工
2016-05-23 09:37:35     打赏
4楼

专家
2016-05-29 11:01:07     打赏
5楼
很详细~

高工
2016-05-31 10:59:44     打赏
6楼
学习

高工
2016-06-30 14:43:44     打赏
7楼
搬凳听讲。

高工
2016-07-03 19:34:08     打赏
8楼
板凳听讲。

专家
2016-07-03 22:44:11     打赏
9楼
好资料,收藏了,慢慢看。

共9条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]