关于Cortex系统定时器(SysTick)

  在“亮灯仪式”之后,接下来就要尝试为LED小灯添加延时以实现亮灭的效果。

  与传统51相比,事实上STM32的延时大多也采用C语言循环体的方式来进行延时,但是STM32同时也存在计时器进行计时,这一点和定时器中断有点类似。接下来我们就要开始学习一下传说中的“嘀嗒计时器”啦!

传说中的“嘀嗒计时器”

  如果你的STM32芯片有操作系统,那么“嘀嗒计时器”可用来切换系统。当然了,我们也可以用来延时,用法与传统51的定时器很类似。我们需要调用相应的函数来使用对应的寄存器,具体的使用在官方文档里有体现。

  这里我们附上源码来说明:

/*****delay.h*****/
#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"

void delay_s(u16 s);
void delay_ms(u16 ms);
void delay_us(u32 us);

#endif
/*****delay.c*****/
/*
//杜洋工作室出品
//洋桃系列开发板应用程序
//关注微信公众号:洋桃电子
//洋桃开发板资料下载 www.DoYoung.net/YT
//即可免费看所有教学视频,下载技术资料,技术疑难提问
//更多内容尽在 杜洋工作室主页 www.doyoung.net
*/

/*
《修改日志》
1-201708271933 加入了秒延时函数。
2-201712260223 加入延时前计数器值清0,解决连续用uS延时的BUG问题。
*/

#include "delay.h"
#define AHB_INPUT 72 //请按RCC中设置的AHB时钟频率填写到这里(单位MHz)

void delay_us(u32 uS){ //uS微秒级延时程序(参考值即是延时数,72MHz时最大值233015)
SysTick->LOAD=AHB_INPUT*uS; //重装计数初值(当主频是72MHz,72次为1微秒)
SysTick->VAL=0x00; //清空定时器的计数器
SysTick->CTRL=0x00000005;//时钟源HCLK,打开定时器
while(!(SysTick->CTRL&0x00010000)); //等待计数到0
SysTick->CTRL=0x00000004;//关闭定时器
}

void delay_ms(u16 ms){ //mS毫秒级延时程序(参考值即是延时数,最大值65535)
while( ms-- != 0){
delay_us(1000); //调用1000微秒的延时
}
}

void delay_s(u16 s){ //S秒级延时程序(参考值即是延时数,最大值65535)
while( s-- != 0){
delay_ms(1000); //调用1000毫秒的延时
}
}

/*****************************
* 杜洋工作室 www.DoYoung.net
* 洋桃电子 www.DoYoung.net/YT
*****************************/

  在例程里面我们可以看到,delay函数共分成了delay_us,delay_ms和delay_s三个部分。这里设计的精妙之处在于这三个函数是用层级关系相互嵌套,由例程可知,后面两个部分的延时都是依靠最开始的delay_us,所以我们接下来只要研究delay_us即可。

SysTick寄存器的使用

  根据文档说明,“嘀嗒定时器”还由四个寄存器组成。