打印
[其他ST产品]

使用PWM控制电机-STM32循迹小车系列教程(一)

[复制链接]
1817|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本章节主要讲解直流减速电机控制原理,电机驱动电路,以及如何使用PWM控制直流减速电机

前言
1.软件准备:STM32CubeMx、Keil5_ MDK

2.硬件准备:STM32F103C8T6核心板、TB6612电机驱动模块/L298N电机驱动、18650锂电池3节/3S航模电池、杜邦线若干

直流减速电机
       图2-1为市场上常用的直流减速电机的图片,减速电机由直流电机加上减速齿轮构成。减速齿轮决定减速电机的减速比,减速比越大电机转速越慢,力矩越大。减速电机一般驱动电压有 12V 和 24V 的,驱动电压越大同样减速比减速电机对应的力矩也就越大,同时耗电电流也会增加。



下图为某厂家 370减速电机的参数表,我们可以从表中看出与减速电机减速比和驱动电压相对应的力矩、电流等参数的相关关系。


直流电机有两个引脚,当我们正向给电机正向通电时电机正转,当我们反向给电机通电时电机反转。如图 2-3 所示为,当电机的 1 脚施加正极,2 脚施加负极时电机正转;电机的 2 脚施加正极,1 脚施加负极电机反转。



————————————————
版权声明:本文为CSDN博主「宝玺」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_49821504/article/details/130443350

使用特权

评论回复
沙发
烟雨蒙蒙520|  楼主 | 2023-7-29 16:03 | 只看该作者
直流电机调速
       对于电机的调速我们需要通过脉冲宽度调制(Pulse width modulation,PWM)来实现,PWM 的占空比为高电平占整个调制周期的时间比例。
       如图 2-4 所示为脉冲宽度调制的的原理图示,比如高电平时间为 8ms,低电平时间为 2ms时,这是整个脉宽周期是为 10ms,占空比即为 80%。我们通过此波形来控制电机即可实现电机的速度控制,且占空比越高的话,高电平的比例越高,则电机速度就会越快,反之就越慢,一般PWM的频率应大于 1KHZ。当然单片机引脚产生的这个 PWM 波形肯定是不可能直接驱动电机的,中间需要使用驱动电路。


    图 2-5 左为单向电机驱动电路,PWM 引脚为高电平时 N 沟道 MOS 管导通,如果把电机看成电阻的话,这是电机两端电压应该为 12V,PWM 引脚为低电平时 N 沟道 MOS管截止,电机两端电压应该为 0V。但实际电机并不能看成电阻。

        图 2-5 右的电路等效为右边的电路,我们可以把电机看成一个电感,我们知道电感有储能的作用,所以当 MOS管截止电感会释放能量,所以电机两端电压并不是 0V。

使用特权

评论回复
板凳
烟雨蒙蒙520|  楼主 | 2023-7-29 16:04 | 只看该作者
同样当 MOS 管导通时电感会吸收能量,所以电机两端电压也并不是 12V。而是与 PWM 占空比相关,电机两端电压应该

使用特权

评论回复
地板
烟雨蒙蒙520|  楼主 | 2023-7-29 16:04 | 只看该作者
        如果 PWM占空比为 80%,电机供电电压为 12V 的话,此时电机的实际电压应为 9.6V,所以调PWM 占空比调节电机转速也就是调节电机两端电压调节电机转速。但是PWM 脉冲周期需要小于电感储放能的时间。

使用特权

评论回复
5
烟雨蒙蒙520|  楼主 | 2023-7-29 16:04 | 只看该作者
电机驱动电路
        一般我们控制电机需要控制电机的正反转,一个 MOS 管并不能满足我们的需求,所以我们需要通过 H 桥电路来实现,H 桥需要 4 个 MOSFET,这样电路设计起来比较麻烦。市场上有帮我们搭建好的 H 桥电机驱动芯片,这里我们用到的驱动芯片为TB6612FNG,如下图所示,
TB6612FNG介绍  
        单片机引脚的电流一般只有几十个毫安,无法驱动电机,因此一般是通过单片机控制电机驱动芯片进而控制电机。TB6612是比较常用的电机驱动芯片之一。


TB6612FNG可以同时控制两个电机,工作电流1.2A,最大电流3.2A。

AIN1/2、BIN1/2接单片机的GPIO口。PWMA/B接单片机的定时器口(配置为定时器PWM)。AO1/2、BO1/2接电机的正负极。

        PWMA、AIN1/2、AO1/2为一组驱动一个电机, PWMB、BIN1/2、BO1/2为一组驱动另一个电机。

        STBY为正常工作、待机状态控制引脚,一般接3.3V电即可。VM为电机驱动电压输入(<12V,可接3S锂电池),VCC为逻辑电平输入端(2.7V~5.5V)。

使用特权

评论回复
6
烟雨蒙蒙520|  楼主 | 2023-7-29 16:05 | 只看该作者
用户可通过配置AIN1/2、BIN1/2的电平状态控制电机转向,如下图TB6612电机驱动真值表,



       我们将VM和GND接入电源正极(6~12V,一般2-3节锂电池)和负极(GND需要与主控板共地),PWMA接入主控板上PA6端口,AIN1接入主控板的PB12端口,AIN2接入主控板的PB13端口,STBY接入3.3V,AO1和AO2接入电机的正负极。

使用特权

评论回复
7
烟雨蒙蒙520|  楼主 | 2023-7-29 16:05 | 只看该作者
电机驱动程序实现
定时器配置和GPIO配置均通过STM32CUBEMX配置

使用特权

评论回复
8
烟雨蒙蒙520|  楼主 | 2023-7-29 16:05 | 只看该作者
GPIO配置
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);

  /*Configure GPIO pins : PB12 PB13 PB14 PB15 */
  GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

使用特权

评论回复
9
烟雨蒙蒙520|  楼主 | 2023-7-29 16:06 | 只看该作者
PWM配置
void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 72-1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 1000-1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */
  HAL_TIM_MspPostInit(&htim3);

}

使用特权

评论回复
10
烟雨蒙蒙520|  楼主 | 2023-7-29 16:06 | 只看该作者
电机控制代码
/**************************************************************************
函 数 名:void motor_ctrl(int16_t left_speed,int16_t right_speed)
功    能:电机速度设定函数
入口参数:left_speed左电机速度 right_speed右电机速度
**************************************************************************/
void motor_ctrl(int16_t left_speed,int16_t right_speed)
{
        if(left_speed>=0) //左电机速度大于0时,电机正转
        {
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET);
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_RESET);
        }
        else         //电机反转                                                                   
        {               
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,GPIO_PIN_SET);
  }
       
        if(right_speed>=0)  
        {
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_SET);
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_RESET);
        }
        else                                                                            
        {               
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_15,GPIO_PIN_SET);
  }
       
        __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, abs(left_speed));//将速度占空比赋给电机
        __HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_2, abs(right_speed);
}

使用特权

评论回复
11
烟雨蒙蒙520|  楼主 | 2023-7-29 16:06 | 只看该作者
主函数
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  The application entry point.
  * @retval int
  */
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 */

  /* 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_TIM3_Init();
  /* USER CODE BEGIN 2 */
                HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//开启定时器PWM
                HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
                motor_ctrl(500,-500);
                HAL_Delay(5000);
                motor_ctrl(-500,500);
                HAL_Delay(5000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

使用特权

评论回复
12
烟雨蒙蒙520|  楼主 | 2023-7-29 16:06 | 只看该作者
具体实现
可以观察到当速度正反改变,电机转动方向也会改变。

使用特权

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

本版积分规则

33

主题

641

帖子

0

粉丝