从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速

 好久没更新了,最近忙着换工作了。

前面几期好像把硬件部分的搭建说完了,从这期开始讲讲软件吧,先说说直流电机的控制。这部分可以看作是整个系统运行起来的第一步吧,有了这部分内容,前面搭建起来的机器人硬件就可以运作起来了,你的小车就可以放地上跑起来了。

01

PWM

PWM(Pulse Width Modulation),即脉冲宽度调制,是利用微处理器的数字输出对模拟电路进行控制的一种技术,其控制简单灵活动态响应好,广泛应用于工业测控、功率控制,电机控制、开关电源以及音频放大器等领域。

PWM通过使用高分辨率计数器调整输出信号的占空比,实现用数字信号控制模拟信号。PWM信号是数字信号,在任一时刻,电源只有通(1)或断(0)两种状态,电源是以重复脉冲序列加到模拟负载上的。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第1张图片

如图所示,一个PWM的周期内包括一段高电平和一段低电平,其中高电平时间即为脉宽时间,PWM的占空比即为脉宽时间与PWM周期的比值。实际应用中,通过改变占空比来实现控制。

下面以一个电压控制的例子解释PWM的控制实现方法。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第2张图片

如图所示,假设高电平为5V,低电平为0V,当设置PWM的占空比为50%,则实际输出电压值为5V*50%=2.5V,同理,当占空比设置为75%或20%时,则对应的输出电压值分别为3.75V和1V,从而实现了电压的调制输出。由此可见,只要我们设置不同的占空比,理论上就可以将输出电压调制为任意值。

02

代码实现

通过STM32单片机的定时器生成PWM信号。

STM32原理与应用就不讲了,可以自行去学习。 这里直接给出代码。笔者用了STM32CUBEMX进行开发,这个软件是ST自己的软件,相当于是内置了stm32的HAL库,相当于引脚配置这部分的代码不需要自己再手写了,省去了造轮子的时间,开发人员只需要把精力放在业务代码的实现上,大大提高了开发效率。当然如果读者习惯了用标准库函数开发,也可以自己决定使用哪种。

说一下CUBEMX的配置吧。这块具体的配置内容,包括引脚号啥的跟前面硬件的连接那部分是相关的,读者自行对照着看即可。

首先就是要选择单片机型号,即stm32f103c8t6。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第3张图片

双击以后就会自动生成工程。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第4张图片

设置时钟源为外部晶振。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第5张图片

设置时钟频率为72MHz

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第6张图片

开启SW仿真调试。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第7张图片

设置定时器TIM1生成两路PWM信号。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第8张图片

设置电机驱动模块的两路电机输入引脚。注意设置为推挽输出。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第9张图片

这样的话,单片机就配置完了。然后设置一下代码生成规则。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第10张图片

此处MDK版本对照你电脑上安装的版本即可。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第11张图片

点击生成代码。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第12张图片

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第13张图片

点击打开工程即可。然后就自动用KeilMDK软件打开了。

从零开始搭建ROS移动机器人系列之(四)直流电机PWM调速_第14张图片

这是自动生成的引脚配置的代码。

再写一点设置PWM的代码。

#include "stm32f1xx_hal.h"
#include "pwm.h"
#include "tim.h"

void Set_pwm(signed short left, signed short right)
{
  if(left >= 0)
  {
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);
    __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, left);
  }
  else
  {
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET);
    __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, -left);
  }
  if(right >= 0)
  {
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);
    __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_4, right);
  }
  else
  {
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET);
    __HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_4, -right);
  }
}

然后在主函数里开启PWM,再调用Set_pwm函数就可以了。
 

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    Set_pwm(1000,1000);
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

编译通过后下载进单片机就可以看到电机已经可以转起来了。读者也可以尝试改变Set_pwm函数的参数大小,可以发现电机转速会随着参数值的变化而变化。至此就实现了直流电机的PWM调速。

你可能感兴趣的:(从零开始搭建ROS移动机器人,单片机)