ARM Cortex-M3内核中有一个Systick定时器,它是一个24位(0~(2^24-1))的倒计数定时器,当计数到0时,它就会从Load寄存器中自动重装定时初值,只要不把CTRL寄存器中的ENABLE清0,它就永不停。
时钟源可以是内部时钟FCLK或外部时钟STCLK
配置系统定时器步骤:
①选择时钟源
②设定重载数(reload)
③开启中断
④启动滴答定时器
在core_cm3.h中有关于系统定时器的配置:
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) { if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); /* Reload value impossible */ } SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ return (0UL); /* Function successful */ }
可以通过系统定时器产生的时基用于延时功能的设置:
时基:1/72M 装值:SystemCoreClock /X X: 1000000 //10^(-6)----1us X: 100000 //10^(-5)----10us X: 1000 //10^(-3)----1ms u32 TimingDelay; void Systick_Init(void) { //判断是否大于72000000 if(SysTick_Config(SystemCoreClock /100000)) // 10us while(1); SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk ;//禁止定时器中断 } //1ms void Delay_ms(__IO u32 time) { TimingDelay =time*100; //1ms SysTick->CTRL |=SysTick_CTRL_ENABLE_Msk; while(TimingDelay !=0); SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk; } //1us void Delay_us(__IO u32 time) { TimingDelay =time; SysTick->CTRL |=SysTick_CTRL_ENABLE_Msk; while(TimingDelay !=0); SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk; } //中断服务函数 void SysTick_Handler(void) { if(TimingDelay!=RESET) TimingDelay--; }
不带中断的延时:
//不带中断进行精确延时 //全局变量 static u8 fac_us;//us级基数 --0~255 static u16 fac_ms;//ms级基数 --0~65536 //延时函数初始化 void Delay_init(void) { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//9MHz //SysTick->CTRL &= 0xfffffffb;--misc.c-199选择HCLK/8作为systick时钟 fac_us =SystemCoreClock/8000000;//9 fac_ms =(u16)fac_us*1000; } //us void Dealy_us(u32 nus)//nus--2^24/9 { u32 time; SysTick->CTRL = 0x00; //关闭SysTick定时器 SysTick->LOAD =nus*fac_us;//加载时间 SysTick->VAL =0x00; //清空计数器 //SysTick->CTRL |=0x01;//开定时器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//使能定时器 do { time =SysTick->CTRL; }while(time&0x01 && !(time&(1<<16)));//等待时间到达 SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;//失能定时器 SysTick->VAL =0x00;//清空计数器 } //ms void Dealy_us(u16 nms)//nms<=2^24/9000=1864 { u32 time; SysTick->CTRL = 0x00; //关闭SysTick定时器 SysTick->LOAD =(u32)nms*fac_ms;//加载时间 SysTick->VAL =0x00; //清空计数器 //SysTick->CTRL |=0x01;//开定时器 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//使能定时器 do { time =SysTick->CTRL; }while(time&0x01 && !(time&(1<<16)));//等待时间到达 SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;//失能定时器 //SysTick->CTRL = 0x00; //关闭SysTick定时器 SysTick->VAL =0x00;//清空计数器 }