????????定时器STM32非常重要的外设,也是比较复杂的外设,下面以STM32F407ZGT6为例记录学习内容:(1)基本定时功能,(2)PWM输出功能,(3)PWM互补死区、多通道移相输出、刹车,(4)输入捕获之计算方波时长,(5)输入捕获之编码器。分别使用通用定时器和高级定时器进行外设配置,使用库函数和寄存器的配置方式。
????????STM32F407ZG共有14个定时器。2个高级定时器(TIM1和TIM8),10个通用定时器(TIM2、TIM3、TIM4、TIM5、TIM9、TIM10、TIM11、TIM12、TIM13、TIM14),2个基本定时器(TIM6、TIM7);
? ? ? ? 如上图所示,STM32F407ZGT6的定时器分为三种:高级定时器(TIM1和TIM8)、通用定时器(TIME2~TIME5,TIM9~TIM14 )、基本定时器(TIM6和TIM7)。这几种定时器在功能上是有区分的,总体的性能排序:高级定时器>>通用定时器>>基本定时器。
APB2总线:TIM1、TIM8~TIM11
APB1总线:TIM2~TIM7、TIM12~TIM14
????????STM32F407ZGT6的系统时钟频率配置为168MHz的时候,基本的时钟树如下图所示,从下图中可以观察出APB1和APB2总线上的时钟是不一样的。
APB2总线时钟:168MHz
APB1总线时钟:84MHz
? ? ? ? 对于定时器来讲,挂载的时钟总线的时钟频率是非常重要的。进行定时器配置的时候,定时的时间是需要根据总线时钟进行配置的。
STM32内部重要总线地址:
????????APB1:0x40000000(Peripheral memory map)
????????APB2:0x40010000(Peripheral memory map)
? ? ????AHB1:0x40020000(Peripheral memory map)
????????AHB2:0x50000000(Peripheral memory map)
? ? ? ? 定时器的基本定时功能是比较简单的。所有类的TIMx定时器都可以实现。下面以通用定时器3为例进行讲解。
? ? ? ? 下图所示的是通用定时器的内部连接图,本章通用定时的基本定时功能基本没有使用到下面的内部连接图,后面其他的配置需要使用到,所以下图是非常重要的。
? ? ? ? 基本定时器的寄存器如下图所示,不同的模式配置使用到的寄存器不一样,本次通用定时器的基本定时功能只需要使用到:(1)控制寄存器 1 [TIMx_CR1],(2)TIMx 预分频器 [TIMx_PSC],(3)自动重载寄存器 [TIMx_ARR],(4)DMA/中断使能寄存器 [TIMx_DIER]
? ? ? ? ??
? ? ? ? 控制寄存器TIMx_CR1的相关配置主要是定时器的基本配置。
? ? ? ? 本寄存器主要是是对定时器的计数频率进行分频之后,在将其放进定时器的计数器的寄存器CNT中。
? ? ? ? 定时器的计数值配置,计数值超过这个值之后就会从新装载寄存器从新开始计数。
? ? ? ??
? ? ? ? 此寄存器的配置,主要是中断和DMA的配置。
? ? ? ? (1)使能TIM3时钟。
? ? ? ? (2)设置计数值。
? ? ? ? (3)设置预分频值。
? ? ? ? (4)使能更新中断。
? ? ? ? (5)定时器的CR1寄存器配置(可以直接使用默认值)。
? ? ? ? (6)定时器使能。
? ? ? ? (7)中断的优先级配置、内核中断使能、中断分组配置等。
下面是配置代码,高级定时器、通用定时器、基本定时器的配置都是一样的。
????????但是STM32内部的基本定时器只能完成基本定时的功能,以及某些事件的触发,所以只使用定时器功能时候,最好使用基本定时器(TIM6、TIM7).
//定时器3中断服务程序
void TIM3_IRQHandler(void)
{
if(TIM3->SR&0X0001) //溢出中断
{
LED1=!LED1;
}
TIM3->SR&=~(1<<0); //清除中断标志位
}
//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为42M
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us.
//Ft=定时器工作频率,单位:Mhz
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<1; //TIM3时钟使能
TIM3->ARR=arr; //设定计数器自动重装值
TIM3->PSC=psc; //预分频器
TIM3->CR1 |= 1<<7; //ARPE使能,自动重装载使能(可以不设置也会自动重装载,应该是ARR设置了就使能了)
TIM3->DIER|=1<<0; //允许更新中断
TIM3->CR1|=0x01; //使能定时器3
MY_NVIC_Init(1,3,TIM3_IRQn,2); //抢占1,子优先级3,组2
}
下图是基础定时器的内部连接图:
下面是基础定时器的寄存器:
? ? ? ? 基础定时使用代码的配置与上面介绍的定时器3的配置是一样的。
? ? ? ? 根据上面STM32Cubemx的配置图可知APB1总线的时钟频率为84MHz,TIM2~TIM7、TIM12~TIM14等非高级定时器挂载在APB1总线上。
? ? ? ? 如上图所示的,定时器的定时和计数的配置,主要有预分频器的分频值、预装载计数器的装载值。
? ? ? ? (1)预分频器的分频值PSC:84MHz / PSC = A1(Hz)
? ? ? ? (2)预装载计数器的装载值ARR:ARR * (1 / A1) = tim(s)
????????上面的A1就是“CNT计数器”的计数的时钟频率,也即是A1频率的脉冲跳动一次,就计数一次,此时计数一次的时间就是频率的倒数(1/A1)单位秒s,预装载计数器的装载值ARR就是记录的次数,乘以前面计数一次的时间,就是tim计时总时间,单位秒s。
???????? 根据上面STM32Cubemx的配置图可知APB2总线的时钟频率为168MHz,TIM1、TIM8~TIM11等定时器挂载在APB2总线上。
? ? ? ? 定时的时间和上面分析的一样,就是将“84MHz”换成“168MHz”就可以了。
????????(1)预分频器的分频值PSC:168MHz / PSC = A1(Hz)
? ? ? ? (2)预装载计数器的装载值ARR:ARR * (1 / A1) = tim(s)
? ? ? ? STM32的PWM输出是外部调节的一个重要方式,STM32F407ZGT6的高级定时器和通用定时器是可以产生PWM输出,基础定时是不可以产生PWM输出的,下面最基础的PWM输出采用通用定时器实现介绍。
? ? ? ? 通用寄存器的基础知识在第二章中已经介绍过一些,这里不重复。下面只介绍与PWM相关的知识。
? ? ? ? 下图是STM32内部连接图,比较重要,从图中可以看出通用定时器TIM2到TIM5的外部输出的PWM通道有四个,可以同时产生4路PWM脉冲。下面将根据下图展开叙述定时器的PWM输出。
? ? ? ?TIM2到TIM5的PWM输出的配置也是需要定时的定时的基础配置,然后是PWM模式和通道的配置。定时器的计数模式的配置前面已经描述。
? ? ? ? 注意:这里计数器的内部自动计数模式还是外部触发的计数模式的配置的选择。如上图所示,如果对“捕获/比较x寄存器”进行配置了之后,定时器的模式就会有下面三种。
【1】捕获/比较x寄存器未配置
? ? ? ? (1)定时器内部自动计数。
【2】捕获/比较x寄存器配置(需要各自配置)
? ? ? ? (1)定时器的计数由外部脉冲触发计数,对外部脉冲计数。
? ? ? ? (2)定时器内部自己进行计数,然后外部触发产生中断进行标记。
? ?????????TIM2到TIM5的PWM输出需要配置的寄存器有:(1)捕获/比较模式寄存器 1 (TIMx_CCMR1),(2)捕获/比较使能寄存器 (TIMx_CCER),(3)捕获/比较寄存器 1 (TIMx_CCR1)。
? ? ? ? 配置与前面相同,最简单的配置就是只配置预分频值与计数值就可以,其他的都使用默认配置。
? ? ? ? 定时器的“CCMR1”寄存器是配置PWM模型输出通道的,如下图所示的,将对应的GPIO复用到这个CHx接口上之后,就可以对这个通道OCx进行配置。
该寄存器配置的主要有以下部分:
(1)配置通道OCx为输出模式,也就是PWM比较模式,PWM 模式 1和PWM 模式?2(B1)
(2)使能通道OCx(A1)
(3)配置通道OCx预装载使能(A1)
? ? ? ? 上面是“CCER”寄存器的“捕获/比较寄存器”的配置,三个为一组“CC1E”、“CC1P”、“CC1NP”,在PWM输出配置的时候只需要用到“CC1E”、“CC1P”两个位就可以了。
(1)“CC1E”:使能CCxL输出到OCx
(2)“CC1P”:设置输出的有效电平
? ? ? ? 定时器的“CCER”寄存器是对“捕获/比较x寄存器”的配置,也就是上图中的“CCxL”输出到“OCx”的配置。
? ? ? ? “CCR1”是PWM波占空比设置的寄存器,只需要改变定时器中的“CCR1”的值就可以改变PWM波的占空比,下面会详细介绍。
? ? ? ? 影响PWM波形的输出的主要有下面的三个因素:
(1)定时器的预分频值和重装载值。
? ? ? ? 定时器的预分频值与重装载值是定时器产生的波形。
(2)定时的计数模式,上升、下降、双边沿。
? ? ? ? 这里设置的也是定时器产生的波形。
(3)捕获比较寄存器CCR1的值的设置。
? ? ? ? 占空比 = CCR1 / arr
(4)CHx通道的PWM模式
? ? ? ? PWM模式1:在递增计数模式下,只要 TIMx_CNT<TIMx_CCR1,通道 1 便为有
? ? ? ? PWM模式2:在递增计数模式下,只要 TIMx_CNT<TIMx_CCR1,通道 1 便为无
? ? ? ? 这里通过CCR1的值与定时器的CNT(定时器的计数值)值进行比较之后,比CNT值小的时候输出有效值,比CNT值大的时候输出无效值。
? ? ? ? 下面是针对上面三种配置的不同波形展示:
(1)定时器为上升沿,重装载值为arr,输出比较值为CCR1,高电平有效。
(2)定时器为下降沿,重装载值为arr,输出比较值为CCR1,高电平有效。
(3)定时器为双边沿,重装载值为arr,输出比较值为CCR1,高电平有效。
? ? ? ? (1)使能定时器时钟
? ? ? ? (2)使能对应GPIO时钟
? ? ? ? (3)配置GPIO为复用推挽输出,上拉输出
? ? ? ? (4)配置GPIO的复用模式寄存器
? ? ? ? (5)设置定时器的自动重装载值
? ? ? ? (6)设置定时器预分频器不分频
? ? ? ? (7)定时器其他配置可以直接使用默认值CR1寄存器的配置
? ? ? ? (8)设置CHx通道的PWM模式
? ? ? ? (9)设置CHx通道的预装载使能,CCR1寄存器的值预装载
? ? ? ? (10)输出比较寄存器OCx的输出使能
? ? ? ? (11)定时器的ARPE,自动重装载值使能
? ? ? ? (12)使能定时器。
void TIM2_PWM_Init(u32 arr,u32 psc)
{
//此部分需手动修改IO口设置
RCC->APB1ENR|=1<<0; //TIM2时钟使能
RCC->AHB1ENR|=1<<0; //使能PORTA时钟
GPIO_Set(GPIOA,PIN0,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//复用功能,上拉输出
GPIO_AF_Set(GPIOA,0,1); //PF9,AF9
TIM2->ARR=arr; //设定计数器自动重装值
TIM2->PSC=psc; //预分频器不分频
TIM2->CCMR1&=~(uint16_t)(3<<0); //CH1 PWM1模式
TIM2->CCMR1 |= 1<<3; //CH1 预装载使能
TIM2->CCMR1 |= 7<<4; //PWM2模式
TIM2->CCER |= 1<<0; //OC1 输出使能
TIM2->CCER |= 1<<1; //OC1 低电平有效
TIM2->CCR1 |= 100; //比较寄存器值
TIM2->CR1 |= 1<<7; //ARPE使能
TIM2->CR1 |= 1<<0; //使能定时器14
}
? ? ? ? 下面是GPIOA0口输出的PWM波形。
? ? ? ? 通用定时器TIM9到TIM14定时器与通用定时器TIM2到TIM5的配置几乎相同,不同的就是通道的数量不同,TIM9到TIM14定时器的输入和输出通道只有两个,所以在配置“通道”和“捕捉/比较x寄存器”的时候就需要注意
? ? ? ? 下面是TIM14的配置代码,与上面的TIM2配置完全一样。
//TIM14 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM14_PWM_Init(u32 arr,u32 psc)
{
//此部分需手动修改IO口设置
RCC->APB1ENR|=1<<8; //TIM14时钟使能
RCC->AHB1ENR|=1<<5; //使能PORTF时钟
GPIO_Set(GPIOF,PIN9,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//复用功能,上拉输出
GPIO_AF_Set(GPIOF,9,9); //PF9,AF9
TIM14->ARR=arr; //设定计数器自动重装值
TIM14->PSC=psc; //预分频器不分频
TIM14->CCMR1|=6<<4; //CH1 PWM1模式
TIM14->CCMR1|=1<<3; //CH1 预装载使能
TIM14->CCER|=1<<0; //OC1 输出使能
TIM14->CCER|=1<<1; //OC1 低电平有效
TIM14->CCR1 = 100; //比较寄存器值
TIM14->CR1|=1<<7; //ARPE使能
TIM14->CR1|=1<<0; //使能定时器14
}
? ? ? ? 多通道的移相输出是高级定时器和通用定时器都可以实现的;PWM的死区互补输出只有高级定时器可以实现。下面以高级定时器1对移相输出、死区互补输出的配置进行讲解。
? ? ? ? 注意:这里的重复计数器寄存器是为了弥补自动重载寄存器的值不够大的问题。当定时计数器计数值达到自动重载寄存器值得时候,会产生溢出,这时候重复计数器寄存器中得值减一,直到技术到重复计数器寄存器中的值减为零的时候,计数器计数才算结束。
????????