SysTick是内核的一个外设,内嵌在NVIC中,它是一个24位向下递减的定时器,每计数一次的事件位1/SYSCLK(一般为72M),当重装载寄存器的值递减到0时,系统定时器就产生一次中断,循环往复,这个定时器一般用于操作系统来产生时基以维持心跳。
CTRL:控制及状态寄存器
LOAD:重装载数值寄存器
VAL:当前数值寄存器
CALIB:校准数值寄存器:暂不讨论
bsp_systick.h:
#ifndef __SYSTICK_H #define __SYSTICK_H #include"stm32f10x.h" void SysTick_Init(void); void Delay_us(__IO u32 nTime); void SysTick_Delay_Us( __IO uint32_t us); void SysTick_Delay_Ms( __IO uint32_t ms); #endif
bsp_systick.c:
#include "bsp_systick.h" #include "core_cm3.h" #include "misc.h" static __IO u32 TimeDelay; //这个函数主要是产生一次中断的时间,因为是72M的频率的话,计数一次的时间位1/72M //重装载寄存器里的值就是计数次数,(计数次数)/(系统频率72M)=一次中断的时间 void SysTick_Init(void) { /* SystemFrequency / 1000 1ms * SystemFrequency / 100000 10us * SystemFrequency / 1000000 1us */ //下面这个参数就是计数次数,720/72M=1/100000秒 //简化得之:分母为X,中断一次的时间为1/X秒 if (SysTick_Config(SystemCoreClock / 100000)) { while (1); } } //nTime: Delay_us( 1 )产生的延时为1*(1/100000)S void Delay_us(__IO u32 nTime) { TimeDelay = nTime; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; while(TimeDelay != 0); } // 这个函数用于被中断处理函数调用,产生一次中断,这个函数就会被调用一次,获得时基 //以此来达到延时(nTime*时基)的目的 void TimeDelay_Decrement(void) { if (TimeDelay != 0x00) { TimeDelay--; } } //寄存器版本的微秒延时 不需要用到中断处理函数 //在SysTick_Config函数里就会一直计数,重装载,计数 //来产生连续的时基,以维持心跳 void SysTick_Delay_Us( __IO uint32_t us) { uint32_t i; SysTick_Config(SystemCoreClock/1000000); for(i=0;i<us;i++) { while( !((SysTick->CTRL)&(1<<16)) ); } 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++) { while( !((SysTick->CTRL)&(1<<16)) ); } SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk; }
main.c:
#include"stm32f10x.h" #include"bsp_led.h" #include"bsp_systick.h" int main(void) { LED_GPIO_Config(); SysTick_Init(); while(1) { red(ON); Delay_us(100000); red(OFF); green(ON); SysTick_Delay_Us(1000000); green(OFF); blue(ON); SysTick_Delay_Ms(1000); blue(OFF); } }
中断处理函数:
void SysTick_Handler(void) { TimeDelay_Decrement(); }