单片机04__基本定时器__毫秒微秒延时

2024-02-23 10:36

本文主要是介绍单片机04__基本定时器__毫秒微秒延时,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基本定时器__毫秒微秒延时

基本定时器介绍(STM32F40x)

        STM32F40X芯片一共包含14个定时器,这14个定时器分为3大类:

通用定时器

10个

TIM9-TIM1和TIM2-TIM5

具有基本定时器功能,

还具有输入捕获,输出比较功能

高级定时器

2个

TIM1和TIM8  

具有通用定时器和基本定时器功能,

还具有死区刹车功能。

基本定时器

2个

TIM6和TIM7 

能实现基本定时功能和DAC模块触发功能

注:若只存在6个定时器。TIM1一定为高级定时器,TIM6一定为基本定时器。其余为通用。

若存在10个定时器。TIM1&&TIM8为高级定时器,TIM6&&TIM7为基本定时器。其余为通用。

基本定时器概述STM32F40x

        基本定时器TIM6和TIM7各包含一个16位的自动重载计数器(最大计数值是0~ 2^16-1),该计数器由可编程预分频器驱动(降低计数频率,达到更长的计时要求)。

        可编程预分频器(降低计数频率): 一个脉冲计一次数;更长计时:十个脉冲计一次数。

        基本定时器不仅能用来作为简单的计数功能,还可以用来作为通用定时器的时基单元,还可以用作驱动DAC模块。

基本定时器特征STM32F40x

        ①基本定时器的计数范围是:0-65535,计数方式为递增计数。

        ②可以对基本定时器的时钟源进行分频:分频系数介于1-65536之间,分频的目的是为了满足更长的计时时间要求。

        ③可以作为DAC模块的驱动时钟

       ④在基本定时器的计数器溢出的时候,可以产生一个更新事件,并同时可以产生一个中断/DMA请求。

定时器的时钟源

如下图,如果芯片的工作频率到此时钟总线的频率的分频系数为1,则频率不变。否则X2。

如果若使用的定时器的是时钟频率不是总频就要考虑是否要X2的问题,而且X2之后的频率绝对不会超过总频。

基本定时器内部框图STM32F40x

①CK_PSC为主频,通过“预分频器”得到定时器时钟(CK_CNT)。

        预分频器:设置分频值,降低计数频率,增长计数时间。(一个脉冲计数一次,分频后:多个脉冲计数一次,时间增长)

        预分频器有影子寄存器,且影子寄存器不可设置,长期自动开启。

        内核只会读取影子寄存器的分频值。当更新事件UEV后,上层新的预分频值才会替换掉影子寄存器内的旧分频值。

②CNT COUNTER:计数器当前计数的值。计数器上溢。

        事件更新UEV:当前计数的值到达计数周期。

③自动重载寄存器:设置计数周期(计数的最大值)。

        新的自动重载寄存器的值,只能在事件更新UEV后,才会替换掉重载影子寄存器的值。

        第一次开启计数器时,有UG位手动更新重载影子寄存器的值。

        状态寄存器:产生事件更新UEV时,状态寄存器标志位变为1,只有重新清0,才可再次计数。手动设置UG位,引起UEV,也需要状态寄存器状态位清0。

定时器时基单元  (TIM6/TIM7)  

        可编程定时器的主要模块由一个 16 递增计数器及其相关的自动重载寄存器组成。计数器的时钟可通过预分频器进行分频。

        计数器、自动重载寄存器预分频器寄存器可通过软件进行读写。即使在计数器运行时也可执 行读写操作。

定时器的时基单元是定时器最基本的寄存器

        ①计数器寄存器:定时器计数工作寄存器,从0开始(不一定是0,想从多少开始则将数值直接写给计数器寄存器即可)累积计数到自动重装载数值,从而产生溢出,重新开始从初始值计数。

        ②预分频寄存器:对输入的时钟源进行分频,降低计数频率,达到更长的计时要求。

        ③自动重装载寄存器:定时器的工作周期(决定了计数器一周期内计数的次数/最大范围)。

分频器分频1->2

计数器时序图

自动重载寄存器(ARR预装载)

基本定时器相关寄存器STM32F40x

总述:

        自动重载寄存器是预装载的。每次尝试对自动重载寄存器执行读写操作时,都会访问预装载寄存器。预装载寄存器的内容既可以直接传送到影子寄存器,也可以在每次发生更新事件 UEV 时传送到影子寄存器,这取决于 TIMx_CR1 寄存器中的自动重载预装载使能位 (ARPE)。当计数器达到上溢值并且 TIMx_CR1 寄存器中的 UDIS 位为 0 时,将发送更新事件。该更新事件也可由软件产生。     

        计数器由预分频器输出 CK_CNT 提供时钟,仅当 TIMx_CR1 寄存器中的计数器启动位 (CEN)  1 时,才会启动计数器。

TIM6初始化

        开启时钟。

控制寄存器TIMx_CR1(TIM6和TIM7)

计数器 TIMx_CNT (TIM6和TIM7)

预分频器 TIMx_PSC (TIM6和TIM7)

自动重载寄存器 TIMx_ARR (TIM6和TIM7)

状态寄存器 TIMx_SR (TIM6和TIM7)

事件生成寄存器 TIMx_EGR (TIM6和TIM7)

基本定时器编程思路STM32F40x

/************************************************
函数功能:定时器TIM6初始化
函数参数:
psc:分频值
arr:自动重载值时间(s) = 计数周期(arr) / 计数频率
计数频率 = 定时器工作频率(hz 已知)/分频系数(psc)定时器工作频率:42*2MHZ == 84000000HZ
设:psc == 8400  ----->   计数频率 == 10000
设:arr == 10000   ---->   时间 == 1s
************************************************/
void TIM6_Init(uint16_t psc,uint16_t arr)
{RCC->APB1ENR |= 1<<4;	//开启时钟TIM6->CR1 |= 1<<7;	//自动重载预装载使能TIM6->CR1 &= ~(1<<3);	//循环计数TIM6->CR1 &= ~(1<<2);	//选择事件更新源TIM6->CR1 &= ~(1<<1);	//事件发生后更新影子寄存器的值//设置时基单元TIM6->CNT = 0;	//设置计数初始值TIM6->PSC = psc -1;	//设置分频值TIM6->ARR = arr;	//设置自动重载值TIM6->EGR |= 1<<0;	//手动更新UG位TIM6->SR &= ~(1<<0);	//状态寄存器,清除标志位TIM6->CR1 |= 1<<0;	//使能计数器
}

使能基本定时器时钟     

  1. 配置基本定时器的功能模式:是否开启影子寄存器、计数模式。。。。。
  2. 写计数器初始值,预分频值、自动重装载值。
  3. 如果使用中断,则开启中断   
  4. 手动产生更新事件(UG位)
  5. 清标志位
  6. 启动计数器

基本定时器实现毫秒微秒延时

公式:

时间(s) = 计数周期(arr) / 计数频率

计数频率 = 定时器工作频率(hz 已知)/分频系数(psc)

TIM7挂载在APB1(42MHZ)线上,不为时钟总频,所以定时器工作频率:42*2*1000000HZ

定时器工作频率:42*2MHZ == 84000000HZ

设:psc == 8400  ----->   计数频率 == 10000

设:arr == 10000   ---->   时间 == 1s

毫秒:

设:arr== 10   ------>   时间 == 1s/1000 == 1ms

微秒:

设:psc==84;arr==1   ------>   时间== 1ms/1000  == 1us

举例:

//毫米延时
void delay_ms(uint16_t num)
{uint16_t i = 1;//10000 -> 1s   10 -> 1msTIM7_Init(8400,10);while(1){if(TIM7->SR & 1<<0){TIM7->SR &= ~(1<<0);i++;}if(i == num)break;}
}
//微秒延时
void delay_us(uint16_t num)
{uint16_t i = 1;//10000 -> 1s   10 -> 1ms   TIM7_Init(84,1);while(1){if(TIM7->SR & 1<<0){TIM7->SR &= ~(1<<0);i++;}if(i == num)break;}
}

这篇关于单片机04__基本定时器__毫秒微秒延时的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/738333

相关文章

SQL BETWEEN 语句的基本用法详解

《SQLBETWEEN语句的基本用法详解》SQLBETWEEN语句是一个用于在SQL查询中指定查询条件的重要工具,它允许用户指定一个范围,用于筛选符合特定条件的记录,本文将详细介绍BETWEEN语... 目录概述BETWEEN 语句的基本用法BETWEEN 语句的示例示例 1:查询年龄在 20 到 30 岁

mysql中insert into的基本用法和一些示例

《mysql中insertinto的基本用法和一些示例》INSERTINTO用于向MySQL表插入新行,支持单行/多行及部分列插入,下面给大家介绍mysql中insertinto的基本用法和一些示例... 目录基本语法插入单行数据插入多行数据插入部分列的数据插入默认值注意事项在mysql中,INSERT I

mapstruct中的@Mapper注解的基本用法

《mapstruct中的@Mapper注解的基本用法》在MapStruct中,@Mapper注解是核心注解之一,用于标记一个接口或抽象类为MapStruct的映射器(Mapper),本文给大家介绍ma... 目录1. 基本用法2. 常用属性3. 高级用法4. 注意事项5. 总结6. 编译异常处理在MapSt

MyBatis ResultMap 的基本用法示例详解

《MyBatisResultMap的基本用法示例详解》在MyBatis中,resultMap用于定义数据库查询结果到Java对象属性的映射关系,本文给大家介绍MyBatisResultMap的基本... 目录MyBATis 中的 resultMap1. resultMap 的基本语法2. 简单的 resul

Java 枚举的基本使用方法及实际使用场景

《Java枚举的基本使用方法及实际使用场景》枚举是Java中一种特殊的类,用于定义一组固定的常量,枚举类型提供了更好的类型安全性和可读性,适用于需要定义一组有限且固定的值的场景,本文给大家介绍Jav... 目录一、什么是枚举?二、枚举的基本使用方法定义枚举三、实际使用场景代替常量状态机四、更多用法1.实现接

git stash命令基本用法详解

《gitstash命令基本用法详解》gitstash是Git中一个非常有用的命令,它可以临时保存当前工作区的修改,让你可以切换到其他分支或者处理其他任务,而不需要提交这些还未完成的修改,这篇文章主要... 目录一、基本用法1. 保存当前修改(包括暂存区和工作区的内容)2. 查看保存了哪些 stash3. 恢

MySQL基本查询示例总结

《MySQL基本查询示例总结》:本文主要介绍MySQL基本查询示例总结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Create插入替换Retrieve(读取)select(确定列)where条件(确定行)null查询order by语句li

Python 异步编程 asyncio简介及基本用法

《Python异步编程asyncio简介及基本用法》asyncio是Python的一个库,用于编写并发代码,使用协程、任务和Futures来处理I/O密集型和高延迟操作,本文给大家介绍Python... 目录1、asyncio是什么IO密集型任务特征2、怎么用1、基本用法2、关键字 async1、async

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

使用Python实现一个优雅的异步定时器

《使用Python实现一个优雅的异步定时器》在Python中实现定时器功能是一个常见需求,尤其是在需要周期性执行任务的场景下,本文给大家介绍了基于asyncio和threading模块,可扩展的异步定... 目录需求背景代码1. 单例事件循环的实现2. 事件循环的运行与关闭3. 定时器核心逻辑4. 启动与停