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)Svoid 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;iCTRL)&(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 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();}