STM32F4X定时器之通用定时器

news2024/12/25 12:52:00

一、STM32通用定时器概述

通用定时器包括一个16位或32位自动重载计数器,可通过可编程预分频器进行驱动。定时器可以实现多种功能,包括测量输入信号的脉冲宽度和生成输出波形,通过使用定时器预分频器和RCC时钟控制器预分频器,可以将脉冲宽度和波形周期从几微秒调制到几毫秒。此外,通用定时器之间是完全独立的,不会共享任何资源。定时器可应用于许多不同的领域,例如自动控制等。

通用 TIMx 定时器具有以下特性:
● 16 位 (TIM3 和 TIM4) 32 (TIM2 和 TIM5) 递增、递减和递增 / 递减自动重载计
数器。
● 16 位可编程预分频器,用于对计数器时钟频率进行分频 (即运行时修改),分频系数介
1 65536 之间。
● 多达 4 个独立通道,可用于:
— 输入捕获
— 输出比较
— PWM 生成(边沿和中心对齐模式)
— 单脉冲模式输出
● 使用外部信号控制定时器且可实现多个定时器互连的同步电路。
● 发生如下事件时生成中断/DMA 请求:
— 更新:计数器上溢/ 下溢、计数器初始化(通过软件或内部 / 外部触发)
— 触发事件(计数器启动、停止、初始化或通过内部/ 外部触发计数)
— 输入捕获(红外捕获)
— 输出比较(PWM波)
● 支持定位用增量(正交)编码器和霍尔传感器电路
● 外部时钟触发输入或逐周期电流管理

 通用定时器一共有10个如下表

所有的计数器都可以由16位可编程预分频器(1到65536分频)驱动。从而实现将脉冲宽度和波形周期从几微秒调制到几毫秒。

所有的通用定时器都彼此完全独立不共享任何资源。
所有的通用定时器的功能包括基本的定时功能之外,还可以测量输入信号的脉冲宽度(输入捕获),或者生成输出波形〈输出比较、PwM)。
补充:PWM(脉冲宽度调制)波特点:波形的周期/频率不会变化,占空比可以变化。

占空比:波形的高电平时间占整个周期的比例。

注意:(方波:波形的周期/频率和占空比都可以变化)

二、通用定时器框架

(1) TIMx..chx,总共有4个,但是左右两边是同一个通道,即是4个GPIO口,为了说明内部功能将其一分为二。
多达4个独立通道,可用于:
一输入捕获
一输出比较

---PWM生成一单脉冲模式输出
发生如下事件时生成中断/DMA请求:
一更新:计数器上溢/下溢、计数器初始化(通过软件或内部/外部触发)

一触发事件(计数器启动、停止、初始化或通过内部/外部触发计数)

一输入捕获
一输出比较

二、STM32通用定时器捕获输入

1、STM32的捕获输入原理

输入捕获:利用定时器的捕获通道捕获一个输入的信号。

输入捕获原理:通过检测TIMx_CHx通道上的边沿信号,在边沿信号发生跳变(比如上升沿/下降沿)的时候,会产生一个icXps信号(捕捉事件),当产生捕捉事件时会将当前定时器的值(TIMx_CNT)存放到对应的捕获影子寄存器里面(结果),完成一次捕获。

输入捕获的应用:捕获输入信号的脉冲宽度或者周期/频率。

2、STM32的捕获输入框架

总结:捕获的信号周期(频率)计算:

(1)从捕获寄存器中读出捕获的计数器的值(发生更新事件时)。

(2)计数周期(算出计数一个数的时间)。

(3)周期 = 计数 * 计数周期。

3、STM32的捕获输入相关寄存器

STM32的捕获输入

(1)设计:利用定时器的输入捕获功能检测按键按下的时长(脉冲宽度)

原理分析:

硬件分析

PA0配置为复用功能,复用为定时器5的CH1

******************************
@brief :定时器5输入捕获配置
@param : none
@return : none
@note TIM5->CH1 ===PA0 捕获按键按下的时长
*************************************/
void Time5_Init(void)
{
    /*1IO配置*/
    RCC->AHB1ENR |= 1 << 0;
    GPIOA->MODER &= ~(0X3 << 0);
    GPIOA->MODER |= (0X2 << 0);//复用功能
    GPIOA->AFR[0] &= ~(0XF<< 0);//
    GPIOA->AFR[0] |= 2 << 0;//PC6复用为定时器3的ch1
    /*2定时器配置*/
    RCC->APB1ENR |= 1<<1;//打开TIM3的时钟
    //时基单元配置
    //配置时基单元(预分频器,自动:重载寄存器,计数值)
    TIN5->ARR = 0xFFFF - 1;//10000
    TIM5->PSC = 8400 - 1;//10Khz 100us
    TIM5->CNT = 0;
    TIM5->CR1 = 0;
    TIM5->CR1 |= 1 << 7;//使用缓冲区
    TIM5->CR1 |= 1 << 2;
    //计数器递增计数
    //连续模式
    //UG位的使用手动产生更新事件,
    //目的:首次配置将缓冲区的值加载到时基寄存器中
    TIM5->EGR=1<<0;
    //清除更新一次标志位
    TIM5->SR &= ~(1 << 0);
    //配置输入捕获
    TIM5->CCMR1 |= 0XF << 4;//最大采样频率
    TIM5->CCER &= ~(1 << 3);
    TIM5->CCER &= ~(1 << 1);//通道1第一次上升沿触发
    TIM5->CCMR1 |= 1 << 0;//CC1通道配置为输入,IC1映射到TI1上
    TIM5->CCMR1 &= ~(3 << 2);//00:无预分频器,捕获输入上每检测到一个边沿便执行捕获
    TIM5->CCER |= (1 << 0);//使能捕获
    
    TIM5->DIER |= 1 << 1;//打开通道1的捕获中断
    //配置捕获中断在NVIC中的中断信息
    NVIC_SetPriority(TIM5_IRQn, NVIC_EncodePriority(5,2,1));//为定时器5设置中断信息
    NVIC_EnableIRQ(TIM5_IRQn);
    TIM5->DIER |= 1 << 0;
    //使能计数器
    TIM5->CR1 |= 1 << 0;
}
u16 update_num;//完整的周期个数
u32 count;
u32 updatflag;
void TIM5_IRQHandler(void)
{
    //判断是否是更新中断
    if(TIM5->SR &(1 << 0))
    {
        TIM5->SR &= ~(1 << 0);
        if(updateflag == 1)
        {
            update_num++;
        }
        printf("update_num = %d\r\n",update_num);
    }
    //判断是否是捕获中断
    if(TIM5->SR &(1 << 1))
    {
        if(KEY1)//按键按下
        {
            updateflag = 1;
            TIM5->DIER |= 1 << 0;
            TIM5->CNT = 0;
            TIM5->CCER &= ~(1 << 3);
            TIM5->CCER |= (1 << 1);
        }
        else//按键松开
        {
            TIM5->DIER &= ~(1 << 0);
            count = update_num * 0XFFFF + TIM5->CCR1;
            printf("count = %d\r\n",count);
            printf("count = %.2f\r\n",count*0.1);
            TIM5->CCER &= ~(1 << 3);
            TIM5->CCER &= ~(1 << 1);
            update_num = 0;
            count = 0;
            updateflag = 0;
        }
    }

}    

4、时钟源框架分析

由上图可知计数器时钟可由下列时钟源提供:

内部时钟(CK_INT)
外部时钟模式1:外部输入引脚(TIx)
外部时钟模式2:外部触发输入(ETR),仅适用于 TIM2、TIM3和TIM4。

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

注意:在四个时钟输入源中,除了特殊模式外正常情况下选择内部时钟源作为预分频器的时钟输入。

内部时钟源:

如果禁止从模式控制器(TIMx_SMCR [SMS]=000),则CEN位、DIR位(TIMx_CR1寄存器中)和UG位(TIMx_EGR寄存器中)为实际控制位,并且只能通过软件进行更改(UG除外,仍自动清零)。当对CEN位写入1时,预分频器的时钟就由内部时钟CK_INT提供。
如何选择内部时钟源??
TIMx_SMCR[SMS] = 000
TIMx_CR[CEN] = 1时
既可选择为内部时钟源。
外部时钟源模式2

如何选择外部时钟源模式2??
通过在TIMx_SMCR寄存器ECE位中写入=1可选择此模式即TIMx_SMCR[ECE]=1
既可选择为外部时钟源模式2
计数器可在外部触发输入 ETR 出现上升沿或下降沿时计数。

外部时钟源模式1

如何选择外部时钟源模式1??
TIMx_SMCR[SMS]=111

TIMx_SMCR[CEC]=0//关闭模式2。

既可选择为外部时钟源模式1

5、STM32的通用定时器比较输出

输出比较:通用定时器通过定时器通道向外部输出相应的波形(其中最重要的是 PWM 波)

输出 PWM 的应用:控制电机的转速,在充电器充电过程,生活中的灯光控制,声音控制等

补充:
PWM(脉冲宽度调制) 波特点:波形的周期/频率不会变化,占空比可以变化

占空比:波形的高电平时间占整个周期的比例。

注意:(方波:波形的周期/频率和占空比都可以变化 )。

比较输出原理

原理:当计数器的值和比较寄存器的值相同时会产生一个参考信号ocxref(一个完整周期),该参考信号再经过输出控制后,就通过OCX输出到外部。

细节描述:选择计数器向上计数,当计数器开始计数时,计数器的值 < 比较寄存器的值,此时产生一个高电平(或低电平),当计数器的值 > 比较寄存器的值,此时产生一个低电平(或高电平)。

总结:

(1)配置流程
 IO配置:
开时钟

复用功能

复用为定时器的通道x
(2)定时器配置
开时钟

配置计数器:1时基单元
(3)PWM配置过程:
1向比较寄存器写入一个比较值

2配置通道为输出方向

3 选择比较模式(PWM1/2)

4选择实际输出的有效电平
5打开输出通道

(4)输出PWM的:
周期: 由计数器的值来决定

占空比: 比较寄存器的值决定

6、STM32比较输出相关寄存器

通用定时器输出PWM 控制 LED 灯实现呼吸灯或控制灯的亮度

硬件:

选择将PC6复用为定时器3的通道1。
原因:定时器产生的 PWM 波和LED3 灯是同一个管脚,所以信号输出之后直接可以控制LED3,不用使用杜邦线将 LED 灯所在的管脚PWM 波所在的管脚连在一起。

/************************************
@brief:定时器3输出PWM管脚配置
@param:none
@return:none
@note TIM3->CH1 === PC6 控制灯的亮度
*************************************/
void Time3_Init(u16 arr, u16 ZKB)
{
    /*IO配置*/
    RCC->AHB1ENR |= 1 << 2;
    GPIOC->MODER &= ~(0X3 << 12);
    GPIOC->MODER |=(0x2 << 12);//复用功能
    GPIOC->AFR[0] &= ~(0XF << 24);
    GPIOC->AFR[0] |= 2 << 24;//PC6复用为定时器3的ch1
    /*2定时器配置*/
    RCC->APB1ENR |= 1 << 1;//打开TIM3的时钟
    /*时基单元配置*/
    //配置时基单元( 预分频,自动重载寄存器,计数值 )
    TIM3->ARR = arr - 1;//
    TIM3->PSC = 8400 -1;
    TIM3->CNT = 0;
    TIM3->CR1 = 0;
    TIM3->CR1 |= 1 << 7;//使用缓冲区
    //计数器递增计数
    //连续模式
    TIM3->CCR1 = ZKB;
    //UG位的使用手动产生更新事件
    //目的 : 首次配置将缓冲区的值加载到时基寄存器中
    TIM3->EGR |= 1 << 0;
    //清除更新一次标志位
    TIM3->SR &= ~(1 << 0);
    /*配置PWM*/
    TIM3->CCMR1 &= ~(0X3 << 8);//通道1配置为输出方向
    TIM3->CCMR1 |= (0X6 << 4);//选择PWM1模式
    TIM3->CCER &= ~(0X1 << 3);
    TIM3->CCER &= ~(0X1 << 1);//有效电平为高
    TIM3->CCER |= (0X1<< 0)//开启一在相应输出引脚上输出 OC1 信号
    //使能计数器
    TIM3->CR1 |= 1<< 0;
}



比较输出相关寄存器分析

TIMx 控制寄存器 1 (TIMx_CR1)

位7:决定当前ARR寄存器有没有影子寄存器

位6:5 --  00 选择边沿对齐模式

位4:选择递增还是递减模式

位3:

0:连续计数

1:单次计数

位2:1

位1:0--使能UEV

TIMx 从模式控制寄存器 (TIMx_SMCR)

TIMx DMA/中断使能寄存器 (TIMx_DIER)

TIMx 状态寄存器 (TIMx_SR)

更新中断标志位置1:就是一个周期结束

TIMx 事件寄存器 (TIMx_EGR)

TIMx 捕获/比较模式寄存器 1 (TIMx_CCMR1)

位7:0不受ETRF的影响

模式选择:一般可以选用PWM模式1

配置为00,选择输出模式

TIMx 捕获/比较模式寄存器 2 (TIMx_CCMR2)

和CCMR1一致,针对通道3和通道4

TIMx 捕获/比较使能寄存器 (TIMx_CCER)

TIMx 捕获/比较寄存器 1 (TIMx_CCR1)

比较输出:

软件设计

1、配置GPIO口

先打开GPIOC的时钟

配置PC6为复用功能

复用到TIM3_CH1

2、配置TIM3的通道1

打开TIM3的时钟

选择内部时钟源(84M)

写预分频值

写重装载值

配置一些基本的(CR1寄存器)

往CCR1里写值

把通道1配置为输出模式

选择CCR1有影子寄存器

生成更新事件(让UG位置1)

配置OCREF不受ETRF的影响

选择PWM模式1

选择不反相输出

使能OC1,让信号可以输出出去

使能更新中断标志位

配置中断优先级

让核心响应中断

使能是计数器

编写中断服务函数

不断改变CCR1的值

捕获输入

软件设计

1、GPIO口配置

先打开GPIOA的时钟

配置PA0为复用功能

复用到TIM5_CH1

2、TIM5_CH1配置

打开TIM3的时钟

选择内部时钟源(84M)

写预分频值

写重装载值

配置一些基本的(CR1寄存器)

选择CCR1有影子寄存器

生成一次更新事件

先滤波(82kHZ)

选择上下变沿都触发

将CH1映射到TI1上

选择输入模式

每一个边沿都会触发一次捕获事件

使能捕获通道

EGR的CC1G位置0代表不使用软件触发捕获

使能中断(捕获 /比较 1 中断使能,更新中断使能)

配置中断优先级

核心响应中断

使能计数器

编写中断服务函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1199663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习之基于Pytorch框架的MNIST手写数字识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 MNIST是一个手写数字识别的数据集&#xff0c;是深度学习中最常用的数据集之一。基于Pytorch框架的MNIST手写数字识…

牛客网刷题笔记231112 最小k位数+二叉树层序遍历+SQL异常邮件概率

算法题牛客网NC119 最小的k个数 题目&#xff1a; 用了一下python列表的便利&#xff0c;不知道在面试时允许用不。当然最简单的方法其实是直接sort()一下取前k位数即可。本次写的思路如下&#xff1a; 用一个最大容量为k的列表存储结果&#xff0c;遍历n个元素&#xff0c;当…

Python基础入门例程52-NP52 累加数与平均值(循环语句)

最近的博文&#xff1a; Python基础入门例程51-NP51 列表的最大与最小(循环语句)-CSDN博客 Python基础入门例程50-NP50 程序员节&#xff08;循环语句&#xff09;-CSDN博客 Python基础入门例程49-NP49 字符列表的长度-CSDN博客 目录 最近的博文&#xff1a; 描述 输入描…

【C++】stack,queue和deque

stack的介绍 stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xff0c;并提供一组特定 的成…

华为ensp:ospf动态路由

ip已配置好了 &#xff0c;现在进入路由器去宣告网段 R1 进入系统视图 ospf 1 area 1 network 192.168.1.0 0.0.0.255 network 1.1.1.0 0.0.0.255 R2 进入系统视图 ospf 1area 1 network 1.1.1.0 0.0.0.255 quit area 0 network 192.168.2.0 0.0.0.255 network 2.2…

Java13新增特性

前言 前面的文章&#xff0c;我们对Java9、Java10、Java11、Java12 的特性进行了介绍&#xff0c;对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 今天我们来一起看一下Java13这个版本的一些重要信息 版本介绍 Java 13 是在 2019 年 9 月 17 日…

不同性别人群的股骨颈骨密度随年龄的变化趋势

增龄是发生骨质疏松的危险因素。因此&#xff0c;中老年人需要积极防范骨质疏松&#xff0c;以免发生骨折等不良事件。 为了探究不同性别人群的股骨颈骨密度随年龄的变化趋势&#xff0c;首先创建一个df&#xff0c;变量有id&#xff08;编号&#xff09;、age&#xff08;年龄…

Linux:安装MySQL5.7

1. 下载 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/5.7.html#downloads 2. 解压 tar -xvf mysql-5.7.26-linux-glibc2.12-x86_64.tar 再移动并重命名一下 mv mysql-5.7.26-linux-glibc2.12-x86_64 /usr/local/mysql3. 创建mysql用户组和用户并修改权限 g…

山西电力市场日前价格预测【2023-11-13】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-13&#xff09;山西电力市场全天平均日前电价为428.16元/MWh。其中&#xff0c;最高日前电价为751.89元/MWh&#xff0c;预计出现在18: 30。最低日前电价为289.03元/MWh&#xff0c;预计…

【原型详解】JavaScript原型链:深入了解Prototype,超级详细!!!

&#x1f601; 作者简介&#xff1a;一名大四的学生&#xff0c;致力学习前端开发技术 ⭐️个人主页&#xff1a;夜宵饽饽的主页 ❔ 系列专栏&#xff1a;JavaScript进阶指南 &#x1f450;学习格言&#xff1a;成功不是终点&#xff0c;失败也并非末日&#xff0c;最重要的是继…

不使用 pip 安装 Python 包

在本文中&#xff0c;我们将学习如何在 Python 中安装没有 pip 的库。 我们还将学习如何使用 conda 命令在 Python 中安装包。 不使用 pip 命令安装 Python 库 在 Python 中&#xff0c;pip 命令是我们系统中安装开源库最常用的方法。 但是&#xff0c;除了 pip 命令之外&…

是谁为所欲为,将我的电脑控作己用?

在刚刚发完短篇小杂文《要找事做&#xff0c;我真怕被闲死》的投稿之后&#xff0c;笔者继续浏览社交网站的网页搜索...... 正看到《温州殡仪馆 》《温州动车723事故死亡高 》《 动车脱轨温州事件真正原因》《 浙江平阳县灭门惨案处理结果公布》《 温州厉秀珍死亡 》这一串又一…

C++ 中的内存分配 -- new 与 delete

c 常用的内存分配 分配释放类别是否可以重载mallocfreeC否newdeleteC 表达式(expressions)否operator new()operator delete()c 函数是operator new[]operator delete[]c 函数&#xff08;用于数组&#xff09;是allocator<T>::allocateallocator<T>::deallocatec …

java使用geotools导出shp文件

SHP格式是一种矢量数据格式&#xff0c;用于存储地理信息系统&#xff08;GIS&#xff09;数据。 SHP文件由一系列有序的文件组成&#xff0c;我们导出的shp文件包括.shp、.shx、.dbf、.prj以及.fix文件。 .shp&#xff08;shape&#xff09;文件&#xff1a;存储矢量地图数据&…

Ubuntu 22.04源码安装cmake 3.27.7

安装参考博客是《ubuntu安装cmake》和《Ubuntu 安装CMake》。 https://cmake.org/download是cmake官网下载的网址。 sudo wget -c https://github.com/Kitware/CMake/releases/download/v3.27.7/cmake-3.27.7.tar.gz可以下载源码&#xff0c;最后显示‘cmake-3.27.7.tar.gz’…

详解数据仓库之拉链表(原理、设计以及在Hive中的实现)

最近发现一本好书&#xff0c;读完感觉讲的非常好&#xff0c;首先安利给大家&#xff0c;国内第一本系统讲解数据血缘的书&#xff01;点赞&#xff01;近几天也会安排朋友圈点赞赠书活动(ง•̀_•́)ง 0x00 前言 本文将会谈一谈在数据仓库中拉链表相关的内容&#xff0c;包…

分类网络搭建示例

搭建CNN网络 本章我们来学习一下如何搭建网络&#xff0c;初始化方法&#xff0c;模型的保存&#xff0c;预训练模型的加载方法。本专栏需要搭建的是对分类性能的测试&#xff0c;所以这里我们只以VGG为例。 请注意&#xff0c;这里定义的只是一个简陋的版本&#xff0c;后续一…

基于猕猴感觉运动皮层的神经元Spike信号分析

公开数据集中文版详细描述参考前文&#xff1a;https://editor.csdn.net/md/?not_checkout1&spm1011.2124.3001.6192 目录 0. 公开数据集1. 神经元的raster和PSTH图1.1 Raster1.2 PSTH 2. 运动轨迹图 (center_out)3. 神经元的运动调制曲线 (tuning curve) 0. 公开数据集 …

Leetcode100120. 找出强数对的最大异或值 I

Every day a Leetcode 题目来源&#xff1a;100120. 找出强数对的最大异或值 I 解法1&#xff1a;模拟 枚举 2 遍数组 nums 的元素&#xff0c;更新最大异或值。 代码&#xff1a; /** lc appleetcode.cn id100120 langcpp** [100120] 找出强数对的最大异或值 I*/// lc c…

火爆进行中的抖音双11好物节,巨量引擎助5大行业商家开启爆单之路!

抖音双11好物节目前正在火热进行中&#xff0c;进入爆发期&#xff0c;各大商家“好招”频出&#xff0c;都想要实现高速增长。依托“人群、货品、流量”三大优势&#xff0c;巨量引擎一直都是商家生意增长的给力伙伴&#xff0c;在今年的抖音双11好物节&#xff0c;巨量引擎就…