打印
[应用相关]

STM32通用定时器(TIM2-5)PWM输出

[复制链接]
545|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhuomuniao110|  楼主 | 2016-9-21 23:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。
PWM输出模式
STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下:
110:PWM模式1-在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。
111:PWM模式2-在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。
由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。
而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。
PWM输出管脚
PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7 定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如说TIM3的第2个通道,在没有重映像的时候,指定的管脚是PA.7,如果设置部分重映像之后,TIM3_CH2的输出就被映射到PB.5上了,如果设置了完全重映像的话,TIM3_CH2的输出就被映射到PC.7上了。

沙发
zhuomuniao110|  楼主 | 2016-9-21 23:48 | 只看该作者
PWM输出信号
PWM输出的是一个方波信号,信号的频率是由TIMx的时钟频率和TIMx_ARR预分频器所决定的,具体设置方法在前面一个学习笔记中有详细的交代。而输出信号的占空比则是由TIMx_CRRx寄存器确定的。其公式为“占空比=(TIMx_CRRx/TIMx_ARR)*100%”,因此,可以通过向CRR中填入适当的数来输出自己所需的频率和占空比的方波信号。

按以下步骤配置:
1. 设置RCC时钟;
2. 设置GPIO时钟;
3. 设置TIMx定时器的相关寄存器;
4. 设置TIMx定时器的PWM相关寄存器;

    第1步设置RCC时钟已经在前文中给出了详细的代码,在此就不再多说了。需要注意的是通用定时器TIMx是由APB1提供时钟,而GPIO则是由APB2提供时钟。注意,如果需要对PWM的输出进行重映像的话,还需要开启引脚复用时钟AFIO。
   第2步设置GPIO时钟时,GPIO模式应该设置为复用推挽输出GPIO_Mode_AF_PP,如果需要引脚重映像的话,则需要用GPIO_PinRemapConfig()函数进行设置。
   第3步设置TIMx定时器的相关寄存器时,和前一篇学习笔记一样,设置好相关的TIMx的时钟和技术模式等等。
   第4步设置PWM相关寄存器,首先要设置PWM模式(默认情况下PWM是冻结的),然后设置占空比(根据前面所述公式进行计算),再设置输出比较极性:当设置为High时,输出信号不反相,当设置为Low时,输出信号反相之后再输出。最重要是是要使能TIMx的输出状态和使能TIMx的PWM输出使能。相关设置完成之后,就可以通过TIM_Cmd()来打开TIMx定时器,从而得到PWM输出了。

使用特权

评论回复
板凳
zhuomuniao110|  楼主 | 2016-9-21 23:49 | 只看该作者
以下是我写的参考程序:
void GPIO_PA_Init()
{//PA13管脚配置
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_DeInit(GPIOA);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP ;//复用推挽输出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);//使能端口时钟A
GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void TIMER3_Init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_DeInit(TIM3);
TIM_InternalClockConfig(TIM3);
TIM_TimeBaseStructure.TIM_Period=10000-1;//ARR的值周期10K
TIM_TimeBaseStructure.TIM_Prescaler=0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
}

void TIMER3_PWM_Init()
{  
TIM_OCInitTypeDef TIMOCInitStructure;
TIMOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM模式1输出
TIMOCInitStructure.TIM_Pulse =0;//占空比=(CCRx/ARR)*100%
TIMOCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM输出比较极性高
TIMOCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//使能输出状态
TIM_OC2Init(TIM3, &TIMOCInitStructure);//TIM3的CH2输出
TIM_CtrlPWMOutputs(TIM3,ENABLE);//设置TIM3的PWM输出为使能
TIM_Cmd(TIM3, ENABLE); //开启时钟
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

198

主题

3291

帖子

10

粉丝