定时器_第六章--系统滴答定时器

本文介绍了系统滴答定时器,它是内核(M4)定时器,可使用内核或外部时钟源。其应用于UCOS系统提供时钟节拍、简单延时及定时器中断。文中分析了定时器框图,介绍相关寄存器及位,还给出滴答定时器延时和中断的配置步骤及对应代码。

第六章--系统滴答定时器

简介:系统滴答定时器是内核(这里指M4)定时器使用的是内核时钟源168MZ或可以选择外部时钟源21MZ

应用场合:

为UCOS系统提供时钟节拍

作为简单的定时器延时使用 //最大延时798ms

作为定时器中断使用

=======================================================

1.sTick定时器简介

SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号: 15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统"心跳"的节律。Cortex‐M3处理器内部包含了一个简单的定时器。因为所有的CM3芯片都带有这个定时器,软件在不同 CM3器件间的移植工作得以化简。该定时器的时钟源可以是内部时钟(FCLK,CM3上的自由运行时钟),或者是外部时钟( CM3处理器上的STCLK信号)。不过, STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同,你需要检视芯片的器件手册来决定选择什么作为时钟源。SysTick定时器能产生中断, CM3为它专门开出一个异常类型,并且在向量表中有它的一席之地。它使操作系统和其它系统软件在CM3器件间的移植变得简单多了,因为在所有CM3产品间对其处理都是相同的。

1.1有4个寄存器控制SysTick定时器,功能如表8.9至表8.12所示

14757cdd218e4039ce9ecbd84a0c4070.png
b14689c13b209fd3d07a38a6e2a71fad.png

-----------------------------------------------------------------------------------------------

2.系统滴答定时器框图:

0de50c2982f4e14892375429405e4b0e.png

分析框图写程序看要用到些什么

1. 先看框图左边有一个2选1选择器这是选择滴答定时器的时钟源的分内核时钟和外部时钟源

再看2选1选择器对过来是Sys Tick当前值寄存器 VAL 为24位向下计数器,可以存放的最大值为 2^24=16777216,如你写进100,SysTick控制及状态寄存器CTRL使能计数器后,当前值寄存器向下计数(100减到0),从而达到定时效果,当计数到0后产生一个中断信号Sys Tick控制及状态寄存器CTRL的状态标志位自动置1,如果使能中断则会产生中断,不关闭计数器重装载值寄存器LOAD就会把预先的值写进当前值寄存器VAL重新计数

时钟分析:

内核时钟源:168M

168M=168000 000/s=168/us

当前值寄存器写进16777216则最大延时时间99ms

16777216 /168 = 99864us = 99ms

外部时钟源:21M

21M=21000 000/s = 21/us

当前值寄存器写进16777216则最大延时时间798ms

16777216 / 21 = 798915us = 798ms

-----------------------------------------------------------------------------------------------

2. 分析框图可知要用到的相关寄存器及位如下

SysTik->CTRL :状态及控制寄存器

第2 位:时钟源选择

写0:外部时钟源(STCLK) 21M 系统时钟8分频

写1:内核时钟(FCLK)168M

第0 位:计数器使能

写0:禁止计数

写1:使能计数

第16位:当计数器自动计数到零的时候,此位自动置1(读取该位如果为0,定时时间未到,如果为1,定时时间到)此位需要软件清零

①通过读此位就会清零 SysTik->CTRL

②对当前值寄存器写任意值,此位也会清零 SysTick->VAL = 0xff

当前值寄存器 = 随便写一个数 ;//对状态控制寄存器的16位清零

SysTik->VAL :当前值寄存器

1)当使能计数器后,开始向下计数,当SysTik->VAL为0时,即计数到0时

控制及状态寄存器16位自动置1;

2)对当前值寄存器写操作,它自己本身也清零,状态控制寄存器的16位清零

SysTik->LOAD : 重装载值寄存器

根据要定时多长时间,可以把定时的时间,加载到当前值寄存器中,当计数器的计数值向下计数到了后如果不关闭计数器,那么LOAD的重装载值就会自动加载到计数器中,重新开始向下计数。

注意:最大值 21M 798ms

-----------------------------------------------------------------------------------------------

3.滴答定时器延时配置步骤:

1.选择时钟源->21M/168M

2.清零当前值寄存器->写进任意一个数据

3.向重装载值寄存器写进一个定时值

4.使能计数器

5.等待计数完成

6.关闭计数器

/************************************************

*函数名 :SysTick_us

*函数功能 :系统滴答定时器实现微妙级别延时

*函数参数 :u32 us

*函数返回值:无

*函数描述 :将需要延时的时间写入到参数中

***************************************************/

void SysTick_us(u32 us)

{

//时钟源选择21M //控制及状态寄存器的2位写 0外部时钟

SysTick->CTRL &= ~(1 << 2);

SysTick->VAL = 0xff; //将当前值寄存器清零 //随便写一个数据进入

SysTick->LOAD = us * 21; //将要计时的数据写入到重装载值寄存器

SysTick->CTRL |= 1 << 0; //开始计数//开计数器使能

while(!(SysTick->CTRL & 1 << 16)); // (16位为0) 等待计数完成为1计数完成

SysTick->CTRL &= ~(1 << 0); //关闭计数器

}

-------------------------------------------------------------------------------------

3.滴答定时器中断配置步骤:

1.选择时钟源->21M/168M

2.清零当前值寄存器->写进任意一个数据

3.向重装载值寄存器写进一个定时值

4.使能计数器

5.等待计数完成

4.系统滴答中断

注意:系统滴答属于系统中断,不需要使能NVIC中断响应通道系统滴答延时函数 不能同系统滴答中断一起使用

/************************************************

*函数名 :SysTick_ms_interrupt_init

*函数功能 :系统滴答定时器毫秒级别定时中断初始化

*函数参数 :u16 ms

*函数返回值:无

*函数描述 :将需要定时的时间写入到参数中

***************************************************/

void SysTick_ms_interrupt_init(u16 ms)

{

u32 pri;

/*系统滴答定时器配置*/

SysTick->CTRL &= ~(1 << 2); //时钟源选择21M控制及状态寄存器的2位写 0外部时钟

SysTick->VAL = 0xff; //将当前值寄存器清零->随便写一个数据进入

SysTick->LOAD = ms * 21000; //将要计时的数据写入到重装载值寄存器

SysTick->CTRL |= 1 << 1; //定时中断使能

/*NVIC控制器配置*/

//中断优先级分组(抢占和响应的位数) //抢占2位 响应 2位在主函数中

//中断优先级编码值(抢占和响应的具体级别)

pri = NVIC_EncodePriority(5,2,1);

NVIC_SetPriority(SysTick_IRQn,pri); //将优先级编码值写入到具体中断源中

SysTick->CTRL |= 1 << 0; //开始计数 //开计数器使能

}

/************************************************

*函数名 :SysTick_Handler

*函数功能 :

*函数参数 :无

*函数返回值:无

*函数描述 :

***************************************************/

void SysTick_Handler(void)

{

SysTick->VAL = 0xff; //向VAL寄存器写入一个值清除中断标志位

GPIOF->ODR ^= 1 << 8; //每次触发中断蜂鸣器响取反一次

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值