目录
延时函数编程思想
- 利用SysTick 定时器,SysTick 是一个 24 位的倒计数定时器。
- 当计数到 0 时,将从 RELOAD 寄存器中自动重装载定时初值,开始新一轮计数。
SisTick定时器
SysTick->CTRL(控制状态寄存器)
COUNTFLAG(计数标志位)
- 段位:16 类型:R 复位值:0
- 使用1:如SisTick已经倒数到了0,则该位为1
- 使用2:如读取该位,该位将自动清零
CLKSOURCE(时钟源选择)
- 段位:2 类型:R/W 复位值:0
- 使用1: 0=外部时钟源(STCLK)
- 使用2: 1=内核时钟(FCLK)
TICKINT(中断请求)
- 段位:1 类型:R/W 复位值:0
- 使用1: 0=数到0时无动作
- 使用2: 1=数到0产生中断请求
ENABLE(定时器使能)
- 段位:0 类型:R/W 复位值:0
- 使用: 定时器使能
SysTick->LOAD(重装载数值寄存器)
RELOAD(重装载)
- 段位:0 类型:R/W 复位值:0
- 使用1: 当倒数至零时,将被重装载的值
SysTick->VAL(当前值寄存器)
CURRENT(当前值)
- 段位:0 类型:R/W 复位值:0
- 使用1:读取返回当前倒计数的值,写它则使之清零
- 使用2:同时还会清除在SisTick控制及状态寄存器中的COUNTFLAG标志
delay函数
代码示例
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //每个 us 需要的 systick 时钟数
fac_ms=(u16)fac_us*1000; //每个 ms 需要的 systick 时钟数
}
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //装载值时间
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开启SisTick
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //倒计时结束
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭SisTick
SysTick->VAL =0X00; //清空计数器
}
代码解释
时钟源配置函数:SysTick_CLKSourceConfig();
- 外部时钟源是 HCLK(AHB总线时钟)的1/8,HCLK为72Mhz,故SisTick时钟节拍为9Mhz
- 通过fac_us=SystemCoreClock/8000000; 计算得1us有9个SysTick 时钟周期
- 故延迟几微妙 就乘以几个 9装入LOAD中即可,而毫秒再乘1000即可