1、系统滴答定时器的概述
滴答定时器又称 SysTick,有两个时钟源,一个为内部时钟,一个为外部时钟。滴答定时器是一个 24 位倒计
数的定时器,从预装载值一直到 0,重装载寄存器的值会自动装载到计数寄存器中。 只要不把它使能位清除,那
么它就永远不停,即使在芯片在睡眠模式下也能工作。
2、滴答定时器的内部框图

系统滴答定时器的是一个倒计数计数器,作用是:通过计数来定时。常用于:①操作系统的心跳时钟。②裸机代码中的简单定时。
STM32F407ZGT6的系统滴答定时器的计数频率为21MHZ或者为168MHZ。系统滴答定时器控制器有一个“自动重装载寄存器”,该寄存器是24位有效。
举例:假如系统滴答定时器的计数频率设置为21MHZ,定时1ms,需要计数21000,则将该值写入“自动重装载寄存器”。然后系统滴答定时器还有一个“当前值寄存器”,“当前值寄存器”加载“自动重装载寄存器”中的值,在每个时钟节拍下,“当前值寄存器”的置递减,递减到0,则定时时间到。
3、相关寄存器
详细资料在《Cortex M3 与 M4 权威指南》第 315 页
3.1、控制及状态寄存器(SysTick_CTRL)

举例:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,如何配置?
SysTick-》CTRL &=~(1《《2);
SysTick-》CTRL &=~(1《《1);
SysTick-》CTRL |= (1《《0);
3.2、自动重装载数据寄存器(SysTick_LOAD)

只有低 24 位有效,数值有效范围为 0-(2^24-1)。 当 SysTick 定时器倒计数到 0 时,该寄存器的值就会把计
数初始值重新加载到计数器中工作。
举例1:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,定时时间为1us,如何配置?
答1:
SysTick-》CTRL &=~(1《《2);
SysTick-》CTRL &=~(1《《1);
SysTick-》LOAD = 0; //清零
SysTick-》LOAD = 21; //计21次为1us
SysTick-》CTRL |= (1《《0);
举例2:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,最大定时时间是多少?
重装载数值寄存器的最大值是16777215,则最大定时时间是:(1/21000000)*16777215 = 0.798915秒。
3.3、当前值寄存器(SysTick_VAL)

这个寄存器同样只有低 24 位有效, SysTick 定时器倒计数寄存器。读取时返回当前倒计数的值,对这个寄存
器进行写操作,则使之清零,并对到零标志位清零。
3.4. 设置延迟时间
由上面寄存器可知,定时器计数的周期为 SysTick-LOAD 寄存器的值和选择的时钟源有关。例如:选择时钟频
率为 24MHz 的时钟,即周期为 1/24000000s,所以假如要实现定时 1s,则需要设置装载值为 24000000(1s=
(1/24000000) *24000000)。同理可得 1ms 需要设置装载值为 21000, 1us 需要设置装载值为 21。
4、软件设计
寄存器
#include “stm32f4xx.h”
void delay_ms(int ms)
{
SysTick-》CTRL &=~(1《《2);//选择时钟源为21MHZ
SysTick-》CTRL &=~(1《《1);//禁止滴答中断
SysTick-》LOAD = 21000*ms; //设置重装载寄存器的值
SysTick-》CTRL |= (1《《0);//使能滴答定时器
while(!(SysTick-》CTRL&(1《《16)));//阻塞判断定时时间是否到达,判断SysTick-》CTRL的位
}
int main(void)
{
LED_Init();
while(1)
{
GPIOF-》ODR |= (1《《6);//GPIOF_ODR的位6置1则输出高电平
Delay_ms(500);//延时500ms
GPIOF-》ODR &= ~(1《《6);//GPIOF_ODR的位6清零则输出低电平
Delay_ms(500);//延时500ms
}
}
void delay_s(int s)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //选择时钟
SysTick-》VAL =0;
SysTick-》LOAD =s*24000000; //设置预装载值
SysTick-》CTRL =1; //使能滴答定时器
while(!(SysTick-》CTRL &(1《《16))); //等待计数完成
SysTick-》CTRL =0; //失能滴答定时器
}
void delay_ms(int ms)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
SysTick-》VAL =0;
SysTick-》LOAD =ms*24000;
SysTick-》CTRL =1;
while(!(SysTick-》CTRL &(1《《16)));
SysTick-》CTRL =0;
}
void delay_us(int us)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
SysTick-》VAL =0;
SysTick-》LOAD =us*24;
SysTick-》CTRL =1;
while(!(SysTick-》CTRL &(1《《16)));
SysTick-》CTRL =0;
}
int main(void)
{
LED_Init();
while(1)
{
GPIO_SetBits(GPIOF,GPIO_Pin_9);
delay_s(2);
GPIO_ResetBits(GPIOF,GPIO_Pin_9);
delay_s(2);
}
}
1、系统滴答定时器的概述
滴答定时器又称 SysTick,有两个时钟源,一个为内部时钟,一个为外部时钟。滴答定时器是一个 24 位倒计
数的定时器,从预装载值一直到 0,重装载寄存器的值会自动装载到计数寄存器中。 只要不把它使能位清除,那
么它就永远不停,即使在芯片在睡眠模式下也能工作。
2、滴答定时器的内部框图

系统滴答定时器的是一个倒计数计数器,作用是:通过计数来定时。常用于:①操作系统的心跳时钟。②裸机代码中的简单定时。
STM32F407ZGT6的系统滴答定时器的计数频率为21MHZ或者为168MHZ。系统滴答定时器控制器有一个“自动重装载寄存器”,该寄存器是24位有效。
举例:假如系统滴答定时器的计数频率设置为21MHZ,定时1ms,需要计数21000,则将该值写入“自动重装载寄存器”。然后系统滴答定时器还有一个“当前值寄存器”,“当前值寄存器”加载“自动重装载寄存器”中的值,在每个时钟节拍下,“当前值寄存器”的置递减,递减到0,则定时时间到。
3、相关寄存器
详细资料在《Cortex M3 与 M4 权威指南》第 315 页
3.1、控制及状态寄存器(SysTick_CTRL)

举例:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,如何配置?
SysTick-》CTRL &=~(1《《2);
SysTick-》CTRL &=~(1《《1);
SysTick-》CTRL |= (1《《0);
3.2、自动重装载数据寄存器(SysTick_LOAD)

只有低 24 位有效,数值有效范围为 0-(2^24-1)。 当 SysTick 定时器倒计数到 0 时,该寄存器的值就会把计
数初始值重新加载到计数器中工作。
举例1:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,定时时间为1us,如何配置?
答1:
SysTick-》CTRL &=~(1《《2);
SysTick-》CTRL &=~(1《《1);
SysTick-》LOAD = 0; //清零
SysTick-》LOAD = 21; //计21次为1us
SysTick-》CTRL |= (1《《0);
举例2:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,最大定时时间是多少?
重装载数值寄存器的最大值是16777215,则最大定时时间是:(1/21000000)*16777215 = 0.798915秒。
3.3、当前值寄存器(SysTick_VAL)

这个寄存器同样只有低 24 位有效, SysTick 定时器倒计数寄存器。读取时返回当前倒计数的值,对这个寄存
器进行写操作,则使之清零,并对到零标志位清零。
3.4. 设置延迟时间
由上面寄存器可知,定时器计数的周期为 SysTick-LOAD 寄存器的值和选择的时钟源有关。例如:选择时钟频
率为 24MHz 的时钟,即周期为 1/24000000s,所以假如要实现定时 1s,则需要设置装载值为 24000000(1s=
(1/24000000) *24000000)。同理可得 1ms 需要设置装载值为 21000, 1us 需要设置装载值为 21。
4、软件设计
寄存器
#include “stm32f4xx.h”
void delay_ms(int ms)
{
SysTick-》CTRL &=~(1《《2);//选择时钟源为21MHZ
SysTick-》CTRL &=~(1《《1);//禁止滴答中断
SysTick-》LOAD = 21000*ms; //设置重装载寄存器的值
SysTick-》CTRL |= (1《《0);//使能滴答定时器
while(!(SysTick-》CTRL&(1《《16)));//阻塞判断定时时间是否到达,判断SysTick-》CTRL的位
}
int main(void)
{
LED_Init();
while(1)
{
GPIOF-》ODR |= (1《《6);//GPIOF_ODR的位6置1则输出高电平
Delay_ms(500);//延时500ms
GPIOF-》ODR &= ~(1《《6);//GPIOF_ODR的位6清零则输出低电平
Delay_ms(500);//延时500ms
}
}
void delay_s(int s)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //选择时钟
SysTick-》VAL =0;
SysTick-》LOAD =s*24000000; //设置预装载值
SysTick-》CTRL =1; //使能滴答定时器
while(!(SysTick-》CTRL &(1《《16))); //等待计数完成
SysTick-》CTRL =0; //失能滴答定时器
}
void delay_ms(int ms)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
SysTick-》VAL =0;
SysTick-》LOAD =ms*24000;
SysTick-》CTRL =1;
while(!(SysTick-》CTRL &(1《《16)));
SysTick-》CTRL =0;
}
void delay_us(int us)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
SysTick-》VAL =0;
SysTick-》LOAD =us*24;
SysTick-》CTRL =1;
while(!(SysTick-》CTRL &(1《《16)));
SysTick-》CTRL =0;
}
int main(void)
{
LED_Init();
while(1)
{
GPIO_SetBits(GPIOF,GPIO_Pin_9);
delay_s(2);
GPIO_ResetBits(GPIOF,GPIO_Pin_9);
delay_s(2);
}
}
举报