当前位置: 首页 > news >正文

STM32-定时器的基本定时/计数功能实现配置教程(寄存器版)

本章概述思维导图:

STM32-定时器

STM32定时器是一种功能强大的外设模块,通过时基单元(包含预分频器、计数器和自动重载寄存器)实现精准定时和计数功能,广泛应用于PWM控制、信号测量、定时任务调度等场景。

STM32F103系列提供8个定时器:

2个基本定时器:TIM6、TIM7;

4个通用定时器:TIM2、TIM3、TIM4、TIM5;

2个高级定时器:TIM1、TIM8;

STM32定时器工作原理:(1)时钟源、(2)时基单元、(3)计数模式;

(1)时钟源:

内部时钟(CK_INT):由APB总线时钟经倍频后得到,是定时器的主要时钟源。

外部时钟:通过外部输入脚(TIx)或外部触发输入(ETR)提供时钟信号。

内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器。

(2)时基单元:

计数器寄存器(TIMx_CNT):核心计数单元,存储当前的计数值。

预分频器(TIMx_PSC):对输入时钟进行分频,分频系数为1~65536。

自动重装载寄存器(TIMx_ARR):决定计数周期,当计数器达到该值时产生更新事件。

(3)计数模式:

向上计数模式:从0计数到ARR值,然后重新从0开始计数。

向下计数模式:从ARR值向下计数到0,然后重新从ARR开始计数。

中央对齐模式:先向上计数到ARR值,再向下计数到0,常用于PWM输出中实现更精确的脉冲宽度控制。

基本定时器介绍

基本定时器TIM6和TIM7个包含一个16位自动装载计数器,由各自的可编程预分频器驱动。

它们可以作为通用定时器提供时间基准,特别地可以为数模转换器(DAC)提供时钟。实际上它们在芯片内部直接连接到DAC并通过触发输出直接驱动DAC。

这两个定时器是相互独立得,不共享任何资源

TIM6和TIM7基本定时器的主要功能:

1. 16位自动重装载累加计数器

2. 16位可编程(可实时修改)预分频器,用于对输入的时钟系数为1~65536之间的任意数值分频

3. 触发DAC的同步电路

4. 在更新事件(计数器溢出)时产生中断/DMA请求

通用定时器介绍

TIM2、TIM3、TIM4、TIM5通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。

它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较PWM)。

使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒见调整。

每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。

TIM2、TIM3、TIM4、TIM5通用定时器的功能包括(拥有基本定时器所有功能):

1.16位向上、向下、向上/向下自动装载计数器。

2. 16位可编程(可实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值.

3. 4个独立通道:(1)输入捕获;(2)输出比较;(3)PWM生成;(4)单脉冲模式输出

4.多种时钟源。

5.支持针对定位的增量(正交)编码器和霍尔传感器电路。

高级定时器介绍

高级控制定时器(TIM1和TIM8)由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动。

它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。

使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。

高级控制定时器(TIM1和TIM8)和通用定时器(TIMX)是完全独立的,它们不共享任何资源。它们可以同步操作。

TIM1和TIM8高级定时器的功能包括(拥有通用定时器所有功能):

1.死区时间可编程的互补输出

2. 断路输入信号(刹车输入信号)

3.重复计数器

总结:

STM32的定时器分为基本定时器(TIM6和TIM7)、通用定时器(TIM2、TIM3、TIM4、TIM5)、高级定时器(TIM1和TIM8),功能逐级递增;

基本定时器:仅提供基础定时中断功能,适用于简单的定时任务。

通用定时器:支持输入捕获、输出比较及编码器接口,适用于测量输入信号的脉冲长度或产生输出波形。

高级定时器:支持PWM生成、死区控制、刹车保护等复杂功能,适用于电机控制等场景。

实现定时器计数功能配置

配置计数器功能要用到的相关寄存器

计数器:TIM_CNT

分频器:TIM_PSC(要查看时钟树,知道默认时钟工作频率是多少。查看当前配置定时器需要多少时钟工作频率进行设置)

重装载值寄存器:TIM_ARR

控制寄存器:TIM_CR1 ;TIM_CR2;

状态寄存器:TIM_SR

中断寄存器:TIM_DIER

配置定时器2实现计数功能配置步骤:

1.开时钟

2.开启复位时钟然后关闭

3.配置计数器寄存器清0操作

4.配置预分频寄存器->计数器的时钟频率CK_CNT等于fck_psc/(PSC[ 1 5 : 0 ] +1 );最大填写不能超过65535;内部减一(psc-1)可以填写65536

5.配置自动重装载寄存器

6.配置CR1控制寄存器ARPE:自动重装载预装载允许位

7.配置CR1控制寄存器CEN:使能计数器

8.配置中断使能寄存器(TIMx_DIER)UIE:允许更新中断

9.调用中断优先级函数

代码示例:

#include "TIM.h"
#include "SYS.h"
/*配置通用定时器2实现计数功能形参:PSC->预分频系数arr->重装载值(计数周期)
*/
void TIM2_Init(u16 psc,u16 arr)
{
//	1.开时钟RCC->APB1ENR|=1<<0;//开启TIM2时钟
//	2.开启复位时钟然后关闭RCC->APB1RSTR|=1<<0;//开启TIM2复位RCC->APB1RSTR&=~(1<<0);//关闭复位
//	3.配置计数器寄存器清0操作TIM2->CNT=0;
//	4.配置预分频寄存器->计数器的时钟频率CK_CNT等于fck_psc/(PSC[ 1 5 : 0 ] +1 );最大填写不能超过65535;内部减一(psc-1)可以填写65536TIM2->PSC=(psc-1);
//	5.配置自动重装载寄存器TIM2->ARR=arr;
//	6.配置CR1控制寄存器ARPE:自动重装载预装载允许位TIM2->CR1|=1<<7;
//	7.配置CR1控制寄存器CEN:使能计数器TIM2->CR1|=1<<0;
//	8.配置中断使能寄存器(TIMx_DIER)UIE:允许更新中断TIM2->DIER|=1<<0;
//	9.调用中断优先级函数STM32_SetNVICPriority(TIM2_IRQn,1,1);
}

形参写入讲解:

例如:TIM2_Init( 72, 1000);

此时定时器的工作频率为72MHZ;

72MHZ/72=1MHZ,芯片TIMXCLK时钟/分频系数PSC=1MHZ;

转换时间为:1/1MHZ=1us;1us*周期时间=1us*1000=1ms;

算出定时时间为1ms;


例如:TIM2_Init( 65536, 65536);定时器最长定时时间

此时定时器2的工作频率为72MHZ;

72MHZ/65536=72000KHZ/65536=1.0987328125KHZ;

芯片TIMXCLK时钟/分频系数PSC=1.0987328125KHZ;

转换时间为:1/1.0987328125KHZ=0.9102222222222ms;

0.9102222222222ms*周期时间=0.9102222222222ms*65536=59.652325555m;
算出定时最长时间为:59.652325555m;

判断定时器定时时间操作

判断定时器状态寄存器中UIF位更新中断标记(当产生更新事件时该位由硬件置’1’。它由软件清’0’。):注意这是在主函数中判断,要注释实现定时器计数功能配置里步骤8和步骤9。

代码示例:

#include "LED.h"
#include "USART1.h"
#include "stdio.h"
#include "TIM.h"
int main()
{LED_Init();//LED灯初始化函数USART1_Init(115200);//USART1串口1初始化函数TIM2_Init(7200,50000);//定时器2设置定时时间为5000毫秒=5秒u8 flag=0;while(1){if(TIM2->SR&1<<0){printf("定时器2计数时间到,循环定时时间为5秒\n");LED1(!flag);TIM2->SR&=~(1<<0);}}
}

代码运行结果:


配置定时器2中断服务函数

配置步骤:

1.在stm32f10x_md.s文件夹中找定时器2中断服务函数

2.在中断服务函数中判断定时器状态寄存器中UIF位更新中断标记

代码示例:

/*定时器2中断服务函数
*/
void  TIM2_IRQHandler(void)
{if(TIM2->SR&1<<0){printf("定时器2计数时间到,循环定时时间为5秒\n");TIM2->SR&=~(1<<0);}
}

主函数代码示例:

#include "LED.h"
#include "USART1.h"
#include "stdio.h"
#include "TIM.h"
int main()
{LED_Init();//LED灯初始化函数USART1_Init(115200);//USART1串口1初始化函数TIM2_Init(7200,50000);//定时器2设置定时时间为5000毫秒=5秒while(1){}
}

代码运行结果:


制作不易!喜欢的小伙伴给个小赞赞!喜欢我的小伙伴点个关注!有不懂的地方和需要的资源随时问我哟!   
http://www.lryc.cn/news/600609.html

相关文章:

  • 手动开发一个串口调试工具(二):Qt 串口类基本认识与使用
  • ClickHouse高性能实时分析数据库-消费实时数据流(消费kafka)
  • 【Linux系统】理解硬件 | 引入文件系统
  • Kotlin线程同步
  • 高并发微服务限流算法方案对比与实践指南
  • 告别Vite脚手架局限!MixOne Beta测试招募:你的需求,我们来实现
  • 基于 ThinkPHP 开发的垂直化网址导航
  • 深入解析Hadoop如何实现数据可靠性:三副本策略、校验和验证与Pipeline复制
  • 使用Spring Boot创建Web项目
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频语义理解与智能检索进阶(365)
  • 【工程化】浅谈前端构建工具
  • nginx一个域名下部署多套前端项目
  • 机器学习特征工程详解:特征选择与降维(PCA)
  • NLua和C#交互
  • Flask input 和datalist结合
  • VTK交互——ImageClip
  • xLua和C#交互
  • 高性能网络DPDK、RDMA、XDP初探
  • 电子电气架构 --- 高阶智能驾驶对E/E架构的新要求
  • 工具 | 解决 VSCode 中的 Delete CR 问题
  • uniapp+vue3——通知栏标题纵向滚动切换
  • 全球化2.0 | 云轴科技ZStack亮相阿里云印尼国有企业CXO专家活动
  • 以太坊下一阶段的关键——隐私
  • DSP在CCS中实现双核在线仿真调试及下载的方法(以TMS320F28x为例)
  • 生产环境使用云服务器(centOS)部署和使用MongoDB
  • (React入门上手——指北指南学习(第一节)
  • docker 从主机复制文件到容器外进行编辑
  • MongoDB数据模型
  • vulhub Web Machine(N7)靶场攻略
  • AutoDL 数据盘清理指南:彻底删除 .Trash-0 内文件释放空间