stm32滴答计时器_第三讲 STM32 SysTick---系统滴答定时器

本文详细介绍了STM32的系统滴答定时器Systick,包括其功能、工作原理和相关寄存器。通过Systick配置实现精确延时,并给出在流水灯应用中的示例代码,展示了如何利用Systick进行微秒级别的延时控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Systick简介

Systick也叫系统滴答定时器,滴答定时器就是一个非常基本的倒计时定时器。它存在的意义是为系统提供一个时基,能够给操作系统提供一个硬件上的中断。使用Systick能够精准延时,对于时间要求严格的场所,意义十分重大,我将写一个流水灯改进版----精确延时(可调控)的流水灯。

二、Systick timer

Systick是一个24位的定时器,一次最多可以计数2^24个时钟脉冲,这个脉冲计数值保存在当前计数值寄存器STK_VAL(Systick current value register)中,只能向下计数,每接收到一个时钟脉冲,STK_VAL的值就会向下减1,当减到0时,硬件会自动把重装载寄存器STK_LOAD(Systick reload value register)中保存的数据加载到STK_VAL,重新开始向下计数。如果STK_VAL的值被减至0时,会触发异常产生中断。

三、相关寄存器介绍

除了上面说的STK_VAL,下面带大家了解相关的寄存器和寄存器位。

1.  SysTick_CSR       控制状态寄存器

Bit0: ENABLE

SysTick timer的使能位,1使能Systick timer,0关闭Systick timer

Bit1: TICKINT

异常触发使能位,TICKINT=1,STK_VAL计数到0触发异常;TICKINT=0,不触发异常

Bit2: CLKSOURCE

Systick时钟选择位,SysTick = 1,时钟为AHB时钟;0时钟位AHB/8

Bit16:COUNTFLAG

计数为0标志位, 当STK_VAL计数到0,此标志位会被置1

2. SysTick_LOAD      重装载寄存器

0-23 24位的重装值,这也是为什么只能计数到2^24

3.  SysTick_VAL    当前值寄存器

4.  SysTick_CALRB    校准寄存器

由于我们要写精确延时的LED流水灯,所以我们需要使用Systick进行精确延时,理论上它的最小计时单位为AHB的时钟周期,1/72000000秒,72分之一微秒。

我们在昨天流水灯的基础上,新建两个文件,SysTick.c和SysTick.h

具体代码如下

SysTick.h

#ifndef __SYSTICK_H__

#define __SYSTICK_H__

#include "stm32f10x.h"

void SysTick_Init(void);

void Delay_us(__IO u32 nTime);

#endif

SysTick.c

#include "SysTick.h"

#include "stm32f10x.h"

static __IO u32 TimingDelay;

void SysTick_Init(void)

{

if(SysTick_Config(SystemCoreClock/100000))

{

while(1);

}

//关闭滴答定时器

SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;

}

void TimingDelay_Decrement(void)

{

if(TimingDelay != 0x00)

{

TimingDelay--;

}

}

void Delay_us(__IO u32 nTime)

{

TimingDelay = nTime;

//使能滴答定时器

SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

while(TimingDelay != 0);

}

中断函数,在stm32f10xit.c

void SysTick_Handler(void)

{

TimingDelay_Decrement();

}

修改main.c如下

#include "stm32f10x.h"

#include "led.h"

#include "SysTick.h"

int main(void)

{

//LED端初始化

LED_GPIO_Config();

//配置SysTick为10us中断一次

SysTick_Init();

while(1)

{

LED1(0);

Delay_us(50000);

LED1(1);

LED2(0);

Delay_us(50000);

LED2(1);

LED3(0);

Delay_us(50000);

LED3(1);

LED4(0);

Delay_us(50000);

LED4(1);

}

}

这里面只有两个函数,SysTick_Init()和Delay_us(),一个是配置SysTick定时器,一个是进行精确延时

中断函数也只是运行了一个自定义函数,看看不难理解

SysTick_Config(SystemCoreClock/100000);

SystemCoreClock是系统时钟的宏,SystemCoreClock = 72000000

我们的计时总时间 T = tick * (1/f),tick为SysTick_Config()的输入参数

1/f为SysTick timer使用的时钟源的时钟周期,f为该时钟源的时钟频率。

上面的语句中:tick = SystemCoreClock/100000=720,表示720个时钟周期中断一次,1/f是时钟周期的时间,1/f = 1/72us,所以T = 720*(1/72) = 10us

SysTick_CTRL_ENABLE_Msk,这是一个宏,用来指示寄存器的特定位置或进行位屏蔽用的,那么他是如何定义的呢?

其中的寄存器位指示宏:SysTick_xxx_Pos, 宏展开后为xxx在相应寄存器中的位置,如控制SysTick时钟源的SysTick_CTRL_CLKSOURCE_Pos,宏展开后为2,正好是SysTick_CSR中的Bit2

寄存器的位屏蔽宏:SysTick_xxx_Msk,宏展开是xxx的位全部置1后,左移SysTick_xxx_Pos位,1ul使之无符号长整型,上图中SysTick_CTRL_CLKSOURCE_Msk,宏展开为1ul<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值