1、简介
Cortex‐M3处理器内部包含了一个简单的定时器。因为所有的CM3芯片都带有这个定时器,软件在不同 CM3器件间的移植工作得以化简。该定时器的时钟源可以是内部时钟,或者是外部时钟。不过,STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同,你需要查找芯片的器件手册来决定选择什么作为时钟源。
Cortex-M3 的内核中包含一个 SysTick 时钟。SysTick 为一个 24 位递减计数器,SysTick 设定初值并使能后,每经过 1 个系统时钟周期,计数值就减 1。计数到 0 时,SysTick 计数器自动重
装初值并继续计数,同时内部的 COUNTFLAG 标志会置位,触发中断 (如果中断使能情况下)。
2、SysTick包含的寄存器
STM32中的Systick 部分内容属于NVIC控制部分,一共有4个寄存器,名称和地址分别是:
STK_CTRL, 0xE000E010 -- 控制和状态寄存器
STK_LOAD, 0xE000E014 -- 重载寄存器
STK_VAL, 0xE000E018 -- 当前值寄存器
STK_CALRB, 0xE000E01C -- 校准值寄存器
(1)STK_CTRL控制和状态寄存器:寄存器内有4个位具有意义
第0位:ENABLE,Systick 使能位(0:关闭Systick功能;1:开启Systick功能)
第1位:TICKINT,Systick 中断使能位(0:关闭Systick中断;1:开启Systick中断)
第2位:CLKSOURCE,Systick时钟源选择(0:使用HCLK/8 作为Systick时钟;1:使用HCLK作为Systick时钟)
第16位:COUNTFLAG,Systick计数比较标志,如果在上次读取本寄存器后,SysTick 已经数到了0,则该位为1。如果读取该位,该位将自动清零
(2)STK_LOAD 重载寄存器
Systick是一个递减的定时器,当定时器递减至0时,重载寄存器中的值就会被重装载,继续开始递减。STK_LOAD 重载寄存器是个24位的寄存器最大计数0xFFFFFF(因此范围为1~16777216。)。
(3)STK_VAL当前值寄存器
也是个24位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick 控制及状态寄存器中的COUNTFLAG 标志。
(4)STK_CALRB 校准值寄存器(用于校准,不常用)
/****************************************************************************
* 名 称:delay_us(u32 nus)
* 功 能:微秒延时函数
* 入口参数:u32 nus
* 出口参数:无
* 说 明:
* 调用方法:无
****************************************************************************/
void delay_us(u32 nus)
{
u32 temp;
//因为这里采用八分频,所以SysTick时钟就为72MHz÷8=9MHz,即9000000Hz,也就意味着1s时间内,会计数9000000次,那么1us,也就是计数9次
SysTick->LOAD = 9*nus;
//清空计数器
SysTick->VAL = 0x00;
//使能systick定时器,减到零是无动作,采用外部时钟源
//第0位:SysTick使能位,为1开启SysTick功能 (0则关闭)
//第1位:SysTick中断使能位,为1开启SysTick中断 (0则关闭)
//第2位:SysTick时钟源选择,0:使用HCLK/8作为SysTick时钟;1:使用HCLK作为SysTick时钟
//16位:计数比较标志,如果上次读取本寄存器后,SysTick已经数到了0,则该位为1。如果读取该位,该位将自动清零
SysTick->CTRL = 0x01;
do
{
temp = SysTick->CTRL;//读取当前倒计数值,如果减到了0,该寄存器第16位就会置为1
}while(temp&(0x01) && ( !(temp&(1<<16)) ));
//关闭计数器
SysTick->CTRL = 0x00;
//清空计数器
SysTick->VAL = 0;
}
/****************************************************************************
* 名 称:delay_ms(u32 nms)
* 功 能:微秒延时函数
* 入口参数:u32 nms
* 出口参数:无
* 说 明:
* 调用方法:无
****************************************************************************/
void delay_ms(u32 nms)
{
u32 temp;
//因为这里采用八分频,所以SysTick时钟就为72MHz÷8=9MHz,即9000000Hz,也就意味着1s时间内,会计数9000000次,那么1ms,也就是计数9000次
SysTick->LOAD = 9000*nms;
//清空计数器
SysTick->VAL = 0x00;
//使能systick定时器,减到零是无动作,采用外部时钟源
SysTick->CTRL = 0x01;
do
{
temp = SysTick->CTRL;//读取当前倒计数值
}while(temp&(0x01) && ( !(temp&(1<<16)) ));
//关闭计数器
SysTick->CTRL = 0x00;
//清空计数器
SysTick->VAL = 0;
}