请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32之PWM

[复制链接]
STMCU小助手 发布时间:2022-1-14 22:51
  PWM、、英语好的人估计又知道这三个大写字母代表哪三个英语单词了、小弟不才,就说中文意思好了:脉冲宽度调制,玩过飞思卡尔的人估计对PWM非常的不陌生吧、电机驱动需要PWM,控制舵机的转向需要PWM,总之、可以说,PWM,you are so good。
STM32的PWM,就是由定时器产生的,但是奇怪的是除了定时器TIM6和TIM7不能产生PWM外,其他的定时器都可以产生,而且还有多路之分,“高级官员”TIM1和TIM8说:老子可以产生多达7路,而其他的定时器默默的哀伤,因为自己最多只能产生4路(四个通道)。

注:对于寄存器,本博客就不再深入的讲解,大家也可以参照STM32的参考手册,因为本博客讲解的是思路和用库函数,所以就不再细讲寄存器,请见谅
      1、捕获/比较模式寄存器1(TIMx_CCMR1)
      2、捕获/比较使能寄存器(TIMx_CCER)
      3、捕获/比较寄存器2(TIMx_CCR2)
    那好,我们该怎么利用定时器来产生PWM呢??再此之前,我们来了解产生PWM的背后那不为人知的秘密:
    脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。
    在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器,(请注意这句话!!!!)最后还要设置TIMx_CR1寄存器的ARPE位,(在向上计数或中心对称模式中)使能自动重装载的预装载寄存器。
    在PWM模式(模式1或模式2)下,TIMx_CNT和TIMx_CCRx始终在进行比较,(依据计数器的计数方向)以确定是否符合TIMx_CCRx≤TIMx_CNT或者TIMx_CNT≤TIMx_CCRx。
     所以,该寄存器的值一直与CNT比较,根据比较结果产生相应的动作,利用这里一点,我们通过修改这个寄存器的值,就可以控制PWM的输出脉宽了,(在这里有专门的库函数可以操作,所以是相当方便)
    那怎么操作呢??在这里,我们通过一直没有提过的非常重要的概念:重映射,把TIM3_CH2的PA7重映射到PB5,而PB5是连接LED的,所以我们可以通过观察LED的亮度才体验PWM、、也难为了LED君,老是被观察,脸也不红下、、
    所谓的重映射,就是把原本默认的引脚给诱惑到另一个引脚上,专业上给的是重映射,但是我觉得并非这么简单、果然,它还有一个功能:复用、、所以第一步:
        我们要打开复用的时钟和把IO口设成复用推挽输出,当然也要打开TIM3的时钟,见代码:(映射有部分映射和全部映射,都有可用的函数,在这里我们是部分映射,但是,映射了一个引脚,另外的引脚也被牵扯下来了,哎)
  1.             注意红色代码
  2.            RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
  3.            RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  4.                   
  5.            GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);   
  6.      
  7.            GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;               
  8.            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         
  9.            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         
复制代码

    接下来: 通用计时器的初始化:(请看代码:
  1.             TIM_TimeBaseStructure.TIM_Period = arr;               
  2.             TIM_TimeBaseStructure.TIM_Prescaler = psc;
  3.             TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  4.             TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  5.             TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);
复制代码

     接下来,就是PWM的重头戏了,在这里,我们要设置TIM3_CH2为PWM模式,(注意,由于TIM3可以产生四路PWM,每路都有不同的但类似的函数来控制)在这里,我们是通过
    void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)来实现的
打开"stm32f10x_tim.h"可以看到,在这里,我们只显示一些跟我们有用的参数:
TIM_OCMode输出模式;—>PWM2
TIM_OutputState输出使能;—>使能PWM
TIM_OCPolarity输出极性;—>极性为高           代码如下:
  1.          TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
  2.          TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;   
复制代码

     接下来,最关键的一步也是最容易遗漏的:就是使能预装载寄存器,在这里我们通过库函数
    TIM_OC2PreloadConfig     使能或者失能TIMx在CCR2上的预装载寄存器   请看代码:
  1.     TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);   
复制代码

     好了,最后一步,我们开启定时器TIM3,这个大家也不陌生了吧、、还是老规矩;知道的,来人,赏美女十个,还不知道的,拉出去调戏十分钟
  1. /* Enables the TIM3 counter */<div>2  TIM_Cmd(TIM3, ENABLE);</div>
复制代码

      亲、、在这里、、你觉得你能看到LED从暗到亮了吗??你想看,LED君还不肯呢、没错了、、但这是为什么呢??
原因就是这里设置产生的PWN是固定脉宽的、、那我们怎么来改变它呢??咦、库函数为我们提供了这样的一个好机会:
TIM_SetCompare2   设置TIMx捕获比较2寄存器值
通过这个函数我们就可以设置脉冲宽度,从而控制PWM了、、代码如下:
  1. TIM_SetCompare2(TIM3, temp);
复制代码

    好了,我们来总结下步骤:
    1、开启TIM3定时器的时钟,如果有复用,也要打开复用的时钟。
    2、初始化TIM3
    3、设置TIM3_CH2的PWM模式,并使能其输出(注:要使能预装载寄存器)
    4、开启TIM3
    5、改变脉冲宽度,从而改变PWM

少了一些自认为是幽默风趣的语言、、为了是让自己不再显得那么吊儿郎当、、这篇博客在这又到了尾声、、本人也在学习阶段、、尽量把自己当成读者,让读者看得懂、、有写错之处望指出来、不胜感激、、希望能对你有理解上的帮助、、


收藏 评论0 发布时间:2022-1-14 22:51

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版