[应用相关] STM32定时器配置、PWM输出比较详解、电机PWM输出配置

[复制链接]
2108|17
 楼主| tpgf 发表于 2021-12-7 14:43 | 显示全部楼层 |阅读模式
STM32定时器配置详解

STM32拥有三种定时器
9562461af028f18bd2.png

基本功能
其通用定时器可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)、定时、计数等。
其通用定时器(TIM2、TIM3、TIM4、TIM5)的功能包括:
1)16 位向上、向下、向上/向下自动装载计数器(TIMx_CNT),F7的TIM2和TIM5有32位。
2) 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535 之间的任意数值。
3) 4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:
A.输入捕获
B.输出比较
C.PWM 生成(边缘或中间对齐模式)
D.单脉冲模式输出
4)可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同步电路。
5)如下事件发生时产生中断/DMA: A.更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
B.触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
C.输入捕获
D.输出比较
E.支持针对定位的增量(正交)编码器和霍尔传感器电路
F.触发输入作为外部时钟或者按周期的电流管理


 楼主| tpgf 发表于 2021-12-7 14:43 | 显示全部楼层
工作过程(如下图所示):
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg


第一部分:定时器的时钟来源
一共有四种时钟来源,第一种是由内部的RCC提供时钟(TIMxCLK),其中应用最多的时钟来源为APB1;第二种时钟来源为TIMx_ETR外部引脚;第三种为内部其它定时器级联而来,使用一个定时器作为另一个定时器的预分频器,如可以配置Timer1为Timer2的预分频器;第四种为外部捕获比较引脚通过输入滤波和边沿检测器而来。
第二部分:定时器的时基单元
时基单元的作用为通过预分频器(PSC)配置定时器的时钟频率,通过计数器寄存器配置定时器的计数模式,设置自动重装载值。
第三部分:输入捕获
将不同的引脚映射到定时器的不同通道,通过边沿检测器检测引脚的电平变化,当电平变化时捕获比较寄存器可以编程存放检测到对应的每一次输入捕获时计数器的值。
第四部分:输出比较
将计数器当前值和输出比较寄存器的值进行比较,控制高低电平的输出。


 楼主| tpgf 发表于 2021-12-7 14:45 | 显示全部楼层

定时器中断时基1




配置定时器时钟来源,一般选择内部时钟源APB1

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg


时钟来源为APBx后,除非APBx的分频系数为1,否则通用定时器的时钟频率等于APBx的2倍。即如果APB1的时钟分频系数为2,对于F1来说APB1分频后时钟频率为36MHz,那么通用定时器时钟CK_PSC的频率为36*2=72MHz,然后通过预分配器进一步分频。



 楼主| tpgf 发表于 2021-12-7 14:45 | 显示全部楼层
计数器模式


watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg





向上计数模式时,工作流程如图:
1297461af03159f5aa.png
CK_INT为没有通过预分频器分频之前的时钟频率,当分频系数为1时,定时器时钟频率CK_CNT=CK_INT,使能定时器后,定时器开始计数,向上计数模式时,计数器向上计数,达到预装载值后,计数器溢出,产生更新事件,更新中断标志,此时如果使能了定时器溢出中断就会进入中断处理程序。


 楼主| tpgf 发表于 2021-12-7 14:47 | 显示全部楼层
寄存器


1:控制寄存器TIMx_CR1
264361af03665f07a.png
自动重装载寄存器(TIMx_ARR)在物理上实际对应着 2 个寄存器。一个是程序员可以直接操作的,另外一个是程序员看不到的,这个看不到的寄存器在《STM32参考手册》里面被叫做影子寄存器。事实上真正起作用的是影子寄存器。根据 TIMx_CR1 寄存器中 APRE 位的设置:APRE=0 时,预装载寄存器的内容可以随时传送到影子寄存器,此时 2者是连通的;而 APRE=1 时,在每一次更新事件(UEV)时,才把预装在寄存器的内容传送到影子寄存器。

2485861af036ae7290.png
2:当前值寄存器:
5028761af036eb2d20.png
3:中断使能寄存器:
7034061af03742e588.png
4:预分频寄存器:
7382161af0377cf737.png
5:自动重装载值寄存器:
2553361af037cee202.png
6:状态寄存器:
3545161af03839d2d1.png


 楼主| tpgf 发表于 2021-12-7 14:47 | 显示全部楼层
溢出时间如图所示: watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg


 楼主| tpgf 发表于 2021-12-7 14:48 | 显示全部楼层

相关配置程序

中断服务程序
void TIM3_IRQHandler(void)
{                                                                   
        if(TIM3->SR&0X0001)//判断中断类型为溢出中断,硬件置1,软件置0
        {
                LED1=!LED1;                                                                                                                       
        }                                  
        TIM3->SR&=~(1<<0);//清楚中断标志位
}


void TIM3_Int_Init(u16 arr,u16 psc)
{
        RCC->APB1ENR|=1<<1;        //使能定时器3的APB1时钟,APB1的时钟频率为36MHz,36*2=72MHz为定时器频率
        TIM3->ARR=arr;          //设定计数器重装载值
        TIM3->PSC=psc;          //设定预分频系数
        TIM3->DIER|=1<<0;   //允许更新中断
        TIM3->CR1|=0x01;    /使能定时器3
          MY_NVIC_Init(1,3,TIM3_IRQn,2);//设置中断优先级                                 
}



此时时钟的时钟频率为=72000000/7200=10000Hz,周期为5000*1/10000=0.5s
TIM3_Int_Init(4999,7199);



 楼主| tpgf 发表于 2021-12-7 14:49 | 显示全部楼层

PWM产生过程及配置

3239361af03be35af4.png


将计数器当前值与输出比较寄存器的值进行比较控制高低电平的输出。
PWM的周期由ARR和定时器的时钟频率决定,占空比的大小由CCRx决定。
 楼主| tpgf 发表于 2021-12-7 14:51 | 显示全部楼层
pwm工作过程

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg
4971661af04a6da440.png
pwm的两种模式


watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg
110PWM模式1:当当前值小于比较值时为有效电平。
111PWM模式2:当当前值小于比较值时为无效电平。
有效电平的电平高低由CCER:CC1P决定。
STM32定时器3输出通道引脚: 6665961af04ae9e402.png



 楼主| tpgf 发表于 2021-12-7 14:53 | 显示全部楼层

相关寄存器

1:捕获比较寄存器:
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg
2:捕获比较模式寄存器:
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg
3:捕获/比较使能寄存器:
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3cxMDUwMzIxNzU4,size_16,color_FFFFFF,t_70#pic_center.jpg
 楼主| tpgf 发表于 2021-12-7 14:53 | 显示全部楼层
void TIM3_PWM_Init(u16 arr,u16 psc)
{                                                          
        RCC->APB1ENR|=1<<1;         //使能定时器3时钟APB1
        RCC->APB2ENR|=1<<3;            //使能PORTB时钟
        GPIOB->CRL&=0XFF0FFFFF;        //PB5输出
        GPIOB->CRL|=0X00B00000;        //复用功能输出
          
        RCC->APB2ENR|=1<<0;     //开启辅助时钟
        AFIO->MAPR&=0XFFFFF3FF; //清除MARR的11:10位
        AFIO->MAPR|=1<<11;      //部分重映像,TIM3_CH2->PB5

        TIM3->ARR=arr;                        //自动重装载值
        TIM3->PSC=psc;                        //分频系数
        ///7:111左移12位后将位OC2M位即位14:12置为111,PWM模式2,当前值小于比较值时为无效电平
        TIM3->CCMR1|=7<<12;          //CH2 PWM2模式
        TIM3->CCMR1|=1<<11;         //CH2预装载使能   
        TIM3->CCER|=1<<4;           //OC2输出使能
        TIM3->CR1=0x0080;           //ARPE使能,在每一次更新事件(UEV)时,才把预装在寄存器的内容传送到影子寄存器。
        TIM3->CR1|=0x01;            //使能定时器3                                                                  
}         


//设置比较值
#define LED0_PWM_VAL TIM3->CCR2   



 楼主| tpgf 发表于 2021-12-7 14:53 | 显示全部楼层

电机PWM输出配置

void MiniBalance_Motor_Init(u16 arr,u16 psc)
{               
        RCC->APB2ENR|=1<<13;       //使能定时器8时钟
        RCC->APB2ENR|=1<<4;        //PORTC时钟使能
        //C8复用推挽输出
        GPIOC->CRH&=0XFFFFFFF0;    //PORTC8复用输出
        GPIOC->CRH|=0X0000000B;    //PORTC8复用输出
        //C6\C7复用推挽输出
        GPIOC->CRL&=0X00FFFFFF;    //PORTC6 7复用输出
        GPIOC->CRL|=0XBB000000;    //PORTC6 7复用输出
       
        TIM8->ARR=arr;             //设定计数器自动重装载值
        TIM8->PSC=psc;             //预分频器不分频
        TIM8->CCMR1|=6<<12;        //CH2 PWM1模式
        TIM8->CCMR2|=6<<4;         //CH3 PWM1模式
        TIM8->CCMR1|=6<<4;         //CH1 PWM1模式
       
        TIM8->CCMR1|=1<<11;        //CH2预装载使能
        TIM8->CCMR1|=1<<3;         //CH1预装载使能
        TIM8->CCMR2|=1<<3;         //CH3预装载使能
       
        TIM8->CCER|=1<<8;         //CH3输出使能
        TIM8->CCER|=1<<4;         //CH2输出使能
        TIM8->CCER|=1<<0;          //CH1输出使能
       
        TIM8->BDTR |= 1<<15;       //TIM8必须要有这句话才能输出PWM
        TIM8->CR1=0x8000;          //ARPE使能,主输出使能位
        TIM8->CR1|=0x01;          //使能定时器8
        TIM8->CCR1=7200;  //捕获比较寄存器的值为7200,触树输出为低电平
        TIM8->CCR2=7200;
        TIM8->CCR3=7200;
}




WM波的频率:APB1 36MHz,CK_PSC 72MHz,0不分频,自动重装载值7200
那么PWM的周期为7200/72000000=1/10000,频率为10KHz


MiniBalance_PWM_Init(7199,0);   //=====初始化PWM 10KHz,用于驱动电机


keaibukelian 发表于 2022-1-3 20:12 | 显示全部楼层
介绍的非常的详细
labasi 发表于 2022-1-3 20:15 | 显示全部楼层
这个波主要用于干什么呢
paotangsan 发表于 2022-1-3 20:16 | 显示全部楼层
至少介绍的很清晰
renzheshengui 发表于 2022-1-3 20:19 | 显示全部楼层
最高频率是多少
 楼主| tpgf 发表于 2022-1-3 20:19 | 显示全部楼层
这个问题我也不是很清楚
wakayi 发表于 2022-1-3 20:20 | 显示全部楼层
普通定时器可以吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2384

主题

17638

帖子

21

粉丝
快速回复 在线客服 返回列表 返回顶部