====SysTick
- SysTick是一个24位的系统节拍定时器system tick timer,SysTick,具有自动重载和溢出中断功能,所有基于Cortex_M3处理器的微控制器都可以由这个定时器获得一定的时间间隔。
SysTick—系统定时器有4个寄存器,在使用SysTick产生定时的时候,只需要配置前三个寄存器,最后一个校准寄存器不需要使用。
SysTick 属于内核的外设,有关的寄存器定义和库函数都在内核相关的库文件
core_cm3.h
中。
中断优先级是将置位的数转换为2进制,如Systick默认为15,转换为1111,对比中断1组,相当于抢占优先级为1,子优先级为111
====时间计算
* SystemCoreClock / 1000 1ms中断一次
* SystemCoreClock / 100000 10us中断一次
* SystemCoreClock / 1000000 1us中断一次
SysTick 中断时间的计算
SysTick 定时器的计数器是向下递减计数的,计数一次的时间 TDEC=1/CLKAHB,当重装载 寄 存 器 中 的 值 VALUELOAD 减 到 0 的 时 候 , 产 生 中 断 , 可 知 中 断 一 次 的 时 间
TINT=VALUELOAD * TDEC= VALUELOAD/CLKAHB , 其 中 CLKAHB =72MHZ 。 如 果 设 置
VALUELOAD 为 72,那中断一次的时间 TINT=72/72M=1us。不过 1us 的中断没啥意义,整个程序的重心都花在进出中断上了,根本没有时间处理其他的任务。
SysTick_Config(SystemCoreClock / 100000))
SysTick_Config()的形我们配置为 SystemCoreClock / 100000=72M/100000=720,从刚
刚分析我们知道这个形参的值最终是写到重装载寄存器 LOAD 中的,从而可知我们现在把
SysTick 定时器中断一次的时间 TINT=720/72M=10us。
SysTick 定时时间的计算
当设置好中断时间 TINT后,我们可以设置一个变量 t,用来记录进入中断的次数,那么变量 t 乘以中断的时间 TINT就可以计算出需要定时的时间。
====代码1(调用中断)demo
void SysTick_Init(void)
{
// if (SysTick_Config(SystemFrequency / 100000)) // ST3.0.0库版本
if (SysTick_Config(SystemCoreClock / 100000)) // ST3.5.0库版本
{
/* Capture error */
while (1);
}
}
/**
* @brief us延时程序,10us为一个单位
* @arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
*/
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;
// 使能滴答定时器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
while(TimingDelay != 0);
}
/**
* @attention 在 SysTick 中断函数 SysTick_Handler()调用
* void SysTick_Handler(void)
{
TimingDelay_Decrement();
}
*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
====代码2(查询寄存器位)demo
systick 的 counter 从 reload值往下递减到 0 的时候, CTRL寄存器的位 16:countflag 会置 1,且读取该位的值可清 0,所以可以使用软件查询的方法来实现延时。
void SysTick_Delay_Us( __IO uint32_t us)
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000000);
for(i=0;i<us;i++)
{
// 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
while( !((SysTick->CTRL)&(1<<16)) );
}
// 关闭SysTick定时器
SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Delay_Ms( __IO uint32_t ms)
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000);
for(i=0;i<ms;i++)
{
// 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
// 当置1时,读取该位会清0
while( !((SysTick->CTRL)&(1<<16)) );
}
// 关闭SysTick定时器
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}
====Systick的中断处理函数:SysTick_Handler
Systick的中断处理函数:在startup_stm32f10x_hd.s启动文件中有定义。
DCD SysTick_Handler ; SysTick Handler
根据需要直接编写中断处理函数即可:Void SysTick_Handler (void)
注意:如果在工程中,加入了stm32f10x_it.c,而又在主函数中编写中断函数,则会报错。因为在stm32f10x_it.c文件中,也有这个中断函数的声明,只是内容是空的。