文章目录
- 时钟与时钟树
-
- stm32时钟树
- 可以手动把系统时钟72mhz改成其他的吗?
- [ST公司给的外围设备配置文件 的 默认配置说明](#ST公司给的外围设备配置文件 的 默认配置说明)
- 定时器
- [通用定时器 相关框图](#通用定时器 相关框图)
- 定时中断
-
- [OC(Output Compare)输出比较](#OC(Output Compare)输出比较)
-
- [OC_Mode 输出模式控制](#OC_Mode 输出模式控制)
- [PWM (Pulse Width Modulation)脉冲宽度调制](#PWM (Pulse Width Modulation)脉冲宽度调制)
时钟与时钟树
频率:如72Mhz即为每秒72M个脉冲
-
时钟的源头
晶振
-
时钟树的分支
分频器 :分频器是一种将输入时钟信号的频率降低到 其整数倍的电路。
倍频器 :倍频器则是将输入时钟信号的频率提高到 其整数倍的电路。
参考CSDN文章_时钟系统
他们可以通过改变频率实现不同频率的分支。
stm32时钟树
《STM32F103C8T6从入门到精通》SystemInit函数详细讲解
St公司的配置程序:江科大
- 8Mhz HSI做系统时钟
- 再打开HSE取8Mhz 再通过图中黄色路线到锁相环(PLL)倍频9倍,待锁相环输出稳定后,(红色区域)切换锁相环输出为系统时钟 但是,如果外部晶振HSE出现问题,就不会切换,而是继续使用系统内部时钟HSI.
- 在参考手册中的RCC的CR寄存器中的HSION位的部分 找到了对上面过程的说明
- APB1二分频为36mhz APB2不分频,为72mhz
- PCLK2通常指的是APB2 (Advanced Peripheral Bus 2) 的时钟频率。它的频率通常是由更高频率的AHB (Advanced High-performance Bus) 时钟通过一个分频器来调整得到的。
- 参考以下代码(位于systemInit函数中调用的SetSysClockTo72函数中)
可以手动把系统时钟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。
- 预分频器的作用:可以增加定时器的定时上限:
- 当预分频器设置为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)
定时中断
- 配置时钟源 (注意一点:这里的内部外部时钟的概念【脉冲】与时钟树的内部外部时钟源【震荡源输出到AHB总线】不同)
- 如果第二步打算配置为rcc的话,就初始化对应定时器的rcc时钟 (选择系统时钟rcc作为输入,起定时作用)
- 若第二步选择外部时钟,则配置为ETR (选择外部脉冲作为输入,如对射红外传感器,遮挡一次一个脉冲)(注意GPIO是指定的)
- 选择输入时基单元的时钟(上图中黄色部分)
- 配置时基单元
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)
重复计数器
-
- 配置输出控制
- TIM_ITConfig用这个函数
- 其中有一个参数比较关键:TIM_IT (毕竟TIM外设有很多不同的中断)
更新中断 (Update Interrupt) 是基于定时器自身的计数完成事件。
捕获/比较中断 (Capture/Compare Interrupts) 是基于定时器计数器与特定通道的CCR值之间的关系。
触发中断(Trigger Interrupt) 是基于外部触发信号的到达。
- 配置NVIC(配置中断优先级)
- 运行控制(相当与一个总开关)
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 / T~S~
频率越高越平稳 - 占空比 = T~ON~ / T~S~
等效输出比 - 分辨率 = 占空比变化步距
占空比变化的精细程度
- PWM输出流程
- 按照定时中断配置 的前两步配置好时钟(通常选择内部脉冲RCC)输入
- 接着配置时基单元 ,再将下图的结构配置好
- 需要注意的一点是:初始化GPIO时,要配置为复用推挽输出模式(将输出的控制权从输出寄存器转到定时器)
- 最后配置计数器使能(总开关)
- 对于输出比较单元的配置函数参数,有一个结构体,在配置通用定时器时很多都用不到,所以我们可以用给的结构体初始化函数先给结构体初始化一下。
- PWM参数计算
- 一个变化周期 对应 计数器的计数周期
- 频率等于一个变化周期的倒数
- 占空比 Duty = CCR / (ARR + 1) 高电平计数值 比 总计数值
- 分辨率 Reso = 1 / (ARR + 1)