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

本章节主要讲解直流减速电机控制原理,电机驱动电路,以及如何使用PWM控制直流减速电机

前言

1.软件准备:STM32CubeMx、Keil5_ MDK

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

直流减速电机

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

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

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

 直流电机调速

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

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

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

        同样当 MOS 管导通时电感会吸收能量,所以电机两端电压也并不是 12V。而是与 PWM 占空比相关,电机两端电压应该为  𝑉𝑚=𝑃𝑑𝑉𝑖 , 𝑉𝑚 为电机实际电压,  𝑃𝑑  为占空比,  𝑉𝑖 为给电机供电电压。

        如果 PWM占空比为 80%,电机供电电压为 12V 的话,此时电机的实际电压应为 9.6V,所以调PWM 占空比调节电机转速也就是调节电机两端电压调节电机转速。但是PWM 脉冲周期需要小于电感储放能的时间。

电机驱动电路

        一般我们控制电机需要控制电机的正反转,一个 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)。

用户可通过配置AIN1/2、BIN1/2的电平状态控制电机转向,如下图TB6612电机驱动真值表,

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

电机驱动程序实现

定时器配置和GPIO配置均通过STM32CUBEMX配置,本此教程不再赘述,详细请见以往PWM配置教程STM32CubeMx使用教程(五)—— 使用PWM控制蜂鸣器演唱孤勇者

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);

}

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);

}

电机控制代码

/**************************************************************************
函 数 名: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);
}

主函数 

/**
  * @brief  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 */
}

具体实现

可以观察到当速度正反改变,电机转动方向也会改变。

PWM控制电机调速

  • 31
    点赞
  • 228
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: STM32循迹小车PWM是利用STM32单片机实现循迹小车控制的一种方法。PWM(Pulse Width Modulation)是一种通过改变脉冲宽度的方式来控制电子设备的技术。而CSND是中国最大的IT技术社区CSDN的简称。 在STM32循迹小车中,我们可以利用PWM技术控制电机的速度和方向。通过设置占空比来控制电机驱动器的输出电压,从而改变电机的转速。通过改变PWM信号的频率和占空比,可以实现车辆的前进、后退以及转弯等动作。 在循迹小车中,循迹传感器可以检测到黑线与白线的交界处,并将传感器检测到的信号通过模数转换器(ADC)转换为数字信号输入给STM32单片机。根据传感器的检测结果,我们可以通过编程算法判断车辆应该采取的动作,并利用PWM技术控制电机的输出从而实现循迹。 为了编写循迹小车控制程序,我们可以借助CSDN这一IT技术社区,参考其他人的经验与分享,获取相关代码及开发工具的使用教程等。借助CSDN的开放性和交流性质,我们可以更好地学习和解决在开发循迹小车过程中遇到的问题。 总之,STM32循迹小车PWM CSND是一种利用STM32单片机和PWM技术实现循迹小车控制的方法,而借助CSDN这个IT技术社区,我们可以更好地学习和开发循迹小车的相关知识。 ### 回答2: STM32循迹小车是一种基于STM32单片机的智能小车,它能够通过PWM(脉宽调制)技术实现精确的速度调节和转向控制。CSND(CSDN)是一家提供在线技术交流和分享的平台。 循迹小车是一种能够在预定路径上进行移动的智能小车,它通常通过红外传感器等感知模块来检测路径上的黑线,并根据检测结果进行控制使用STM32单片机作为控制核心,可以实现进行实时数据采集和控制计算。PWM技术是一种通过控制信号的占空比来调节输出信号的平均值的方法,可以实现精确的速度调节和转向控制循迹小车通常会根据红外传感器检测到的黑线位置来调整左右轮的PWM信号,从而使小车能够在路径上保持平稳运行。 CSDN是全球最大的中文IT社区和技术交流平台,许多开发者和学习者都会在CSDN上发布他们的技术文章和分享经验。对于循迹小车PWM控制,CSDN上有许多相关的技术文章和实例代码,开发者可以从中学习和借鉴。在CSDN上,通过搜索关键词"STM32循迹小车PWM",可以找到一些相关的技术博文和论坛贴子,其中包含了循迹小车PWM控制的详细实现方法和代码示例。借助CSDN这样的技术社区,开发者可以更好地理解和掌握循迹小车PWM控制的原理和实践应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值