在STM32单片机中,实现延时一般都是使用定时器,既可以使用Systick定时器,也可以使用常规的定时器。

定时器在设置了定时并开启之后,就会进入自主运行模式,其中,初始化设置这一阶段是由CPU执行相应指令完成的,之后,定时器外设就会自行计数,这个过程中,CPU就不需要再参与了。这一过程,不管定时器有没有配置中断,定时器都会独立于CPU自主工作。

那么,定时器配置中断和不配置中断有什么区别呢?

定时器在工作时,我们怎么知道有没有到达定时时间呢?因为我们需要判断是否到达,然后据此触发一些相应的动作。如果不配置中断,就需要CPU去不断判断定时器状态标志位是否被置位,这时候,才需要CPU的参与,这就是常说的轮询,效率不高;如果配置了中断,就不用CPU去轮询,定时器模块完成计时的时候,就会给CPU发一个中断通知,然后CPU再去处理中断事务,也就是说,不需要CPU去轮询。

所以,CPU参与不是为了实现定时,而只是去判断定时器有没有完成定时。

之前,我以为定时器计时也是CPU来实现的,还在想,是不是通过并发来实现的,其实,并不是的,各外设在配置完成后都可以独立工作,并不需要CPU全程参与。所以不要弄错了。如果按照这种错误的思路,那么,延时就不可能会实现,因为定时和主循环和并发执行的,不可能会等待计时完成再执行后面的程序。

延时的思路

在学习51时,常使用for循环来实现延时。

延时的思路,其实就是让程序在一个地方空等一段时间,for循环就是在一个地方等待来实现延时,只是这种for循环的方式,难以准确估计等待的时间。

要想实现精准的延时,就需要用到定时器。

让定时器一直阻塞轮询,只有到达计时时间,才会结束轮询,继续执行后续的指令。

接下来,分别使用Systick和定时器来实现延时。

Systick实现延时

直接参考:

【STM32】Systick滴答定时器_一只大喵咪1201的博客-CSDN博客

Systick定时器,是一个简单的定时器,对于CM3、CM4内核芯片,都有Systick定时器。Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。
Systic定时器也叫做滴答定时器,是一个24 位的倒计数定时器,计到0时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。
如果想熟悉框图,可直接参考:

嵌入式学习笔记——SysTick(系统滴答)_systick寄存器_小向是个Der的博客-CSDN博客

SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15),被操作系统所调用(当上了操作系统时,其他应用程序则不能再使用该滴答时钟来延时)。

延时程序示例:

具体程序实现详见正点原子示例代码。

常规定时器实现延时

定时器实现的思路也比较简单,配置好定时器之后,在程序里打开定时器,然后循环判断计数值是否到0,或者判断状态标志位是否满足要求即可。

比如:

实现微秒级延时
void TIM3Init(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);       	//开启时钟

    TIM_TimeBaseInitStruct.TIM_Period = 0xffff;                	//装载计数值
    TIM_TimeBaseInitStruct.TIM_Prescaler = 42 - 1;              //装载预分频值,1us
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;    //预分频值为1
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数方式

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);            //进行定时器配置	

    TIM_Cmd(TIM3, ENABLE);	//使能TIMx外设
}

// 微秒延时
void delay_us(uint16_t us)
{
	u16 tp1;
	u16 tp2;
	u16 dif;
	
	tp1 = TIM3->CNT;
	while(1)
	{
		tp2 = TIM3->CNT;
		dif = tp2 - tp1;
		if(dif >= us)
			break;
	}
}

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32实现精确延时

发表评论