SysTick定时器
CM3的内核中有一个systick定时器,它是一个24位倒数定时器,当计数到0是将从RELOAD 寄存器中自动重装载定时初值,开始新一轮计数。只要不把它在 SysTick 控制及状态寄存器中的使能位清除,就永不停息。大多数时候都用这个计数器作为精确延时来使用,不需要占用中断,也不占用系统定时器。
SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。Systick中断的优先级也可以设置。
使用systick需要操作的寄存器:
CTRL SysTick 控制和状态寄存器
对于STM32,外部时钟源是 HCLK(AHB总线时钟)的1/8,内核时钟是 HCLK时钟
配置函数:SysTick_CLKSourceConfig(); //Systick时钟源选择 misc.c文件中
LOAD SysTick 自动重装载除值寄存器 //倒数至0的时候将被重新装载的值
VAL SysTick 当前值寄存器 //读取当前计数器的值,写它清零同时清除第一个寄存器的第16位
为了不占用中断,一般这样延时:
static int fac_us;
static int fac_ms;
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SystemCoreClock/8000000; //微秒计时的基准值,因为时钟位系统时钟的1/8所以/8000000
fac_ms=fac_us*1000; //毫秒计时的基准值
}
void delay_us(u16 us)
{
u32 temp;
SysTick->LOAD=fac_us*us; //通过微秒基准值计算计数器中的数
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //使能
do
{
temp=SysTick->CTRL; //读取CTRL寄存器
}while((temp&0x01)&&!(temp&(1<<16))); //第一个是保证计数器使能了,当计数器计数到零的时候第十六位会置1,从而知道计数结束
SysTick->CTRL=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL=0x00; //清空计数器
}
void delay_ms(u16 ms) //msخճֵΪ1864
{
u32 temp;
SysTick->LOAD=fac_ms*ms; //通过毫秒基准值计算计数器中的数
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //使能
do
{
temp=SysTick->CTRL; //读取CTRL寄存器
}while((temp&0x01)&&!(temp&(1<<16))); //第一个是保证计数器使能了,当计数器计数到零的时候第十六位会置1,从而知道计数结束
SysTick->CTRL=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL=0x00; //清空计数器
}
这样就可以延时了,SysTick还可以计算程序运行的时间,这里就不涉及了,后面在嵌入式系统中会讲到。