关于STM32的计数与延时

发布者:SereneJourney最新更新时间:2023-05-10 来源: elecfans关键字:STM32  计数  延时 手机看文章 扫描二维码
随时随地手机看文章

Ⅰ关于STM32的计数和延时

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


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


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


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


ⅡSTM32的TIM定时器

STM32的定时器有3类:

高级定时器Advanced control Timer

通用定时器General purpose Timer

基本定时器BasicTimer

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等具有计数功能的模块。


关键字:STM32  计数  延时 引用地址:关于STM32的计数与延时

上一篇:基于stm32的keil开发环境搭建
下一篇:单片机STM32时钟设计分析

推荐阅读最新更新时间:2024-11-10 21:09

stm32-串口接受不定长数据方法(3种)
方法1:串口接受数据,定时器来判断超时是否接受数据完成。 方法2:DMA接受+IDLE中断 实现思路:采用STM32F103的串口1,并配置成空闲中断IDLE模式且使能DMA接收,并同时设置接收缓冲区和初始化DMA。那么初始化完成之后,当外部给单片机发送数据的时候,假设这帧数据长度是200个字节,那么在单片机接收到一个字节的时候并不会产生串口中断,而是DMA在后台把数据默默地搬运到你指定的缓冲区里面。当整帧数据发送完毕之后串口才会产生一次中断,此时可以利用DMA_GetCurrDataCounter();函数计算出本次的数据接受长度,从而进行数据处理。 应用对象:适用于各种串口相关的通信协议,如:MODBUS,PPI ;还有类
[单片机]
stm32学习笔记---计数器定时中断(1s)
#include tim_driver.h //tim2³õʼ»¯:1ÃëÖÓ¸üÐÂÊý¾Ý void tim2_init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //ʹÄÜʱÖÓ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
[单片机]
<font color='red'>stm32</font>学习笔记---<font color='red'>计数</font>器定时中断(1s)
STM32定时器产生不同频率的PWM
STM32产生PWM是非常的方便的,要需要简单的设置定时器,即刻产生! (1)使能定时器时钟:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); (2)定义相应的GPIO: /* PA2,3,4,5,6输出- Key_Up,Key_Down,Key_Left,Key_Right,Key_Ctrl */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU
[单片机]
stm32 --- 灵活的静态存储器控制器FSMC
所有的外部存储器共享控制器输出的地址、数据和控制信号,每个外部设备可以通过一个唯一的片选信号加以区分。FSMC在任一时刻只访问一个外部设备。 具有静态存储器接口的器件包括: 1. 静态随机存储器(SRAM) 2. 只读存储器(ROM) 3. NOR闪存 4. PSRAM(4个存储器块)。可以外部扩展存储器。 FSMC模块挂载在AHB总线上。至于RD,WE,RS,CS信号都已经是FSMC控制器自动产生的,在操作中不用管这些信号的变化。 从FSMC的角度看,可以把外部存储器划分为固定大小为256M字节的四个存储块,见下图。 ● 存储块1用于访问最多4个NOR闪存或PSRAM存储设备。这个存储区被划分为4个NOR
[单片机]
51单片机IO口模拟串口通讯1-延时
最近因工作需要,研究了一下单片机IO口模拟串口通讯的相关知识。相关内容主要参考了网上《51单片机模拟串口的三种方法》和《单片机IO口模拟串口程序(发送+接收)》两篇文档,并动手做了一下实验。感受颇多。 硬件环境:STC89C52 软件环境:IDE Keil uVision V4.10 编译器 C51 V9.0 代码如下: /********************************************** 方法1:延时法 硬件:11.0592MHz晶振,STC89C52,RXD P1.0 TXD P1.1 波特率:9600 描述:所谓延时法是指根据模拟出的波特率,每1位持续的时间的长短是通过循环空指令来延
[单片机]
100进制计数
100进制计数器 异步级联法组成的100进制计数器 定义集成计数器的高低位,1#芯片为低位(相当于个位);2#芯片为高位,(相当于十位),从低位开始计数,把计数脉冲CP送入1#(低位)集成计数器的CP端。B.寻找进位信号,进位端C发出的就是进位信号,这是从0~9的计数过程中,计数到Q3Q2Q1Q0=1001(9)时,发出的高电平信号。C.74LS160是CP上升沿有效的集成计数器,高位芯片需要一个脉冲上升沿进行触发计数,并且,就进位的时机而言,应该在低位芯片的状态是9à0(Q3Q2Q1Q0=1001à0000)时刻,此时,进位输出端C:从1à0,这是一个下降沿,这也是我们需要的进位信号,只是信号边沿不对。可以用一个非门进行
[模拟电子]
100进制<font color='red'>计数</font>器
修改STM32库函数中的晶振值
STM32F407的库文件中默认晶振值为25MHz,若外接晶振8MHz,则需修改以下几个地方: 1)修改HSE_VALUE的值 将#define HSE_VALUE ((uint32_t)25) /*! Value of the External oscillator in Hz */ 修改为 #define HSE_VALUE ((uint32_t)8) /*! Value of the External oscillator in Hz */ 2)修改PLL_M的值 将#define PLL_M 25修改为 #define PLL_M 8 3)修改STM32F407工程的Options设置 在Option for t
[单片机]
STM32之DAC固定电压输出配置
STM32F103VCT6自带两个12位DAC,DAC的转换速度一直没有查到,网上有人说是1MHZ的频率,那就是1us了。ADC的转换时间在56MHZ工作频率下为1us,在72MHZ工作频率下为1.17us。如果AD和DA有对称关系的话,那么很可能跟ADC的时间相同,刚入手分析的,不见得正确! 由于我此次使用是DA输出电压。STM32的DAC固定电压配置和波形输出配置相似,不同的地方在于它要多调用一个函数:DAC_SoftwareTriggerCmd(DAC_Channel_1,ENABLE);这样才会输出固定的电平。 具体配置如下: void DAC_VOLTAGE_Configuration(void) { D
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved