2.4 定时器与TIM中断

文章目录


时钟与时钟树

频率:如72Mhz即为每秒72M个脉冲

  • 时钟的源头

    晶振

  • 时钟树的分支
    分频器 :分频器是一种将输入时钟信号的频率降低到 其整数倍的电路。
    倍频器 :倍频器则是将输入时钟信号的频率提高到 其整数倍的电路。
    参考CSDN文章_时钟系统

他们可以通过改变频率实现不同频率的分支。

stm32时钟树


《STM32F103C8T6从入门到精通》SystemInit函数详细讲解

St公司的配置程序:江科大

  1. 8Mhz HSI做系统时钟
  2. 再打开HSE取8Mhz 再通过图中黄色路线到锁相环(PLL)倍频9倍,待锁相环输出稳定后,(红色区域)切换锁相环输出为系统时钟 但是,如果外部晶振HSE出现问题,就不会切换,而是继续使用系统内部时钟HSI.
  • 在参考手册中的RCC的CR寄存器中的HSION位的部分 找到了对上面过程的说明
  1. APB1二分频为36mhz APB2不分频,为72mhz
    • PCLK2通常指的是APB2 (Advanced Peripheral Bus 2) 的时钟频率。它的频率通常是由更高频率的AHB (Advanced High-performance Bus) 时钟通过一个分频器来调整得到的。
    • 参考以下代码(位于systemInit函数中调用的SetSysClockTo72函数中)

stm32时钟树_站内跳转

时钟树动画简介

可以手动把系统时钟72mhz改成其他的吗?

可以通过更改这里的宏来实现。
具体代码梳理

ST公司给的外围设备配置文件 的 默认配置说明

《STM32F103C8T6从入门到精通》SystemInit函数详细讲解 该函数配置了系统时钟

在system_stm32f10x.c文件中提到

  • HSI 作为默认时钟源
    HSI (High Speed Internal):内部高速时钟,频率为 8 MHz。每次设备复位后,HSI 自动作为系统时钟源。
    SystemInit() 函数:在启动文件 startup_stm32f10x_xx.s 中定义的函数,用于配置系统时钟。该函数在跳转到主程序前被调用。
  • 时钟源故障处理
    如果用户选择的系统时钟源未能成功启动(例如,外部时钟源未正常工作),SystemInit() 函数将不做任何处理,系统将继续使用 HSI 作为时钟源。
    用户可以在 SetSysClock() 函数中添加代码来处理这种情况,例如重新配置时钟源或进行错误处理。
  • HSE 晶振配置
    HSE (High Speed External):外部高速时钟,通常由外部晶振提供。
    默认情况下,HSE 晶振的频率设置为 8 MHz 或 25 MHz,具体取决于所使用的 STM32F10x 产品。
    HSE_VALUE 定义在 stm32f10x.h 文件中,用于指定 HSE 的频率。
    如果使用 HSE 作为系统时钟源(直接或通过 PLL),并且使用了不同的晶振频率,需要调整 HSE_VALUE 以匹配实际使用的晶振频率。

定时器

cortex-M3 内核里有一个systick定时器(江科大的Delay函数就是用systick实现的)

而下面要提到的是核外外设,高级、通用、普通定时器

什么是定时器

定时器就是计数器
定时器就是计数器
定时器就是计数器
动画演示_B站

PS: 预分频器和计数器的长度都是16bit ,2^16^ = 65536

  • 预分频器(Prescaler) ·:预分频器的值规定在0 ~ n-1(n是输入时钟频率的数值)

    它像是计数器的一个助手,规定每隔几个脉冲 向计数器报告一次,让计数器加1

    1. 当预分频的值为零时,每一个脉冲计数器加一次;设定值为1时,每隔两个脉冲,计数器加1。
    2. 预分频器的作用:可以增加定时器的定时上限:
    • 当预分频器设置为0时,一个脉冲就记一次,因为计数器最多定65536下,对应65536 * (1/72M) ≈ 0.00091秒。
    • 而当预分频器设置为65535时,每72M个脉冲记一次,因为计数器还是最多定65536下,对应时间为,65536 * 65536 * (1/72M) ≈ 59.65 秒 (计数器的值预分频器 处理的记一次对应的脉冲数 再乘 一个脉冲对应的时间)
    • 可见,预分配器正是通过自己额外处理时钟脉冲数来提高总时间的
  • 计数器(Counter)

    • 基本定时器只有向上计数模式。(从零开始加)
    • 通用定时器与高级定时器有向上计数、向下计数(从设定值开始减)、中央计数模式。
  • 自动重装载寄存器(Auto Reload Register) :在计数器到达该寄存器设定值时清零计数器,并同时(如果配置了)

    可触发中断。

定时器的类型

类型 编号 总线 功能
高级定时器 TIM1、TIM8 APB2 拥有通用定时器全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能
通用定时器 TIM2、TIM3、TIM4、TIM5 APB1 拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能
基本定时器 TIM6、TIM7 APB1 拥有定时中断、主模式触发DAC的功能 如何理解主模式触发

STM32C8T6 只有TIM1,TIM2,TIM3,TIM4

影子寄存器 | 预装载寄存器(Preload Register)

在学习TIM定时器时了解到。影子寄存器的主要功能缓冲后台存储数据或配置设置,这样在执行某些关键操作时,可以避免由于直接修改主寄存器而导致的问题。

  • 作用(用时序图作示例)
    • 可看出当 预分频控制寄存器 更改数值后,对应在定时器时钟 的输出没有随之改变(预分频缓冲器 在缓冲)
      而是等上一个定时器时钟记满(到下一个计数周期,触发更新事件),才起更改作用。
    • 省流版:让值的变化更新事件 同步发生
  • 在框图中的阴影标识 江科大

相关工程问题

一上电就进了定时中断?可能为了是避免影子寄存器的缓冲带来的副作用

在配置时基单元时,库函数为了让预分频器立刻起作用(因为有缓冲,要等事件才会更新数据),手动配置了一个事件,同时触发了定时中断


通用定时器 相关框图

用作文章查阅参考

  • 绿色部分(IC input compare)的细节图

  • 红色部分 (OC Output Compare)


定时中断

  1. 配置时钟源 (注意一点:这里的内部外部时钟的概念【脉冲】与时钟树的内部外部时钟源【震荡源输出到AHB总线】不同)
    • 如果第二步打算配置为rcc的话,就初始化对应定时器的rcc时钟 (选择系统时钟rcc作为输入,起定时作用)
    • 若第二步选择外部时钟,则配置为ETR (选择外部脉冲作为输入,如对射红外传感器,遮挡一次一个脉冲)(注意GPIO是指定的)
  2. 选择输入时基单元的时钟(上图中黄色部分)
  1. 配置时基单元
    void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct)
  • 参数1:对应定时器
  • 参数2:结构体里有五个参数
    • TIM_Period

      TIM_Period 设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。

    • TIM_Prescaler

      TIM_Prescaler 设置了用来作为 TIMx 时钟频率除数的预分频值。

    • TIM_CounterMode

      配置计数方式(向上计数、向下计数、中央对齐计数)

    • TIM_ClockDivision (用于输入滤波)

      按一定频率对信号进行采样,来判断信号是否稳定(而这个采样频率来自于系统内部时钟,这里的参数就是对内部时钟再进行分频) b站讲解

      主要用于输入检测、死区时间设定等 STM32 时钟分割TIM_ClockDivision配置及使用详细说明

    • TIM_RepetitionCounter (高级定时器才有的功能,配置通用定时器时给0)

      重复计数器

  1. 配置输出控制
    • TIM_ITConfig用这个函数
    • 其中有一个参数比较关键:TIM_IT (毕竟TIM外设有很多不同的中断)

    • 更新中断 (Update Interrupt) 是基于定时器自身的计数完成事件。
      捕获/比较中断 (Capture/Compare Interrupts) 是基于定时器计数器与特定通道的CCR值之间的关系。
      触发中断(Trigger Interrupt) 是基于外部触发信号的到达。
  2. 配置NVIC(配置中断优先级)
  3. 运行控制(相当与一个总开关)

OC(Output Compare)输出比较

  • 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
  • 每个高级 定时器和通用定时器都拥有4个输出比较通道
  • 高级定时器的前3个通道额外拥有死区生成和互补输出的功能(多用于驱动三相无刷电机)

OC_Mode 输出模式控制

模式介绍
点击跳转比较输出结构图

模式 描述
冻结 CNT=CCR时,REF保持为原状态
匹配时置有效电平(理解为高电平) CNT=CCR时,REF置有效电平
匹配时置无效电平(理解为低电平) CNT=CCR时,REF置无效电平
匹配时电平翻转 CNT=CCR时,REF电平翻转
强制为无效电平 CNT与CCR无效,REF强制为无效电平
强制为有效电平 CNT与CCR无效,REF强制为有效电平
PWM模式1 向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平 向下计数:CNT>CCR时,REF置无效电平,CNT≤CCR时,REF置有效电平
PWM模式2 向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平 向下计数:CNT>CCR时,REF置有效电平,CNT≤CCR时,REF置无效电平

PWM (Pulse Width Modulation)脉冲宽度调制

在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域

PWM参数:

  1. 频率 = 1 / T~S~
    频率越高越平稳
  2. 占空比 = T~ON~ / T~S~
    等效输出比
  3. 分辨率 = 占空比变化步距
    占空比变化的精细程度
  • PWM输出流程
  1. 按照定时中断配置 的前两步配置好时钟(通常选择内部脉冲RCC)输入
  2. 接着配置时基单元 ,再将下图的结构配置好
  3. 需要注意的一点是:初始化GPIO时,要配置为复用推挽输出模式(将输出的控制权从输出寄存器转到定时器)
  4. 最后配置计数器使能(总开关)
    • 对于输出比较单元的配置函数参数,有一个结构体,在配置通用定时器时很多都用不到,所以我们可以用给的结构体初始化函数先给结构体初始化一下。
  • PWM参数计算
    • 一个变化周期 对应 计数器的计数周期
    • 频率等于一个变化周期的倒数
    • 占空比 Duty = CCR / (ARR + 1) 高电平计数值 比 总计数值
    • 分辨率 Reso = 1 / (ARR + 1)
相关推荐
Charles Ray6 分钟前
C++学习笔记 —— 内存分配 new
c++·笔记·学习
重生之我在20年代敲代码7 分钟前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
我要吐泡泡了哦1 小时前
GAMES104:15 游戏引擎的玩法系统基础-学习笔记
笔记·学习·游戏引擎
骑鱼过海的猫1231 小时前
【tomcat】tomcat学习笔记
笔记·学习·tomcat
贾saisai3 小时前
Xilinx系FPGA学习笔记(九)DDR3学习
笔记·学习·fpga开发
北岛寒沫3 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习
烟雨666_java3 小时前
JDBC笔记
笔记
2401_858286113 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
GEEKVIP3 小时前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑
jiao000015 小时前
数据结构——队列
c语言·数据结构·算法