高级控制定时器(TIM1 和TIM8)
TIM1和TIM8定时器的功能包括:
● 16位向上、向下、向上/ 下自动装载计数器
● 16位可编程( 可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535 之间的任意数值
● 多达4个独立通道:
─ 输入捕获
─ 输出比较
─ PWM生成(边缘或中间对齐模式)
─ 单脉冲模式输出
● 死区时间可编程的互补输出
●使用外部信号控制定时器和定时器互联的同步电路
● 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器
● 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态
● 如下事件发生时产生中断/DMA :
─ 更新:计数器向上溢出/ 向下溢出,计数器初始化(通过软件或者内部/ 外部触发)
─ 触发事件(计数器启动、停止、初始化或者由内部/ 外部触发计数)
─ 输入捕获
─ 输出比较
─ 刹车信号输入
● 支持针对定位的增量(正交)编码器和霍尔传感器电路
● 触发输入作为外部时钟或者按周期的电流管理
通用定时器(TIMx)
通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:
● 16位向上、向下、向上/ 向下自动装载计数器
● 16位可编程( 可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536 之间的任意数值
● 4个独立通道:
─ 输入捕获
─ 输出比较
─ PWM生成(边缘或中间对齐模式)
─ 单脉冲模式输出
● 使用外部信号控制定时器和定时器互连的同步电路
● 如下事件发生时产生中断/DMA :
─ 更新:计数器向上溢出/ 向下溢出,计数器初始化(通过软件或者内部/ 外部触发)
─ 触发事件(计数器启动、停止、初始化或者由内部/ 外部触发计数)
─ 输入捕获
─ 输出比较
● 支持针对定位的增量(正交)编码器和霍尔传感器电路
● 触发输入作为外部时钟或者按周期的电流管理
基本定时器(TIM6 和TIM7)
TIM6和TIM7定时器的主要功能包括:
● 16位自动重装载累加计数器
● 16位可编程( 可实时修改)预分频器,用于对输入的时钟按系数为1~65536 之间的任意数值
分频
● 触发DAC的同步电路
● 在更新事件(计数器溢出)时产生中断/DMA 请求
STM32的通用定时器是一个通过可编程预分频器(PSC)驱动的16 位自动装载计数器(CNT)构成。STM32的通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)等。 使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。STM32的每个通用定时器都是完全独立的,没有互相共享的任何资源。
注意单元模块时钟总线
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。STM32的定时器除了TIM6和7。其他的定时器都可以用来产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出,这样,STM32最多可以同时产生30路PWM输出!
要使STM32的通用定时器TIMx产生PWM输出,除了定时器介绍的寄存器外,我们还会用到3 个寄存器,来控制PWM 的。这三个寄存器分别是:捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。
TIM3_CH2默认是接在PA7面的,而我们的DS0接在PB5上面,如果普通MCU,可能就只能用飞线把PA7飞到PB5上来实现了,不过,我们用的是STM32,它比较高级,可以通过重映射功能,把TIM3_CH2映射到PB5上。 STM32的重映射控制是由复用重映射和调试IO 配置寄存器(AFIO_MAPR)控制的。
1)开启TIM3时钟以及复用功能时钟,配置PB5为复用输出。
要使用TIM3,我们必须先开启TIM3的时钟,还要配置PB5为复用输出,这是因为TIM3_CH2通道将重映射到PB5上,此时,PB5属于复用功能输出。
库函数使能TIM3时钟的方法是:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
库函数设置AFIO时钟的方法是:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //复用时钟使能
设置PB5为复用功能输出的方法:GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
2)设置TIM3_CH2重映射到PB5上。
因为TIM3_CH2默认是接在PA7上的,所以我们需要设置TIM3_REMAP为部分重映射(通过AFIO_MAPR配置),让TIM3_CH2重映射到PB5上面。在库函数函数里面设置重映射的函数是:
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
STM32重映射只能重映射到特定的端口。第一个入口参数可以理解为设置重映射的类型,比如TIM3部分重映射入口参数为 GPIO_PartialRemap_TIM3,这点可以顾名思义了。所以TIM3部分重映射的库函数实现方法是: GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
3)初始化TIM3,设置TIM3的ARR和PSC。
在开启了TIM3的时钟之后,我们要设置ARR和PSC两个寄存器的值来控制输出PWM的周期。当PWM周期太慢(低于50Hz)的时候,我们就会明显感觉到闪烁了。因此,PWM周期在这里不宜设置的太小。这在库函数是通过TIM_TimeBaseInit函数实现的,在上一节定时器中断章节我们已经有讲解,这里就不详细讲解,调用的格式为:
TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的
4)设置TIM3_CH2的PWM模式,使能TIM3的CH2输出。
接下来,我们要设置TIM3_CH2为PWM模式(默认是冻结的),因为我们的DS0是低电平亮,而我们希望当CCR2的值小的时候,DS0就暗,CCR2值大的时候,DS0就亮,所以我们要通过配置TIM3_CCMR1的相关位来控制TIM3_CH2的模式。在库函数中,PWM通道设置是通过函数TIM_OC1Init()~TIM_OC4Init()来设置的,不同的通道的设置函数不一样,这里我们使用的是通道2,所以使用的函数是TIM_OC2Init()。
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
5)使能TIM3。
在完成以上设置了之后,我们需要使能TIM3。使能TIM3的方法前面已经讲解过: TIM_Cmd(TIM3, ENABLE); //使能TIM3
6)修改TIM3_CCR2来控制占空比。
最后,在经过以上设置之后,PWM其实已经开始输出了,只是其占空比和频率都是固定的,而我们通过修改TIM3_CCR2则可以控制CH2的输出占空比。继而控制DS0的亮度。 在库函数中,修改TIM3_CCR2占空比的函数是:
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2); 理所当然,对于其他通道,分别有一个函数名字,函数格式为TIM_SetComparex(x=1,2,3,4)。
通过以上6个步骤,我们就可以控制TIM3的CH2输出PWM波了。