[STM32 HAL库]学习笔记,七、定时器
目录STM32F1系列的三种定时器1.定时器时基单元模块1时钟来源2降频-预分频器3计数器4自动重装寄存器ARR5重复计数RCR只有高级定时器有*寄存器预加载2.简单实验自制延时函数让LED闪烁1整体代码逻辑2配置参数生成工程3代码部分4编译并下载3.输出比较模块*PWM Pulse Width Modulation 脉冲宽度调制1通过输出比较生成PWM波2输出比较模式4.简单实验用PWM波实现呼吸灯两颗LED交替呼吸1配置TIM参数2电路接线图3HAL库函数介绍以及呼吸灯原理4代码部分5编译并下载5.输入捕获模块6.简单介绍如何配置TIM通道和HAL库函数1配置TIM通道2HAL库函数7.从模式控制器模块从机模式主机模式8.简单实验测量PWM波占空比并打印在串口上基本原理1电路接线图2测试串口打印效果3生成20%占空比的PWM波4配置从模式控制器5代码部分6编译并下载定时器可以对输入的时钟进行计数并在计数值达到设定值时触发中断。简单来说就是每隔一段固定时间执行一次特定任务。下面是定时器工作的整体模块。STM32F1系列的三种定时器根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型。 其中高级定时器功能最多通用定时器为其阉割版而基本定时器功能则更少。而STM32F103C8T6则只有TIM1,TIM2,TIM3,TIM4四个定时器也就是说没有基本定时器。1.定时器时基单元模块1时钟来源时钟来源有三种 其中最主要的还是来自RCC时钟树频率最低为8MHz对于定时器来说这个频率还是太高了2降频-预分频器预分频器可以降低输入时钟的频率分频系数范围0~65535。若分频系数为65535时钟频率8MHz则输出8000000/65536122Hz。3计数器经过预分频系数后进入时钟计数器计数计数方式有三种上计数下计数中心对齐4自动重装寄存器ARR可以设置定时周期范围为0~65535即当计数器清零时重装一个数。5重复计数RCR只有高级定时器有计数器每溢出一次重复计数器则计数一次。重复计数器取值范围为0~65535当重复计数器计数到指定数值时就会触发一次中断。*寄存器预加载寄存器预加载其实就是一种缓冲机制是为了防止定时器跑飞的一种方式写入的值首先会进入到影子寄存器在某个事件发生的时候影子寄存器里的值才会进入到活动寄存器这时写入的值才会生效自动重装寄存器ARR设置定时周期每当计数器计到该数值时发生update事件然后从零开始重新计数。而如果我们想在定时器运行途中突然改变ARR时改变的值可能比当前的计数值小为了达到ARR的值计数器需要计数到65535然后重新从零开始才能达到ARR的值这一段过程就叫程序跑飞了预记载机制则把修改后的ARR的值先存在影子寄存器里程序还是按照原来的值即活动寄存器里的值进行计数当下一次产生update中断时影子寄存器里的值才会加载到活动寄存器里生效此时就不会让程序跑飞。ARR的预加载机制需手动打开2.简单实验自制延时函数让LED闪烁1整体代码逻辑首先用MyGetTick函数返回一个当前时间的值而这个时间变量写在定时器里面每隔一段时间自增。delay逻辑写入一个要延迟的时间延迟结束的时间等于当前时间加要延迟的时间然后在while里不断等待当前时间自增直到超过延迟结束的时间则完成延时。然后再在main函数里启动定时器在回调函数里让时间变量自增最后在while循环里调用延时函数MyDelay完成LED闪烁。2配置参数生成工程选择左侧栏目里Timers的TIM1TIM1挂在APB2上需先配置他的工作模式。首先前两个是定时器的从模式才会用到本次实验用的是RCC内部时钟所以用不到下面有四个通道跟输入捕获和输出比较有关这里也用不到最下面模式本次实验也用不到这里只需要选择时钟来源选择内部时钟即RCC然后配置定时器的参数定时器需要每一毫秒产生一次更新事件。内部时钟RCC没设置过默认为8MHz的频率因此将PSC分频系数配置为7将ARR配置为999此时输出的频率为8000000 /71/99911000Hz即1ms更新一次。计数模式改为Up上计数重复计数器的值改为0然后使能auto-reload preload自动重装预加载即为了安全起见防止程序跑飞。这里的Internal Clock Division用不到。最后在NVIC Settins中使能TIM1更新中断此时定时器已配置好了然后就可以在中断响应函数里面写时间变量自增的代码变量就会每隔一毫秒自增。这个工程还是使用板载LED实现闪烁则同样配置好参数。3代码部分在指定区域里写入代码变量写在变量区variables里函数声明写在函数声明区function prototypes里。最后在main函数里开启中断并写入闪烁代码。4编译并下载按下复位键后可以看到LED成功闪烁且改变MyDelay中的参数可以明显看到闪烁频率改变写入1000时LED灯每秒闪烁一次。3.输出比较模块通过定时器产生精确定时的信号。可以用输出比较产生PWM波*PWM Pulse Width Modulation 脉冲宽度调制占空比 高电平时间 / 总时间1通过输出比较生成PWM波这里用到CCR寄存器在CCR寄存器里写入一个值这个值会和时基单元里的计数器比较自动重装寄存器控制的是PWM的周期而CCR则控制PWM波的占空比。这里想要输出一个占空比为50%的PWM波则CCR寄存器给4ARR寄存器给9计数器计数比CCR小输出高电平计数器计数比ARR大输出低电平。产生占空比50%的PWM波而增加CCR的值PWM波的占空比则会增加2输出比较模式一共有八种模式一般选PWM14.简单实验用PWM波实现呼吸灯两颗LED交替呼吸1配置TIM参数首先和上一个实验一样配置TIM1的参数实现每一毫秒生成一次更新事件然后在通道一中选择一种输出比较模式。互补输出的波形恰好和正常输出的波形相反但两者的占空比相同。这里选PWM正常输出加互补输出可以进行两路输出使两颗LED交替呼吸可以看到右边的芯片图里已经配置好了两个输出引脚PA8和PA7PA8代表正常输出PA7则代表互补输出。同时参数栏里面也多了几条参数首先TRGO是从模式控制器的输出不需要配置下面两个是刹车和死区时间也不需要配置。下面配置CH1的PWM参数1.选择模式PWM mode 12.设置CCR初始值03.设置CCR预加载enable4.CH/CHN Polarity设置正常输出和互补输出的极性High正极性配置完成后生成工程2电路接线图两颗LED正极分别接该引脚负极接地使用的是推挽接法。3HAL库函数介绍以及呼吸灯原理这里用到两个函数分别打开PWM的正常输出和互补输出第一个参数写定时器的句柄第二个参数写通道编号以下的参数可以读取或改写寄存器的值从而改变PWM波的占空比想实现呼吸灯的效果只需要让亮度随正弦关系变化然后用占空比来替代亮度占空比越大LED越亮占空比计算duty CCR / ARR 1根据占空比计算CCR的值整体代码逻辑获取当前时间计算占空比然后读出ARR寄存器的值根据公式计算CCR的值最后再写入CCR寄存器。4代码部分在main函数中写入代码同时还要包含“math.h”。5编译并下载可以看到两颗LED交替点亮5.输入捕获模块捕捉输入信号变化的时间并保存起来。可以用于捕获测量脉冲宽度下面是测量脉冲宽度的大概原理图。将脉冲上升沿的时间保存到通道1的CCR1中将脉冲下降沿的时间保存到通道2的CCR2中。两者相减并乘以时间间隔就是脉冲宽度。通道1捕获信号的边沿并将值存储到CCR中的流程图。先进行滤波把输入信号的毛刺部分滤掉输出干净的方波然后在边沿检测中检测到上升沿产生高电平在信号选择阶段中如果选择上升沿脉冲直接输出则上升沿脉冲直接输出到分频然后记录下当前CCR的值。这里通道2悬空但其信号选择部分选择下降沿脉冲间接输出则会将通道1检测到的下降沿脉冲输出到通道2的分频部分然后将计数值存到CCR2中此时就可以CCR2-CCR1再乘以分辨率就可以算出脉冲宽度。6.简单介绍如何配置TIM通道和HAL库函数1配置TIM通道输入捕获有三种模式这里将通道1设置为直接通道2设置为间接下面配置通道的参数通道1的极性选择上升沿通道2选择下降沿两个通道都选不分频配置计数器参数时需注意定时器的定时周期应该大于最大脉宽不然在脉冲期间定时器归零重新计数就会出现错误。2HAL库函数清除CCR开启或停止通道输入捕获查询某一标志位关闭定时器7.从模式控制器模块从模式控制器简化图总共有三个箭头一个输入一个输出还有一个控制当前的定时器。其中TRGI的来源有多种下面的TF1FP1代表从通道一输入然后经过滤波再选择上升沿脉冲极性选择最后直接输出的信号。TF2FP2也类似。从模式控制器有两种模式一种作为从机一种作为主机主机模式和从机模式可以同时使用当作为从机时从模式控制器接收控制信号控制定时器当作为主机时从模式控制器输出控制信号控制其他模块作为从机和作为主机时又分别有多种模式较常用的是框中的几种从机模式1.从模式禁止不使用从机功能2.复位模式使用TRGI的上升沿来复位CNT同时产生Update事件3.门模式使用TRGI控制时基单元的开关4.触发模式使用TRGI的上升沿来启动定时器5.外部时钟模式1把TRGI作为定时器时钟主机模式1.enable-使能通过TRGO把时基单元的开关状态输出出去2.update-更新每产生一个更新事件就向TRGO输出一个脉冲8.简单实验测量PWM波占空比并打印在串口上基本原理输入一个PWM波TF1FP1会检测PWM波的上升沿并产生一个跳变。而TF1FP1作为从模式控制器的TRGI从模式控制器设置为复位模式每当TF1FP1变化时计数器会复位复位时计数器的数据存到CCR1中则读取CCR1中的数据即可知道PWM波的周期。而当PWM波产生下降沿时CCR2会存储当前计数器的数则读取CCR2中的数据即可知道PWM波的高电平时间。最终可算出PWM波的展开波。1电路接线图2测试串口打印效果设置USART模式为异步模式其他从参数不变在main函数中写入代码在串口上打印“你好世界”四个字编译下载打开串口配置好参数复位后串口成功接收到你好世界四个字3生成20%占空比的PWM波选择用TIM3生成PWM波PSC设7ARR设999CCR设为200。此时输出的就是周期为1ms占空比为20%的PWM波。然后更新代码在main函数中写入以下代码在PA6引脚连一个LED灯编译下载后按下复位键LED灯亮起微弱的光说明已产生PWM波4配置从模式控制器根据此图配置首先配置通道一通道二通道一直接模式通道二间接模式。PSC设为7ARR设为65535然后将通道一的极性改为上升沿通道二的极性改为下降沿。然后配置从模式选择复位模式触发源为TF1FP1更新代码5代码部分代码逻辑根据以上逻辑写入代码补充串口打印函数6编译并下载串口助手里打印出PWM准确数据