延时,就是停在那,啥都不干,发呆。精准延时,就是发呆多长时间,是精确的。
比如,要求某个IO口维持低电平1毫秒后,再维持高电平3毫秒,就需要把IO口拉高,然后延时1毫秒,再拉低,再维持3毫秒。
类似这种情况在硬件接口时序里经常遇到,比如,用IO口模拟SPI协议,用IO口模拟I2C协议等等。
既然延时就是发呆,那我们让系统发发呆就得了呗,让它执行空代码,执行很多很多很多,就能达到预期的效果。
for(i=0; i<20000; i++)
{
for(j=0; j<20000; j++)
{
;;;;;;;;;;;;;;;;;;;;;;;;;
}
}
但这种方法很难测量它发呆的时间,在51单片机中,我们可以通过大概计算代码周期来确定必须运行多少个循环能达到指它的时间。
STM32是三级流水线作业,指令周期不好算,用这种方式延时,精准度有限。
既然定时器能够计时,那就用它来延时吧。
我们就来讲一讲使用定时器来做微秒级(us)的和毫秒级(ms)的精准延时吧。
上一篇《STM32 基本定时器》我们讲过定时器,设置定时器并启动后,定时器会不断数数,可以正着数也可以倒着数,还可以先正着数后倒着数。
既然这样,我们要做一个确定时间的延时,我们就可以启动一个的定时器,让它数数,在它数数这时间内,我们让程序发呆 while(1){},直到数数完成后,再清醒过来 break;
那么,我们就可以这样写程序:
喂,我要定时器数数 xx 微秒。
while(1)
{
if(定时器数完了)
break;
}
依葫芦画瓢,我们照着上节课的TIM1,配置一个TIM2,作为精准延时用的定时器。
这个就不需要中断咯,因为我们让程序发呆,让它边发呆边判断定时器到时间了没,不需要中断。
PS:当然,你也可以用中断做,让它一直发呆,边发呆边判断标志位,定时器到时间了,设置标志位,发呆程序退出,不过,何必呢?
怎么判断定时器到时间了没呢?
可以设置向下计数,那计数寄存器就会从xxxxx开始数数,一直到0,0了,就是到时间了,所以,只需要不断地读这个计数寄存器就行了。
画瓢,初始化:
设置为向下计数,到时判断计数是否为0,若为0,说明计时完成,发呆可以结束。
不需要中断,也暂时不开启,要延时的时候才开启;
/* TIM2init function */
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim2.Instance = TIM2;
htim2.Init.Prescaler = 1; // 这个随便设置,后面计时前再设置
htim2.Init.CounterMode = TIM_COUNTERMODE_DOWN;
htim2.Init.Period = 1; // 这个随便设置,后面计时前再设置
htim2.


6998

被折叠的 条评论
为什么被折叠?



