STM32--SYSTICK定时器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32--SYSTICK定时器相关的知识,希望对你有一定的参考价值。
STM32中的SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。
Systick定时器是一个24位递减计数器,224=16777216,所以Systick的计数最大值为16777215(从0-16777215),转化为16进制即0xFF FFFF;
当定时器计到0 时,将从RELOAD 寄存器中自动重装载定时初值,开始新一轮的计数。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。
SysTick的时钟源可以是内部时钟(FCLK),也可以是外部时钟的分频(HCLK/8);
由系统时钟树可以看到,当选择外部8MHZ晶振时,经过9倍频后,系统时钟为72MHz,所以选择外部时钟的分频时,此时SysTick的时钟即为9MHz,也就是SysTick的VAL寄存器每减一,耗时为1/9μs(9MHz的频率即1秒钟震动9,000,000次)。
SysTick共有4个寄存器,分别为:
SysTick->CTRL, -- 控制和状态寄存器
SysTick->LOAD, -- 重装载寄存器
SysTick->VAL, -- 当前值寄存器
SysTick->CALIB, -- 校准值寄存器
固件库中,关于SysTick的相关函数有一下几句:
1 SysTick_CLKSourceConfig() //Systick选择时钟源(FWLIB-misc.c文件中) 2 SysTick_Config(uint32_t ticks) //初始化Systick(CORE-core_cm3.h文件中)
分别为: 1、配置SysTick的时钟源 2、配置相关寄存器
中断服务函数为:
void SysTick_Handler(void); //stm32f10x_it
首先:
1、SysTick_CLKSourceConfig()函数,我们在misc.c中找到SysTick_CLKSourceConfig()的函数源码:
1 void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) 2 { 3 /* Check the parameters */ 4 assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); 5 if (SysTick_CLKSource == SysTick_CLKSource_HCLK) 6 { 7 SysTick->CTRL |= SysTick_CLKSource_HCLK; //内部时钟72M 8 } 9 else 10 { 11 SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; //外部时钟 72/8=9M 12 } 13 }
由程序可以看出,在此函数里配置了SysTick->CTRL寄存器。
SysTick_CLKSourceConfig参数的两种情况:
两种时钟源 : SysTick_CLKSource_HCLK_Div8 外部时钟 72/8=9M
SysTick_CLKSource_HCLK 内部时钟 HCLK=72M
2、SysTick_Config(uint32_t ticks)函数,core_cm3.h中找到SysTick_Config函数源码:
static __INLINE uint32_t SysTick_Config(uint32_t ticks) { if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); //ticks参数有效性检查 SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; //设置重装载值 //-1:装载时消耗掉一个Systick时钟周期 NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); //配置NVIC SysTick->VAL = 0; //初始化VAL=0,使能Systick后立刻进入重装载 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | //选择时钟源 SysTick_CTRL_TICKINT_Msk | //开启Systick中断 SysTick_CTRL_ENABLE_Msk; //使能Systick定时器 return (0); /* Function successful */ } #endif
在这段函数中,对CTRL、LOAD、VAL三个寄存器进行了配置,初始化了SysTick所使用的时钟,清除系统当前值,装入重装值,使能了Systick定时器,开启了SysTick中断;
所以,在主程序中调用SysTick_Configuration(uint32_t ticks),输入重装值即可。
用SysTick定时器实现延时:
1、初始化延时函数
1 static u8 fac_us=0; //延时微秒的频率 2 static u16 fac_ms=0; //延时毫秒的频率 3 4 void delay_init() 5 { 6 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择时钟源-外部时钟-HCLK/8 7 fac_us=SystemCoreClock/8000000; // 72/8 9MHz 1s震动9,000,000次,所以延时1微秒(除以1,000,000)9个时钟周期 8 fac_ms=(u16)fac_us*1000; // 延时1毫秒9000个Cystic时钟周期 9 }
2、微秒μs延时函数:
1 void delay_us(u32 nus) 2 { 3 u32 temp; 4 //nus*fac_us值最大不能超过SysTick->LOAD(24位)-1 5 SysTick->LOAD=nus*fac_us; // 设置重载值:n(us)*延时1us需要多少个SysTick时钟周期 6 SysTick->VAL=0x00; // VAL初始化为0 7 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; // 使能SysTick定时器 8 do 9 { 10 temp=SysTick->CTRL; 11 }while((temp&0x01)&&!(temp&(1<<16))); // 等待计数时间到达(位16) 12 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; // 关闭使能 13 SysTick->VAL =0X00; // 重置VAL 14 }
3、毫秒ms延时函数
1 void delay_ms(u16 nms) 2 { 3 u32 temp; 4 SysTick->LOAD=(u32)nms*fac_ms; 5 SysTick->VAL =0x00; 6 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; 7 do 8 { 9 temp=SysTick->CTRL; 10 }while((temp&0x01)&&!(temp&(1<<16))); 11 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; 12 SysTick->VAL =0X00; 13 }
2017-10-31 21:42:31
以上是关于STM32--SYSTICK定时器的主要内容,如果未能解决你的问题,请参考以下文章