先写一些,有时间再慢慢补充
SysTick,系统滴答定时器,也可以称为
Cortex System Timer
System Tick Timer
SysTick包含在M3/M4/M7内核里,核心是一个24位的递减计数器
SysTick有三个寄存器,分别是
CTRL,control and status register,控制及状态寄存器
LOAD,重装载寄存器
VAL,current value register,当前值寄存器
下面以F1为例
#define SysClock_Frequency 72
uint32_t g_TimesPerUs;//全局变量,自动重装值值,每个us中SysTick需要递减的次数
//例如,HCLK时钟频率为72MHz,8分频后,时钟频率为9MHz
//每个时钟周期为(1/9M)s=(1/9)us,所以9个时钟周期就是1us,所以SysTick递减9次
void delay_int(void)
{
SysTick -> CTRL = 0; //将控制及状态寄存器清零
//下面这一句选择时钟源频率为 HCLK/8,其实不写这一句也可以
//因为CTRL=0已经包括了这个配置,将这句写出来应该只是为了方便阅读
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);
g_TimesPerUs = SysClock_Frequency/8;
}
void delay_us(uint32_t nus)
{
uint32_t temp;
SysTick -> LOAD = nus * g_TimesPerUs;
SysTick -> VAL = 0; //计数器清零
SysTick -> CTRL |= (1<<0); //使能定时器SysTick
do
{
temp = SysTick -> CTRL; //将CTRL寄存器的值赋给temp
}while(!(temp & (1<<16))); //退出循环条件:标志位为1
SysTick -> CTRL &= ~(1<<0); //失能定时器SysTick
SysTick -> VAL = 0; //计数器清零
}
//在不进行重装,HCLK=72Mhz的情况下,SysTick最多延时(1/9M)*(2^24)=1.86s
//使用下面这种方法是可以的,但是下面这种方法没有进行重装载,最多只能延时1.86s
void delay_ms(uint32_t nms)
{
uint32_t temp;
SysTick -> LOAD = nms * g_TimesPerUs * 1000; //设置重装载值
SysTick -> VAL = 0; //计数器清零
SysTick -> CTRL |= (1<<0); //使能定时器SysTick
do
{
temp = SysTick -> CTRL; //将CTRL寄存器的值赋给temp
}while(!(temp & (1<<16))); //退出循环条件:标志位为1
SysTick -> CTRL &= ~(1<<0); //失能定时器SysTick
SysTick -> VAL = 0; //计数器清零
}
如果想延时超过1.86s,就需要用下面这种方法
void delay_ms(uint32_t nms)
{
uint32_t repeat = nms / 1000;
uint32_t remain = nms % 1000;
for(; repeat ; repeat--)
{
delay_us(1000 * 1000); //1000000us=1000ms=1s
}
if(remain)
{
delay_us(remain * 1000);
}
}
一个小细节:
SysTick -> CTRL |= (1<<0); //使能定时器SysTick,只改变位0,不改变其他位
SysTick -> CTRL &= ~(1<<0); //失能定时器SysTick,只改变位0,不改变其他位