本章节主要讲解直流减速电机控制原理,电机驱动电路,以及如何使用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 管导通,如果把电机看成电阻的话,这是电机两端电压应该为 12V,PWM 引脚为低电平时 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 */
}
具体实现
可以观察到当速度正反改变,电机转动方向也会改变。文章来源:https://www.toymoban.com/news/detail-452968.html
PWM控制电机调速文章来源地址https://www.toymoban.com/news/detail-452968.html
到了这里,关于STM32循迹小车系列教程(一)—— 使用PWM控制电机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!