STM32通用定时器,端口复用和重映射

news2025/1/12 22:50:36

STM32定时器是一种内置在STM32微控制器中的硬件模块,用于测量和控制时间。它具有高精度、可配置性和灵活性的特点,能够支持多种不同的工作模式和应用场景。以下是对STM32定时器的详细讲解:

一、定时器的基本构成

STM32定时器主要由以下几个部分构成:

  • 预分频器(Prescaler):用于对定时器的时钟频率进行分频,以降低计数器的计数速度,从而实现更长时间的定时。
  • 计数器(Counter):对预分频后的时钟信号进行计数,当计数值达到预设的自动重装载值(ARR)时,产生溢出事件或中断。
  • 自动重装载寄存器(Auto-reload Register, ARR):用于存储计数器的重装载值,当计数器溢出时,自动将重装载寄存器的值加载到计数器中,以实现周期性定时。

二、定时器的分类

STM32定时器根据其功能和特点可以分为以下几类:

  • 基本定时器(Basic Timers):功能较为简单,通常用于基本的计时和触发任务,如定时、触发输出直接驱动DAC等。
  • 通用定时器(General-Purpose Timers):提供了更多的功能和配置选项,包括PWM生成、脉冲计数、输入捕获、输出比较等功能。适用于需要更复杂的定时功能的应用,如PWM控制、频率测量、脉冲计数等。

特点:

  • 高级定时器(Advanced-Control Timers):除了通用定时器的功能外,还支持更高级的特性,如相位锁定回路(PLL)、编码器接口、三角波生成等。适用于需要更高级、复杂计时功能的应用,如音频处理、电机控制、编码器接口等。

三、定时器的工作原理

STM32定时器的工作原理基于计数器的计数功能。当定时器的时钟源开始工作时,计数器开始按照预设的计数方向和速率进行计数。当计数值达到自动重装载寄存器的值时,产生溢出事件或中断,同时计数器可以选择性地重新从0开始计数,以实现周期性定时。

四、定时器的配置要点

在配置STM32定时器时,需要注意以下几个要点:

  • 时钟源选择:定时器可以选择内部时钟或外部时钟作为时钟源。内部时钟通常来源于系统时钟(如APB1或APB2总线时钟),而外部时钟可以来自定时器引脚或其他外设的输出。
  • 计数模式选择:定时器支持向上计数、向下计数和中心对齐计数等多种计数模式。不同的计数模式适用于不同的应用场景。

  • 预分频值和重装载值设置:通过设置预分频值和重装载值,可以控制定时器的定时周期和精度。预分频值用于对时钟频率进行分频,而重装载值则决定了计数器的计数上限。
  • 中断和DMA配置:定时器可以配置为在溢出时产生中断或DMA请求,以便在定时结束后执行相应的处理函数或数据传输操作。

五、应用实例

通过中断控制LED灯闪烁

需要掌握的:

TIM_TimeBaseInitTypeDef

这个结构体用于配置定时器的基本时间基准参数,包括预分频器、计数器模式、自动重装载值、时钟分频和重复计数器(仅适用于TIM1和TIM8)。

  • TIM_Prescaler:预分频器值,用于将定时器时钟源进行分频,以减慢计数器的计数速度。
  • TIM_CounterMode:计数器模式,控制计数器的计数方向(向上、向下或中心对齐模式)。
  • TIM_Period:自动重装载值,当计数器达到此值时,将触发更新事件,并将此值重新加载到计数器中,实现周期性计数。
  • TIM_ClockDivision:时钟分频,用于控制定时器内部时钟的进一步分频,影响定时器的某些功能(如死区时间、更新事件等)的分辨率。
  • TIM_RepetitionCounter:重复计数器值,用于在更新事件时重复计数,常用于PWM模式中以控制PWM周期的数量。此参数仅对TIM1和TIM8有效。

NVIC_InitTypeDef

结构体是用于STM32微控制器中,特别是在配置嵌套向量中断控制器(NVIC)时使用的。这个结构体包含了配置一个中断通道所需的所有参数。下面是对每个成员的详细解释:

  1. uint8_t NVIC_IRQChannel;
    • 这个成员指定了要启用或禁用的中断通道。它的值应该来自于IRQn_Type枚举类型,这个枚举类型在STM32的库文件(如stm32f10x.h对于STM32F1系列)中定义,列出了所有可用的中断请求(IRQ)通道。
  2. uint8_t NVIC_IRQChannelPreemptionPriority;
    • 这个成员指定了NVIC_IRQChannel指定的中断通道的抢占优先级。STM32的NVIC支持基于优先级的嵌套中断,抢占优先级决定了中断是否能够打断另一个正在执行的中断。这个值的范围是从0到15,数值越小,优先级越高。
  3. uint8_t NVIC_IRQChannelSubPriority;
    • 这个成员指定了NVIC_IRQChannel指定的中断通道的子优先级。在抢占优先级相同的情况下,子优先级用于决定中断的执行顺序。这个值的范围也是从0到15,数值越小,优先级越高。
  4. FunctionalState NVIC_IRQChannelCmd;
    • 这个成员指定了NVIC_IRQChannel指定的中断通道是启用还是禁用。FunctionalState是一个枚举类型,通常有两个值:ENABLEDISABLE。这个成员用于控制中断的使能状态。

主函数:
 

/**  
 * @brief TIM2定时器更新中断服务例程  
 *   
 * 当TIM2定时器发生更新事件(即计数器从最大值回绕到0时)时,此函数会被自动调用。  
 * 它利用定时器的更新中断来切换连接到GPIOA端口的第1个引脚(GPIO_Pin_1)的电平状态。  
 * 这可以用于生成简单的方波信号或进行周期性的任务处理。  
 */  
void TIM2_IRQHandler(void)  
{  
    static uint16_t temp; // 定义一个静态变量temp,用于在中断之间保持状态  
  
    // 检查是否发生了TIM2的更新中断  
    if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  
    {  
        // 如果确实发生了更新中断  
  
        // 使用temp变量来切换状态,每次中断时temp自增  
        // 如果temp是奇数,则执行一个分支;如果是偶数,则执行另一个分支  
        if(temp++ % 2 == 1)  
        {  
            // 如果temp是奇数,将GPIOA的第1个引脚置为低电平  
            GPIO_ResetBits(GPIOA, GPIO_Pin_1);  
              
        }  
        else  
        {  
            // 如果temp是偶数,将GPIOA的第1个引脚置为高电平  
            GPIO_SetBits(GPIOA, GPIO_Pin_1);  
        }  
  
        // 清除TIM2的更新中断标志,以便允许下一个中断被识别  
        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  
    }  
  
    // 注意:在大多数情况下,不需要在这里添加else分支,  
    // 因为如果TIM_GetITStatus返回RESET,则没有必要执行任何操作。  
    // 但是,如果你希望在未发生更新中断时执行某些操作,可以在这里添加代码。  
}

定时器函数:

/**  
 * @brief 配置TIM2定时器  
 *   
 * 这个函数负责初始化STM32的TIM2定时器,包括时钟源、预分频器、自动重装载值、计数器模式等,  
 * 并启用定时器的更新中断,以及配置NVIC以允许定时器中断。  
 */  
void tim_config(void)  
{  
    TIM_TimeBaseInitTypeDef timinitstructer; // 定义一个定时器基本初始化结构体变量  
    NVIC_InitTypeDef nvicinitstruct;         // 定义一个NVIC初始化结构体变量  
  
    // 使能TIM2定时器的时钟  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);  
  
    // 配置NVIC的优先级分组为NVIC_PriorityGroup_1  
    // 这会影响所有中断的优先级设置方式  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
  
    // 配置TIM2定时器的基本参数  
    timinitstructer.TIM_ClockDivision = TIM_CKD_DIV1; // 时钟分频因子设置为不分频  
    timinitstructer.TIM_CounterMode = TIM_CounterMode_Up; // 计数器模式设置为向上计数  
    timinitstructer.TIM_Period = 10000 - 1; // 自动重装载寄存器周期值,这里设置为10000(实际计数到9999)  
    timinitstructer.TIM_Prescaler = 7200 - 1; // 预分频器值,这里设置为7200(实际分频7199)  
    // 注意:TIM_RepetitionCounter 字段在某些定时器中用于高级控制模式,如PWM重复计数,这里不适用  
    TIM_TimeBaseInit(TIM2, &timinitstructer); // 使用上述配置初始化TIM2定时器  
  
    // 启用TIM2定时器的更新中断  
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  
  
    // 启用TIM2定时器  
    TIM_Cmd(TIM2, ENABLE);  
  
    // 配置NVIC以允许TIM2中断  
    nvicinitstruct.NVIC_IRQChannel = TIM2_IRQn; // 指定中断通道为TIM2中断  
    nvicinitstruct.NVIC_IRQChannelCmd = ENABLE; // 使能该中断通道  
    nvicinitstruct.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级设置为1  
    nvicinitstruct.NVIC_IRQChannelSubPriority = 1; // 子优先级设置为1(在NVIC_PriorityGroup_1中,子优先级可能不被使用)  
    NVIC_Init(&nvicinitstruct); // 使用上述配置初始化NVIC  
}

理解为什么这段代码能够让定时器“看起来”一秒一秒地执行,需要关注几个关键点:定时器的预分频器(Prescaler)、自动重装载值(Period)、以及STM32的时钟系统。

首先,让我们回顾一下tim_config函数中的关键设置:

  1. 预分频器(Prescaler):这个值用于将定时器的时钟源(通常是系统时钟经过APB1预分频后的时钟)进一步分频。例如,如果系统时钟是72MHz,并且APB1预分频器设置为1(意味着APB1时钟与系统时钟相同),然后TIM2的预分频器设置为7199(因为你写的是7200-1),那么TIM2的计数器时钟将是72MHz / (7199 + 1) = 10kHz。

  2. 自动重装载值(Period):这个值定义了定时器计数器在达到哪个值时会触发更新事件(通常是回绕到0并生成更新中断),并重新开始计数。在你的代码中,这个值被设置为9999(因为你写的是10000-1)。因此,从0计数到9999需要的时间是10kHz的倒数乘以10000,即0.0001秒 * 10000 = 1秒。

现在,让我们看看TIM2_IRQHandler函数是如何工作的:

  • 当定时器计数器从9999回绕到0时,会生成一个更新中断。
  • TIM2_IRQHandler函数被调用,并检查是否确实发生了更新中断。
  • 如果是,它会切换一个GPIO引脚的状态(在这个例子中是GPIOA的第1个引脚),并清除中断标志以准备下一次中断。
  • 由于定时器的周期被设置为1秒(基于预分频器和自动重装载值的设置),因此这个GPIO引脚的状态会每秒切换一次,从而“看起来”像是定时器一秒一秒地执行。

然而,这里有一点需要注意:虽然定时器的周期是精确的1秒(基于其配置),但GPIO引脚状态的切换(即方波的生成)的精确性还受到中断响应时间和中断处理函数执行时间的影响。在大多数情况下,这些影响是可以忽略不计的,但在对时间要求非常严格的应用中,可能需要考虑这些因素。

另外,请注意,temp变量在这个特定的例子中实际上并没有直接用于控制定时器的周期或频率。它仅用于在每次中断时切换GPIO引脚的状态。如果你想要的是纯粹的定时器功能(即不需要GPIO切换),那么temp变量和相关的条件判断就不是必需的。不过,在你的例子中,它用于生成一个周期为1秒的方波信号,从而实现LED灯的闪烁。

端口复用

定义
STM32的每个端口引脚通常具有多种功能,例如GPIO(通用输入输出)、USART(通用同步异步收发传输器)、TIM(定时器)等。端口复用是指将一个引脚从默认的GPIO功能切换到其他功能,如USART的TX(发送)或RX(接收)等。

实现步骤

使能GPIO端口时钟和外设时钟
首先,需要使能包含USART1 TX和RX引脚的GPIO端口(如果是PA9和PA10,则是GPIOA)的时钟,以及USART1的时钟。

配置GPIO引脚
将GPIO引脚(PA9和PA10)配置为复用推挽输出(对于TX)和浮空输入(对于RX)。注意,在STM32的库中,复用模式通常是通过设置GPIO的模式为GPIO_Mode_AF_PP(复用推挽输出)或GPIO_Mode_IN_FLOATING(浮空输入,但RX通常不需要显式设置,因为它在USART初始化时自动配置)来实现的。然而,对于USART的RX,你通常会设置它为GPIO_Mode_AF_IPU(复用输入上拉),但这取决于你的具体需求和硬件配置。

初始化USART
最后,初始化USART1,设置波特率、数据位长度、停止位等参数。在这个过程中,库函数会自动将TX和RX引脚配置为它们的外设功能模式。

重映射

定义
重映射功能允许开发者将一个外设的引脚映射到其他引脚,以适应不同的硬件布局需求。这在进行硬件设计时特别有用,可以解决引脚冲突或优化引脚布局。

实现步骤

使能AFIO时钟(对于某些STM32系列,如STM32F1,需要使能AFIO时钟以访问重映射功能。但在更新的STM32系列中,这一步骤可能已被简化或取消):通过配置RCC(复位和时钟控制)模块,使能包含重映射寄存器的时钟。

配置重映射寄存器:使用STM32的库函数或直接操作重映射寄存器,将外设的引脚映射到新的位置。这通常涉及到设置特定的重映射位或选择重映射选项。

注意

  • 复用与重映射的区别:复用是针对单个引脚,改变其功能;而重映射是针对一组引脚,改变其物理位置。
  • 部分重映射与完全重映射:部分重映射只改变部分功能引脚的位置,而完全重映射则改变所有功能引脚的位置。
    • 在进行重映射时,需要注意不要将同一功能映射到多个引脚上,因为这会导致冲突。、

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

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

相关文章

内存管理————基础理解

目录 我们先看以下代码和内存分布图 对一些名词的解释说明: 题目 答案 问题解释: C语言中动态内存管理方式 C语言中动态内存管理方式:malloc/calloc/realloc/free 这里提一下要注意的点 C内存管理方式 基本内容 new/delete操作内置…

常用API:object

文章目录 Object类toString()方法equals()方法总结其他方法 黑马学习笔记 Object类 是所有类的父类,所有的类都默认继承Object类。Java中所有的类的对象都可以直接使用Object类提供的一些方法。 toString()方法 equals()方法 默认是判断两个对象的地址 也是判断…

MATLAB-疲劳检测

首先,我们需要解决一个问题,什么样可以视为疲劳? 频繁的眨眼/眨一次眼所用时间很长 不停的打哈欠 不停的点头 通过分析,我们得到了检测疲劳的三个标准:眨眼,打哈欠,头部姿态。 这三个标准可以…

OpenCV findTours函数及其用法

OpenCV findTours函数主要用以寻找图像中物体的轮廓,其原型如下: indTours 函数参数: Image 输入图像,需8位单通道图像。非零像素被视为1。零像素保持为0,因 此图 像被视为 二进制。您可以使用co…

【数据分享】《全国能源-分行业煤油消费总量》(2000-2020年)

而今天要限时免费分享的数据就是2000-2020年间出版的《全国能源-分行业煤油消费总量》并以多格式提供免费下载。(无需分享朋友圈即可获取) 数据介绍 在过去的二十年里,中国作为全球能源消费的重要力量,其能源结构的变化不仅影…

基于x86 平台opencv的图像采集和seetaface6的图像质量评估功能

目录 一、概述二、环境要求2.1 硬件环境2.2 软件环境三、开发流程3.1 编写测试3.2 配置资源文件3.2 验证功能一、概述 本文档是针对x86 平台opencv的图像采集和seetaface6的图像质量评估功能,opencv通过摄像头采集视频图像,将采集的视频图像送给seetaface6的图像质量评估模块…

21.1 基于Netty实现聊天

21.1 基于Netty实现聊天 一. 章节概述二. `Netty`介绍三. 阻塞与非阻塞1. 阻塞与非阻塞简介2. BIO同步阻塞3. NIO同步非阻塞4. AIO异步非阻塞IO5. 异步阻塞IO(用的极少)6. 总结四. Netty三种线程模型1. 单线程模型2. 多线程模型3. 主从线程模型五. 构建Netty服务器************…

DDL——三范式与表约束

目录 一、三大范式 1.范式的定义 2.第一范式 3.第二范式 4.第三范式 二、表约束 1.约束的定义 2.非空约束(not null) 3.唯一性约束(unique) 4.主键约束(primary key) 5.外键约束(fo…

可集成多模型的机器人开发框架 dora:让机器人编程走向大众

作者 | Annie Xu 责编 | 何苗 出品 | GOSIM 开源创新汇 C 和 C是机器人编程中常用的编程语言,但学起来存在一定难度。那些对机器人感兴趣,但没有精力花费数周时间学习 C 和 C编程的用户只能望而却步。 为了让机器人技术变得更简单,陶海轩&a…

AWS SAM CLI 备忘单!

安装 AWS SAM CLI brew tap aws/tap brew 安装 aws-sam-cli 验证安装 $ sam --version 升级 SAM $ brew upgrade aws-sam-cli 您需要 AWS 凭证才能在 AWS 上工作。 构建并部署简单应用程序 $ sam init→ 下载示例应用程序 $ sam build→ 构建您的应用程序 $ sam deploy --guid…

机器学习:决策树回归树实现

1、决策树: 是一种树形结构,用于通过一系列的是非问题来预测目标值。在决策树回归中,树的叶子节点代表预测的连续值。 2、数据准备: 收集数据集,并对其进行清洗和预处理。 将数据集分为特征(X)…

git-20240822

目录 初始化仓库 Git init Git init project --bare 查看提交的记录 git log --prettyoneline 查看当前git远程库地址 git remote -v 查看详细提交记录 git log 撤出暂存区的文件 git reset HEAD file(.代表全部文件) 提交数据到远程仓库 git config --global push.…

4.6算法之贪心_702:Crossing River

题目 702:Crossing River 总时间限制: 1000ms 内存限制: 65536kB 描述 A group of N people wishes to go across a river with only one boat, which can at most carry two persons. Therefore some sort of shuttle arrangement must be arranged in order to row the boat…

【TB作品】普中V2,数字时钟万年历显示,音乐闹钟,流水灯,Proteus仿真

文章目录 功能硬件原理图LCD1602独立按键LED灯ds1302蜂鸣器 引脚汇总按键功能code 功能 带闹钟和花样流水灯的LCD数显实时时钟设计(运用DS1302时钟模块,LCD显示,带万年历,时间到响音乐显示花样流水灯) 万年历显示 按…

禹神:三小时快速上手TypeScript,TS速通教程(上篇、中篇、下篇,3合1笔记),根据视频整理

TypeScript快速上手 📚一、TypeScript简介 1.TypeScript由微软开发,是其于JavaScript的一个扩展语言. 2.TypeScript包含了JavaScript的所有内容,即:TypeScript是JavaScript的超集 3.TypeScript增加了:静态奖型检查、接…

Win10安装ChatTTS-2024-cuda10.1

0x00 前言 ChatTTS是专门为对话场景设计的文本转语音模型,例如大语言助手对话任务。它支持英文和中文两种语言。最大的模型使用了10万小时以上的中英文数据进行训练。目前在huggingface中的开源版本为4万小时训练且未SFT的版本。 0x01 准备环境 版本操作系统Win1…

大模型参数高效微调技术总结

基础知识 最近,OpenAI推出的ChatGPT展现出了卓越的性能,引发了大规模语言模型(Large Language Model, LLM)的研究热潮。大规模语言模型的“大”体现在两个方面:模型参数规模大,训练数据规模大。以GPT3为例,GPT3的参数…

springboot集成redis之接口缓存

什么是redis的接口缓存? Redis的接口缓存是一种利用Redis这种内存数据库来存储接口(API)响应数据的技术,以提高应用程序的响应速度和性能。具体来说,当用户请求一个接口时,系统会首先检查Redis缓存中是否已…

windows vs2022 MFC使用webview2嵌入网页

Microsoft Edge WebView2 控件允许在本机应用中嵌入 web 技术(HTML、CSS 以及 JavaScript)。 WebView2 控件使用 Microsoft Edge 作为绘制引擎,以在本机应用中显示 web 内容。 一、通过菜单“项目”-“管理NuGet程序包”,下载相关包 二、安装 Microsof…

windows ssh launch Jenkins

一、 windows server2012 ssh launch jenkins 经过一系列测试验证发现,windows server2012始终无法launch到jenkins master。配置ssh之后 [08/21/24 10:08:03] [SSH] Opening SSH connection to 172.xx.xx.xx:18822. [08/21/24 10:08:03] [SSH] WARNING: SSH Host …