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

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.xdnf.cn/news/16343.html

相关文章:

  • 【工具】好用的浏览器AI助手
  • 用unity开发教学辅助软件---幼儿绘本英语拼读
  • 【深度学习新浪潮】什么是GUI Agent?
  • java面试复习(spring相关系列)
  • 【机器学习-2】 | 决策树算法基础/信息熵
  • 【RocketMQ】一分钟了解RocketMQ
  • Earth靶机攻略
  • linux线程概念和控制
  • 字符串缓冲区和正则表达式
  • Mingw 与MSYS2 与Cygwin区别
  • Linux如何执行系统调用及高效执行系统调用:深入浅出的解析
  • 基于深度学习的胸部 X 光图像肺炎分类系统(七)
  • 凝思系统6.0.80安装chorme,亲测可用
  • 如何创建或查看具有 repo 权限的 GitHub 个人访问令牌(PAT)
  • mount: /mnt/sd: wrong fs type, bad option, bad superblock on /dev/mmcblk1
  • FitCoach AI:基于React+CloudBase的智能健身教练应用开发全解析
  • 缓存一致性:从单核到异构多核的演进之路
  • Android Jetpack 组件库 ->WorkManager
  • Linux系统架构核心全景详解
  • Unity 实现帧率(FPS)显示功能
  • 11Linux文件压缩与链接实战技巧
  • 深入解析YARN中的FairScheduler与CapacityScheduler:资源分配策略的核心区别
  • Python 数据分析(二):Matplotlib 绘图
  • 小白成长之路-部署Zabbix7(二)
  • 【GoLang#3】:数据结构(切片 | map 映射)
  • Linux726 raid0,raid1,raid5;raid 创建、保存、停止、删除
  • KubeKey安装KubeSphere、部署应用实践问题总结
  • 零基础学习性能测试第四章:从0到1学会编写性能测试报告
  • 【Spring AI】SiliconFlow-硅基流动
  • C# 位运算及应用