赞
踩
一、系统定时器
1. 简介
SysTick 叫做系统滴答时钟、系统定时器,属于 Cortex-M4 内核中的一个外设(外围设备),并且是24bit向下递减的计数器。
《STM32中文参考手册》P108
RCC 向 Cortex 系统定时器 (SysTick) 馈送 8 分频的 AHB 时钟 (HCLK)。SysTick 可使用此时钟作为时钟源,也可使用 HCLK 作为时钟源。
具体可在 SysTick 控制和状态寄存器中配置。
注意:
计数值,就是要进行多少个计数。
2.工作原理
3.频率的概念
物质在1s内完成周期性变化的次数叫做频率,常用f表示。为了纪念德国物理学家赫兹的贡献,人们把频率的单位命名为赫兹,简称“赫”,符号为HZ。
周期与频率的关系:f=1/T。(其中f为频率,T为周期)。
周期,物体作往复运动或物理量作周而复始的变化时,重复一次所经历的时间。物体或物理量(如交变电流、电压等)完成一次振动(或振荡)所经历的时间。
二、库函数
参考文档:《Cortex M3与M4权威指南.pdf》第314页
1.系统定时器配置
/** \brief System Tick Configuration
The function initializes the System Timer and its interrupt, and starts the System Tick Timer. Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
示例:
//系统定时器触发1KHz的中断,中断周期时间T= 1/f = 1000ms/1000=1ms
//系统定时器连接到PLL输出的168MHz时钟,就是1秒内产生脉冲的个数为168000000。
//只要系统定时器进行168000000次计数,就是1秒时间的到达
//只要系统定时器进行168000次计数,就是1ms时间的到达
//只要系统定时器进行168次计数,就是1us时间的到达 SysTick_Config(SystemCoreClock/1000);
SysTick_Config(168000);
注:若发现定时不准确,检查PLL配置是否正确。
三、最大定时时间
1.确定最大的计数值2^24 -1,若计算到0,则进行2^24次计数。
1000ms Tmax
-------- = --------
168000000 2^24
Tmax = 2^24 *1000ms/168000000 = 99.86ms。
2.测试结果
初始化系统定时器,1S 内核触发 1000 次中断,说白了定时 1ms,能够成功
SysTick_Config(SystemCoreClock/1000);
初始化系统定时器,1S 内核触发 10 次中断,说白了定时 100ms,现象失败
SysTick_Config(SystemCoreClock/10);
初始化系统定时器,1S 内核触发 11 次中断,说白了定时 90.90ms,能够成功
SysTick_Config(SystemCoreClock/11);
总结:填写中断频率值不能小于11,否则定时时间不准确。
SysTick_Config(SystemCoreClock/11);
四、延时函数
1.系统定时器的用途
2.官方示例
参考文档:《Cortex M3与M4权威指南.pdf》第314页
In many cases you might not want to use the SysTick_Config function because you might want to use the reference clock or you might not want to enable the SysTick interrupt. In these cases you need to program the SysTick registers directly,and the following sequence is recommended:
1). Disable the SysTick timer by writing 0 to SysTick->CTRL. This step is optional.It is recommended for reusable code because the SysTick could have been enabled previously.
2). Write the new reload value to SysTick->LOAD.
3). Write to the SysTick Current Value register SysTick->VAL with any value to clear the current value to 0.
4). Write to the SysTick Control and Status register SysTick->CTRL to start the SysTick timer.
参考文档:《Cortex M3与M4权威指南.pdf》第316页
If you want to use the SysTick timer in polling mode, you can use the count flag in the SysTick Control and Status Register (SysTick->CTRL) to determine when the timer reaches zero. For example, you can create a timed delay by setting the SysTick timer to a certain value and waiting until it reaches zero:
SysTick->CTRL = 0; // Disable
SysTick SysTick->LOAD = 0xFF; // Count from 255 to 0 (256 cycles)
SysTick->VAL = 0; // Clear current value as well as count flag SysTick->CTRL = 5; // Enable SysTick timer with processor clock while ((SysTick->CTRL & 0x00010000)==0);// Wait until count flag is set SysTick->CTRL = 0; // Disable SysTick
3.寄存器
4.毫秒与微秒级延时函数
void delay_ms(uint32_t ms)
{
while(ms --)
{
SysTick->CTRL = 0; // 关闭系统定时器后才能配置寄存器
SysTick->LOAD = 21000; // 设置计数值,用于设置定时的时间
SysTick->VAL = 0; // 清空当前值还有计数标志位
SysTick->CTRL = 1; // 使能系统定时器工作,且时钟源为系统时钟的8分频(168MHz/8=21MHz)
while ((SysTick->CTRL & (1<<16))==0); // 等待系统定时器计数完毕
SysTick->CTRL = 0; // 关闭系统定时器
}
}
void delay_us(uint32_t n)
{
SysTick->CTRL = 0; // 关闭系统定时器
SysTick->LOAD = n*168-1; // 168000000/1000000 -1,每次延时1us
SysTick->VAL = 0; //清空val寄存器 还有清空COUNTFLAG标志位
SysTick->CTRL = 5; // 使能系统定时器工作,而它的时钟源为处理器时钟168MHz
while ((SysTick->CTRL & 0x00010000)==0);// 等待系统定时器计数完毕
SysTick->CTRL = 0; // 关闭系统定时器
}
5.微秒和毫秒延时的优化[拓展]
官方代码没有想到意外关闭的问题
int32_t delay_us(uint32_t nus)
{
uint32_t temp;
SysTick->CTRL = 0;
SysTick->LOAD = (nus*21)-1;
SysTick->VAL = 0;
SysTick->CTRL = 1;
while(1)
{
temp=SysTick->CTRL;
//检测count flag
if(temp & 0x00010000)
break;
//检测系统定时器是否意外关闭
if((temp & 0x1)==0)
return -1;
}
SysTick->CTRL = 0;
return 0;
}
int32_t delay_ms(uint32_t nms)
{
uint32_t t = nms;
uint32_t temp;
while(t--)
{
SysTick->CTRL = 0;
SysTick->LOAD = 21000-1;
SysTick->VAL = 0;
SysTick->CTRL = 1;
while(1)
{
temp=SysTick->CTRL;
//检测count flag i
f(temp & 0x00010000)
break;
//检测系统定时器是否意外关闭
if((temp & 0x1)==0)
return -1;
}
}
SysTick->CTRL = 0;
return 0;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。