STM32 学习9 SysTick 定时器
Posted 编程圈子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32 学习9 SysTick 定时器相关的知识,希望对你有一定的参考价值。
STM32 学习8 SysTick 定时器
一、介绍
SysTick定时器,又称为SysTick滴答定时器,它是Cortex-M3内核的一个外设,嵌入在NVIC中。
SysTick是24位向下递减的定时器,计数一次需要的时间是 1/SYSTICK , SYSTICK是系统定时器时钟,取自系统时钟或者系统时钟8分频后值。
定时器计数到0时,会产生一个中断信号,并从LOAD寄存器中自动重装定时器初值,重新计数。
SysTick定时器可服务于操作系统、倒计时等使用。
二、SysTick定时器寄存器
1. CTRL 寄存器
Sys Tick定时器的控制及状态寄存器。
- 16位段: 名称 COUNTFLAG , 类型 R, 复位值: 0 ,如果上次读取本寄存器后,Sys Tick已经数到了0,则该位为1, 如果读取该位,该位将自动清零。
- 2 位段: CLKSOURCE , 类型 R/W, 0=外部时钟源,1=内核时钟
- 1 位段: TICKINT , 类型: R/W, 1=SysTick倒数到0,产生中断; 0 数到0无动作
- 0位段: ENABLE,类型: R/W, SysTick定时器的使能位。
2. LOAD 寄存器
重装载数值计数器,位段: 23:0 , 类型 R/W。
3. VAL 寄存器
当前数值寄存器,位段: 23:0, 类型 R/Wc, 写值就会清零,同时清除SysTick控制及状态寄存器中的COUNTFLAG状态。
4. CALIB 寄存器
SysTick定时器的校准数值寄存器。
三、SysTick定时器的配置步骤
-
- 设置是时钟源
-
- 设置SysTick定时器的重装载初始值
-
- 清零当前计数器值
-
- 打开SysTick定时器
四、相关函数
1. HAL_SYSICK_Config
设置定时时间,用法:
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);// 设置定时时间
重
装
载
值
=
s
y
s
t
i
c
k
时
钟
频
率
(
H
z
)
∗
想
要
的
定
时
时
间
(
S
)
重装载值=systick 时钟频率(Hz) * 想要的定时时间(S)
重装载值=systick时钟频率(Hz)∗想要的定时时间(S)
如:时钟频率为:AHB的8分频;AHB=72MHz
那么systick的时钟频率为72/8MHz=9MHz;
要定时1秒,则重装载值=9000000*1=9000000;
定时10毫秒,重装载状态值=9000000X0.01=90000
2. HAL_SYSTICK_CLKSourceConfig
选择时钟源,用法:
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//选择SYSTICK时钟源,
/* SysTick_IRQn interrupt configuration */
可选值:
#define SYSTICK_CLKSOURCE_HCLK_DIV8 (0x00000000U)
#define SYSTICK_CLKSOURCE_HCLK (0x00000004U)
3. HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
作用:设定优先级
五、延时函数SysTick.c
1. SysTick_Init 初始化
#include "SysTick.h"
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数
void SysTick_Init(u8 SYSCLK){
// 选择时钟源
SysTick_CLKSourceCOnfig(SysTick_CLKSource_HCLK_Div8);
// 微秒,定义公用变量
fac_us=SYSCLK/8;
// 计算毫秒重装载值
fac_ms=(u16)fac_us*1000;
}
2. delay_us() 函数
/*******************************************************************************
* 函 数 名 : delay_us
* 函数功能 : us延时,
* 输 入 : nus:要延时的us数
注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21)
* 输 出 : 无
*******************************************************************************/
void delay_us(u32 nus)
{
u32 temp;
// 装载初值
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开启定时器,开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
3. delay_ms
/*******************************************************************************
* 函 数 名 : delay_ms
* 函数功能 : ms延时,
* 输 入 : nms:要延时的ms数
注意:nms的值,SysTick->LOAD为24位寄存器,
不要大于0xffffff*8*1000/SYSCLK
对72M条件下,nms<=1864ms
* 输 出 : 无
*******************************************************************************/
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
4. 头文件定义
#ifndef _SysTick_H
#define _SysTick_H
#include "system.h"
void SysTick_Init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);
#endif
5. 使用 main.c
#include "SysTick.h"
#include "led.h"
int main()
{
SysTick_Init(72);
// 这里使用了位绑定,后面章节会介绍。
LED_Init();
while(1)
{
led1=0;
led2=1;
delay_ms(500); //精确延时500ms
led1=1;
led2=0;
delay_ms(500); //精确延时500ms
}
}
以上是关于STM32 学习9 SysTick 定时器的主要内容,如果未能解决你的问题,请参考以下文章