当前位置:   article > 正文

第四节:STM32定时器(2.输出PWM波控制电机转速)_pwm控制电机转速

pwm控制电机转速

 关联:STM32总结超全笔记【秋招自用】

 四.STM32定时器(重中之重中之重)

【前言】

我觉得在冗长的理论之前,我们首先要对定时器的输出比较功能做一个理解。

【问】输出比较用来做什么?应用场景是什么??

输出比较,就是可以控制定时器,去比较 CNT 和 CCR 寄存器值的关系,来对输出的电平进⾏置1、置0或翻转的操作,⽤于输出⼀定频率和占空比的 PWM 波形。

【问】什么是PWM波?

PWM全称为脉冲宽度调制。

PWM波输出原理:

当 CNT<CCRx 时, IO 输出低电平(逻辑 0 );
当 CNT>=CCRx 时, IO 输出高电平(逻辑 1 );
当 CNT=ARR 时,定时器溢出, CNT 的值被清零,然后继续递增,依次循环;

占空比:高电平所占时间 / 周期时间
占空比 = CCR / (ARR + 1)

频率 =  CK_PSC / (PSC + 1) / (ARR + 1)

【PWM的应用场景】

【问】我们已经知道了输出比较,就是通过cnt和arr的比较,输出高低电平,输出PWM波,那么PWM波有什么用???

1.PWM输出呼吸灯

之前学完了最简单的基本定时器,我们来学习通用定时器。

首先人眼对80Hz以上的刷新频率是感受不到闪烁的。

我们来分析一下比如说:

  • 频率100Hz的场景:10毫秒内,5毫秒打开,5毫秒关闭,(占空比50%)此时常量。
  • 频率1Hz的场景:1秒内,0.5秒打开,0.5秒关闭,此时很明显的闪烁。
  • 频率100Hz的场景:10毫秒内,9毫秒打开,1毫秒关闭,(占空比90%)此时亮度比第一个例子亮。

所以:频率相同,占空比越大,灯越亮。

改变占空比,即可改变灯的亮度,实现呼吸灯。

2.PWM控制电机转速

直流电机中,电机转速是周期内输出的平均电压值,那么占空比越大,输出电压越大,速度越大。

改变占空比,即可改变电机转速。

3.PWM控制舵机

舵机频率一般为50Hz,相当于20毫秒的脉冲,脉冲的高电平部分范围是0.5ms到2.5ms之间。如果是180度的舵机,那么:

0.5ms对应0度

1ms对应45度

以此类推,2.5ms对应180度

---------------------------------------------------------------------------------------------------------------------------------

有了这些知识铺垫后,我们开始定时器输出比较的学习。

之前学完了最简单的基本定时器,我们来学习通用定时器。

【通用定时器】

 我们着重看一下输出比较这部分框图:

【输出比较】

说白了就是先初始化定时器模块和输出比较模块,然后通过控制CCR的值,改变灯的亮度或者是电机的速度。

那么例程就写一个控制直流电机转速,为后面的STM32小车做铺垫。

【例程6】输出PWM波控制电机转速

首先看一下硬件连接:

因为直流电机属于大功率器件,单片机引脚输出电压太小无法直接驱动,所以需要一个电机驱动模块,这里用TB6612。

【PWM初始化】

  1. void PWM_Init(void)
  2. {
  3. /*开启时钟*/
  4. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟
  5. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
  6. /*GPIO初始化*/
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  9. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  10. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11. GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA2引脚初始化为复用推挽输出
  12. //受外设控制的引脚,均需要配置为复用模式
  13. /*时基单元初始化*/
  14. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量
  15. TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
  16. TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数
  17. TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //计数周期,即ARR的值
  18. TIM_TimeBaseInitStructure.TIM_Prescaler = 36 - 1; //预分频器,即PSC的值
  19. TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到
  20. TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元
  21. /*输出比较初始化*/
  22. TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体变量
  23. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较模式,选择PWM模式1
  24. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性,选择为高,若选择极性为低,则输出高低电平取反
  25. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能
  26. TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值
  27. TIM_OC3Init(TIM2, &TIM_OCInitStructure); //将结构体变量交给TIM_OC3Init,配置TIM2的输出比较通道3
  28. /*TIM使能*/
  29. TIM_Cmd(TIM2, ENABLE); //使能TIM2,定时器开始运行
  30. }

【问】为什么PA2被设置为了复用推挽输出?

因为PA2接的是PWMA,由内部外设控制的时候,需要设置为复用推挽输出。

后面都是比较基础的设置了。

【电机驱动模块的GPIO初始化】

  1. void Motor_Init(void)
  2. {
  3. /*开启时钟*/
  4. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
  5. GPIO_InitTypeDef GPIO_InitStructure;
  6. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  7. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
  8. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  9. GPIO_Init(GPIOA, &GPIO_InitStructure);
  10. PWM_Init(); //初始化直流电机的底层PWM
  11. }

【设置电机速度的函数】

  1. void PWM_SetCompare3(uint16_t Compare)
  2. {
  3. TIM_SetCompare3(TIM2, Compare); //设置CCR3的值
  4. }

这里是对TIM_SetCompare3做一个封装。

  1. void Motor_SetSpeed(int8_t Speed)
  2. {
  3. if (Speed >= 0) //如果设置正转的速度值
  4. {
  5. GPIO_SetBits(GPIOA, GPIO_Pin_4); //PA4置高电平
  6. GPIO_ResetBits(GPIOA, GPIO_Pin_5); //PA5置低电平,设置方向为正转
  7. PWM_SetCompare3(Speed); //PWM设置为速度值
  8. }
  9. else //否则,即设置反转的速度值
  10. {
  11. GPIO_ResetBits(GPIOA, GPIO_Pin_4); //PA4置低电平
  12. GPIO_SetBits(GPIOA, GPIO_Pin_5); //PA5置高电平,设置方向为反转
  13. PWM_SetCompare3(-Speed); //PWM设置为负的速度值,因为此时速度值为负数,而PWM只能给正数
  14. }
  15. }

此函数就是根据TB6612的数据手册编写的(所以查Datasheet非常重要)

 此时在主函数中利用封装好的Motor_SetSpeed函数即可控制电机速度了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/918130
推荐阅读
相关标签
  

闽ICP备14008679号