Cortex‐M3的内核中包含一个SysTick时钟。SysTick 为一个24位递减计数器,SysTick设定初值并使能后,每经过1个系统时钟周期,计数值就减1。计数到0时,SysTick计数器自动重装初值并继续计数,同时内部的COUNTFLAG标志会置位,触发中断(如果中断使能)。 在STM32的应用中,使用Cortex‐M3 内核的SysTick作为定时时钟,设定每一毫秒产生一次中断,在中断处理函数里对N减一,在Delay(N)函数中循环检测N是否为0,不为0则进行循环等待;若为0则关闭SysTick时钟,退出函数。
外部晶振为8MHz,9倍频,系统时钟为72MHz,SysTick的最高频率为9MHz(最大为HCLK/8),在这个条件下,把SysTick 效验值设置成9000,将SysTick 时钟设置为9MHz, 就能够产生1ms的时间基值,即SysTick产生1ms的中断。
使用ST的函数库使用systick的方法
1、调用SysTick_CounterCmd() 失能SysTick计数器
2、调用SysTick_ITConfig () 失能SysTick中断
3、调用SysTick_CLKSourceConfig() 设置SysTick时钟源。
4、调用SysTick_SetReload() 设置SysTick重装载值。
5、调用SysTick_ITConfig () 使能SysTick中断
6、调用SysTick_CounterCmd() 开启SysTick计数器
SysTick设置:
void SysTick_Config(void) { /* Disable SysTick Counter */ SysTick_CounterCmd(SysTick_Counter_Disable); /* Disable the SysTick Interrupt */ SysTick_ITConfig(DISABLE); /* Configure HCLK clock as SysTick clock source */ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); /* SysTick interrupt each 1000 Hz with HCLK equal to 72MHz*/ SysTick_SetReload(9000); /* Enable the SysTick Interrupt */ SysTick_ITConfig(ENABLE); }
全局变量TimingDelay ,必须定义为volatile:
volatile u32 TimingDelay;
Delay_Ms 延迟一毫秒函数:
void Delay_Ms(u32 nTime) { /* Enable the SysTick Counter */ SysTick_CounterCmd(SysTick_Counter_Enable); TimingDelay = nTime; while(TimingDelay != 0); /* Disable SysTick Counter */ SysTick_CounterCmd(SysTick_Counter_Disable); /* Clear SysTick Counter */ SysTick_CounterCmd(SysTick_Counter_Clear); }
TimingDelayMs_Decrement中断调用函数:
void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay‐‐; } }
SysTickHandler 中断进入函数:
void SysTickHandler(void) { TimingDelay_Decrement(); }
NVIC_Configuration 中断向量表配置:
void NVIC_Configuration(void) { #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif }
以上是用库函数2.0.3版本,升级到3.5.0版本后没有SysTick_CounterCmd库函数,需要手动移植。
/* SysTick counter state */ #define SysTick_Counter_Disable ((u32)0xFFFFFFFE) #define SysTick_Counter_Enable ((u32)0x00000001) #define SysTick_Counter_Clear ((u32)0x00000000) void SysTick_CounterCmd(u32 SysTick_Counter) { /* Check the parameters */ assert_param(IS_SYSTICK_COUNTER(SysTick_Counter)); if (SysTick_Counter == SysTick_Counter_Enable) { SysTick->CTRL |= SysTick_Counter_Enable; } else if (SysTick_Counter == SysTick_Counter_Disable) { SysTick->CTRL &= SysTick_Counter_Disable; } else /* SysTick_Counter == SysTick_Counter_Clear */ { SysTick->VAL = SysTick_Counter_Clear; } }
延时函数:
void delay_ms(volatile uint32_t nTime) { SysTick_CounterCmd(SysTick_Counter_Clear); SysTick_CounterCmd(SysTick_Counter_Enable); TimingDelay = nTime; while(TimingDelay != 0); SysTick_CounterCmd(SysTick_Counter_Disable); }
初始化SysTick也有些区别:
void Init_SysTick(void) { if(SysTick_Config(SystemCoreClock / 1000)) //初始化成功后返回0 while(1); SysTick_CounterCmd(SysTick_Counter_Disable); }
中断服务函数基本一样。