关于STM32的计数与延时

描述

Ⅰ关于STM32的计数和延时

在STM32中,具有计数(或计时)功能的模块基本都能实现延时功能。如:系统滴答SysTick、定时器TIM、实时时钟RTC、看门狗WDG。

精确延时一般使用定时器TIM即可实现。当然,是否精确,取决于你的主频(也就是晶振)是否准确,如果主频精确,那么实现的延时也一定精确。

一般来说,常温下实现us微秒级的延时,误差还是挺小的(应该说挺精确)。拿F407,主频168M来说,可以实现几十ns纳秒的延时,如果选用高精度的晶振,误差还是很小的。

总结:想要TIM定时器实现高精确的延时,就需要高精度的晶振。主频精确,那么延时就精确。

ⅡSTM32的TIM定时器

STM32的定时器有3类:

高级定时器Advanced control Timer

通用定时器General purpose Timer

基本定时器Basic Timer

STM32的这三种定时器都能实现最基本的定时计数功能。差异在于它们的功能多少不一样,从结构图一目了然,下面以STM32F4为例,给大家展示一下F4三类定时器的结构图:

高级定时器

计数

通用定时器

计数

基本定时器

计数

相信大家看了上面3种结构图,心里大概应该明白它们的差异存在哪些地方。 具体差异可以参看手册中的“主要特性”,里面详细讲述了其中的功能和特性。

重要提示:

1.定时器的位数有16位和32位之分,详见数据手册。

2.定时器有多少个,以及是TIM几,同样见数据手册。如下图STM32F411就只有8个定时器,没有基本定时器。

计数

ⅢSTM32定时器计数延时原理

上面3种定时器(高级、通用和基本)都能实现计数延时的功能,我们以最简单的基本定时器为例,还是参看着结构图来说明:

计数

1.来自RCC的时钟,参看RCC时钟树,一般是SystemCoreClock或者SystemCoreClock/2, 如STM32F429的就是(180M/2)。

2.分频CK_PSC之后就是计数器CK_CNT的计数频率。

如分频值位9,则计数频率为1M. (180M / 2 /9= 10M).

3.实现1us计数:

上面1秒计数10M个数,那么我计10个数,就是1us的时间。只需要在自动重载寄存器ARR中填充10 - 1即可。

代码分析:

红定义

//计数时钟(相当于1秒钟计数10M次个脉冲) #define TIM6_COUNTER_CLOCK        10000000 //预分频值 #define TIM6_PRESCALER_VALUE      (SystemCoreClock/2/TIM6_COUNTER_CLOCK - 1) //定时周期(计数满10个算一个周期,也就是1us) #define TIM6_PERIOD_TIMING        (10 - 1)

配置

void TIM6_Configuration(void){  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;  /* TIM6时基单元配置 */  TIM_TimeBaseStructure.TIM_Prescaler = TIM6_PRESCALER_VALUE;        //预分频值  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        //向上计数模式  TIM_TimeBaseStructure.TIM_Period = TIM6_PERIOD_TIMING;             //定时周期  TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;            //时钟分频因子  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);                         //使能"更新"中断 }

如果需要中断,则开启1us中断。

定时器阻塞延时

void TIM6_Nus(uint16_t Times){  TIM_Cmd(TIM6, ENABLE);                                             //启动定时器  while(Times--)  {    while(TIM_GetFlagStatus(TIM6, TIM_FLAG_Update) == RESET);        //等待计数完成    TIM_ClearFlag(TIM6, TIM_FLAG_Update);                            //清除标志  }  TIM_Cmd(TIM6, DISABLE);                                            //关闭定时器 }

以上代码,之前有分享过类似的,在下载区 STM32F417_第一阶段里面。

提示:

1.这类阻塞延时,仅供学习其原理使用,请结合实际项目修改代码。

2.可以通过定时中断 + 读取计数器的值来获取精确的时间。

比如:1ms中断一次,同时,计数累加。获取计数值 + 累计值也能得出精确延时。 (当然,中断不能太频繁), 此原理,适用于其他SysTick,RTC等具有计数功能的模块。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分