6 定时器(TIM)
1 定时器简介
- TIM(Timer)定时器
- 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断
- 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时
- 不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能
- 根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型
2 定时器类型
STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4
3 定时器结构图
1 基本定时器
-
预分频器对时钟进行分频,实际分频系数和预分频器之间差了1,由于预分频器是16位,最大值是65535,所以可以得到实际分频65536
-
计数器可以对预分频后的计数时钟进行计数,来一个上升沿就+1,也是16位,可以从0-65535,不断自增运行
-
当计数器的值运行到和自动重装载寄存器(存放计数目标值)的值一致时,产生中断,计数器清0
-
UI就是产生的更新中断信号,会通往NVIC
-
U就是产生的更新事件,不会触发中断,但是可以触发内部其他电路工作
-
PSC、CNT和自动重装载寄存器三者结合称为时基单元
2 通用定时器
-
通用定时器和高级定时器不仅支持向上计数,还支持向下计数和中央对齐计数模式
- 向上计数和基本定时器一样,就是从0计数到重装值申请中断然后重新置0,而且基本定时器仅支持这种计数方式
- 向下计数就是从重装值开始减到0申请中断,再置为重装值
- 中央对齐计数就是先从0开始增到重装值申请中断,然后再从重装值开始减到0申请中断,如此往复
-
通用计时器时钟源不仅能选择72MHz的内部时钟,还可以选择外部时钟(比如TIMx_ETR,TRGI,TIMx_CH1-4,其他定时器)
-
ITR信号是来自其他定时器的TRGO输出,可以实现定时器级联的功能
-
TRGO是主模式输出
-
编码器接口可以读取正交编码器的输出波形
-
输出比较电路,共四个通道,可以用于输出PWM波形,驱动电机
-
输入捕获电路,可以用于测量输入方波的捕获
-
捕获/比较寄存器,输入捕获和输出比较共用的寄存器
3 高级定时器
- 重复次数计数器:可以实现每隔几个周期更新一次,相当于对于输出的周期信号进行分频
- DTG(Dead Time Generate):死区生成电路,为防止互补输出的PWM驱动桥臂时,在开关切换的瞬间由于器件不理想,造成短暂的直通现象,在开关切换的瞬间产生一定的死区,切断桥臂上下管防止直通
- 右边的输出引脚前三路由通用定时器的一个变为两个互补输出,可以输出一对互补的PWM波,可以驱动三相无刷电机(四轴飞行器、电动车的后轮、电钻…)
- 最下面那一部分就是刹车输入的功能,为了给电机驱动提供安全保障
4 定时中断基本结构图
4 时序图
1 预分频器时序
- 计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)
- 注意在这里预分频器防止在计数中途更改造成错误,设置了预分频缓冲器。在这里体现的现象就是在预分频控制寄存器更改的时候,预分频缓冲寄存器并未更改,而是在这一个计数周期结束,也就是计数值达到自动重装载寄存器的值的时候进行更改
2 计数器时序
- 计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1) = CK_PSC / (PSC + 1) / (ARR + 1)
- ARR是自动重装载寄存器
- ARR也是有缓冲寄存器的,和上面预分频器类似,有缓冲机制
3 计数器无预装时序
可以看到在计数过程中对自动加载寄存器进行更改,由FF改成36,在这个计数周期内就立即生效
4 计数器有预装时序
可以看到在计数过程中对自动加载寄存器进行更改,从F5改为36,可以看到自动加载影子寄存器并未发生变化,而是等这个计数周期结束之后才进行更改
5 时钟树
6 TIM输出比较
- OC(Output Compare)输出比较
- 输出比较可以通过比较CNT(时基单元计数器)与CCR(捕获/比较寄存器)寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形
- 每个高级定时器和通用定时器都拥有4个输出比较通道
- 高级定时器的前3个通道额外拥有死区生成和互补输出的功能
1 PWM(Pulse Width Modulation)简介
- PWM(Pulse Width Modulation)脉冲宽度调制
- 在具有惯性的系统中,可以通过对一系列脉冲的宽度进行调制,来等效地获得所需要的模拟参量,常应用于电机控速等领域
- PWM参数:
- 频率 = 1 / TS
- 占空比 = TON / TS(高电平时间比整个周期时间)
- 分辨率 = 占空比变化步距(占空比变化的精确程度)
2 通用定时器的输出比较通道
3 输出比较模式
4 PWM基本结构
5 参数计算
- PWM频率: Freq = CK_PSC / (PSC + 1) / (ARR + 1)
- PWM占空比: Duty = CCR / (ARR + 1)
- PWM分辨率: Reso = 1 / (ARR + 1)
6 高级定时器的输出比较电路(仅了解)
7 舵机
- 舵机是一种根据输入PWM信号占空比来控制输出角度的装置
- 输入PWM信号要求:周期为20ms,高电平宽度为0.5ms~2.5ms
- 将PWM当做一种通信协议来使用
硬件电路:
8 直流电机及驱动简介
- 直流电机是一种将电能转换为机械能的装置,有两个电极,当电极正接时,电机正转,当电极反接时,电机反转
- 直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作
- TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向
硬件电路:
7 TIM输入捕获
- IC(Input Capture)输入捕获
- 输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
- 每个高级定时器和通用定时器都拥有4个输入捕获通道
- 可配置为PWMI模式,同时测量频率和占空比
- 可配合主从触发模式,实现硬件全自动测量
- 由于输入捕获和输出比较是共用引脚和寄存器,所以对于某个定时器的某个通道,只能使用一个输入捕获或者输出比较,不能共用
1 频率测量
-
测频法:在闸门时间T内,对上升沿计次,得到N,则频率
f x = N / T f_x=N / T fx=N/T -
测周法:两个上升沿内,以标准频率fc计次,得到N ,则频率
相当于说测一个周期的时间是N/fc,然后取倒数就是频率
f x = f c / N f_x=f_c / N fx=fc/N
-
中界频率:测频法与测周法误差相等的频率点
f m = f c / T f_m=\sqrt{f_c / T} fm=fc/T
测频法,要求频率高一些精确度更高,测周法要求频率低一些,这样计次会更多,多高算高,多低算低,就看中界频率。当待测信号频率小于中界频率时,选测频法更合适,反之测周法更合适。
2 输入捕获通道
3 主从触发模式
- 主模式可以将定时器内部的信号,映射到TRGO引脚,用于触发别的外设
- 从模式就是接收其他外设或者自身外设的信号,用于控制自身定时器的运行,也就是被别的信号控制
- 触发源选择,就是选择从模式的触发信号源,可以认为是从模式的一部分
4 输入捕获基本结构
5 PWMI基本结构
8 定时器编码器接口
- Encoder Interface 编码器接口
- 编码器接口可接收增量(正交)编码器的信号,根据编码器旋转产生的正交信号脉冲,自动控制CNT自增或自减,从而指示编码器的位置、旋转方向和旋转速度
- 每个高级定时器和通用定时器都拥有1个编码器接口
- 两个输入引脚借用了输入捕获的通道1和通道2
1 正交编码器
2 编码器接口的基本结构
3 工作模式
4 实例(使用在TI1和TI2上计数,不反向)
5 实例(使用在TI1和TI2上计数,TI1反向)
也就是TI1的极性翻转
7 ADC模数转换器
-
ADC(Analog-Digital Converter)模拟-数字转换器
-
ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁
12位逐次逼近型ADC,1us转换时间 -
输入电压范围:03.3V,转换结果范围:04095
-
18个输入通道,可测量16个外部和2个内部信号源
-
规则组和注入组两个转换单元
-
模拟看门狗自动监测输入电压范围
-
STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道
1 逐次逼近型ADC
2 ADC框图
拿点菜举例子,传统ADC就是你点一个菜,做一个菜,然后做好了你可以再点
而STM32的ADC是你点一个菜单,让它做,这就是所谓的分组和可以选择多个通道
3 ADC基本结构
4 输入通道
5 ADC转换模式
1 单次转换,非扫描模式(并未用到菜单列表)
2 连续转换,非扫描模式(转换完成后不停止,立刻下一次转换)
3 单次转换,扫描模式(用到菜单列表)
4 连续转换,扫描模式
6 触发控制
7 数据对齐
由于我们ADC是12位的,转换结果就是12位的数据,但是数据寄存器是16位,所以存在对齐问题
- 右对齐:高位多出来的就补0(一般选择它,读出来的数据就是转换结果)
- 左对齐:低位多出来的就补0,直接读会比原始数据大16倍,如果不需要那么高的分辨率,可以取左对齐的数据寄存器高8位,这样舍弃了4位的精度
8 转换时间
-
AD转换的步骤:采样,保持,量化,编码(量化编码就是比较的过程)
-
STM32 ADC的总转换时间为:
TCONV = 采样时间 + 12.5个ADC周期(量化编码花费的时间) -
例如:当ADCCLK=14MHz,采样时间为1.5个ADC周期
TCONV = 1.5 + 12.5 = 14个ADC周期 = 1μs
9 校准
-
ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换中每个电容器上产生的误差
-
建议在每次上电后执行一次校准
-
启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期
+++
10 硬件电路
8 DMA直接存储器存取
1 DMA简介
- DMA(Direct Memory Access)直接存储器存取
- DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省了CPU的资源
- 12个独立可配置的通道: DMA1(7个通道), DMA2(5个通道)
- 每个通道都支持软件触发和特定的硬件触发(也就是说不同硬件能触发的通道不同)
- STM32F103C8T6 DMA资源:DMA1(7个通道)
2 存储器映像
3 DMA框图
4 DMA基本结构
DMA触发有三个条件:
- 传输计数器大于0
- 触发源有触发信号
- DMA使能
5 DMA请求
6 数据宽度与对齐
由于DMA传输数据常遇到宽度不一致的问题,就应该有一种对齐方案,此处如果源数据宽度长,那么直接舍去源数据宽度的高位。如果源数据宽度短,那么直接将源数据前面补0。
7 数据转运+DMA
8 ADC扫描模式+DMA
9 USART串口协议
1 通信接口
- 通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统
- 通信协议:制定通信的规则,通信双方按照协议规则进行数据收发
- 全双工一般需要有两根数据线
- 有单独时钟线的会同步
- 单端信号是指引脚的高低电平是对GND的电压差,单端信号需要共地,差分信号是指差分线的电压差,不需要共地,有较强抗干扰能力
2 串口通信
- 串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信
- 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大地扩展了单片机的应用范围,增强了单片机系统的硬件实力
3 硬件电路
- 简单双向串口通信有两根通信线(发送端TX和接收端RX)
- TX与RX要交叉连接
- 当只需单向的数据传输时,可以只接一根通信线
- 当电平标准不一致时,需要加电平转换芯片
4 电平标准
电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:
- TTL电平:+3.3V或+5V表示1,0V表示0
- RS232电平:-3-15V表示1,+3+15V表示0
- RS485电平:两线压差+2+6V表示1,-2-6V表示0(差分信号)
5 串口参数及时序
串口发送一个字节会存在一个数据帧内,在串口空闲(不发送数据)情况下,默认为高电平,所以帧需要一个起始位为低电平,产生下降沿告诉串口“我要发送数据”,发送完成之后,需要一个停止位恢复为高电平,方便产生下一次的下降沿
- 波特率:串口通信的速率(在二进制调制情况下, 波特率等于比特率)
- 起始位:标志一个数据帧的开始,固定为低电平
- 数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行(就是完全倒过来,比如发0x55,对应的二进制是0101 0101,也就是要发1010 1010)
- 校验位:用于数据验证,根据数据位计算得来
- 停止位:用于数据帧间隔,固定为高电平
6 USART简介
-
USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器
-
USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
-
自带波特率发生器,最高达4.5Mbits/s
-
可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)
-
可选校验位(无校验/奇校验/偶校验)
-
支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN
-
STM32F103C8T6 USART资源: USART1、 USART2、 USART3
- USART1是APB2总线上的设备,其他是APB1总线上的设备
7 USART框图
这里的TDR和RDR其实在物理上就是一个寄存器
- 对于发送端,数据通过CPU或者DMA写入发送数据寄存器,如果发送移位寄存器中没有数据,就直接将发送数据寄存器的数据移动到发送移位寄存器,然后置标志位,表示数据又可以送到发送数据寄存器中了。发送移位寄存器进行向右移位(这也是低位先行的原因)移出去,一旦全部移完,发送数据寄存器的数据又可以挪到发送移位寄存器中去了。
- 对于接收端也类似,数据通过RX引脚在接收器控制下通向接收移位寄存器,先放置在高位,然后像右移,同样也是低位先行, 到8位之后检查标志位,如果判断到接收数据寄存器非空,就会将接收移位寄存器中整体移动到接收数据寄存器中
- 硬件数据流控,如果发送太快,接收来不及处理,这样会产生错误,所以来一个流控进行控制(一般不用)
- 唤醒单元可以实现多设备的功能,给设备分配地址,然后通过看地址是否一致可以唤醒设备(一般不用)
- 状态寄存器中,有TXE(发送数据寄存器空)和RXNE(接收数据寄存器非空)两个标志位比较重要
8 USART基本结构
9 数据帧
10 起始位侦测
进行一个16倍采样,检测3 5 7次要至少出现两个0,8 9 10次也要至少出现两个0,为了抗噪声。之后检测数据位时,都在8 9 10次进行采样,保证在数据中间
11 数据采样
都检测8 9 10 位,如果没有噪声就会全部为1或者0,如果有噪声 按2:1来判断是1还是0
12 波特率发生器
-
发送器和接收器的波特率由波特率寄存器BRR里的DIV(分频系数)确定
-
计算公式:
波特率 = f P C L K 2 / 1 / ( 16 ∗ D I V ) 波特率 = f_{PCLK2/1} / (16 * DIV) 波特率=fPCLK2/1/(16∗DIV)
13 数据包
1 HEX数据包
2 文本数据包
3 HEX数据包接收
4 文本数据包接收
14 FlyMcu串口下载和STLINK Utility
1 FlyMcu类似于51单片机的STC-ISP
这里必须得使用USART1串口,因为该软件只适配了该串口
-
编写好的程序进行编译生成HEX文件,在FlyMcu中打开该文件
-
在开始编程(烧录)之前,需要配置BOOT引脚,让STM32执行BOOTLoader程序
-
在STM32上将BOOT0的跳线帽切换到1,如下图所示,然后再按下复位键。必须按下复位键,因为STM32只有在刚复位时才会读取BOOT引脚
-
程序已经成功下载到STM32的闪存中之后,还是无法出现想要的结果,需要将BOOT0引脚换回来,再按下复位,这时候就成功了
STM32通过串口进行程序的自我更新就是靠BootLoader,BootLoader程序存储在ROM区的最后,在更新过程中,BootLoader接受USART1数据,刷新到程序存储器,这时候主程序是处于瘫痪状态,更新好之后,在启动主程序,执行新程序,这就是串口下载的流程。
每次下载都要切换跳线帽,有些麻烦,可以接两根线,当要进行下载时自动设置BOOT0的高低电平,实际上是可行的,在CH340芯片上,由于不使用流控,会存在一些多余的接口可以当做普通IO口来使用,可以用他们控制。