基于STM32的PWM电机驱动TB6612、A4950

一、直流电机与驱动简介

  • 直流电机是异种将电能转化为机械能的 装置,有两个电极,当电机正接时,电机正转,当电机反接时,电机反转
  • 直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作
  • TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向
  • A4950电机驱动模块是内置一个全桥电路的电机驱动芯片。用于脉宽调制计数(PWM)控制电机的转速。

1、H桥的介绍

图1-1H桥电路图 

 H桥中由两路推挽电路组成的,上接正极,下接负极,A、C端就是一路推挽电路,当A端MOS管导通,C端MOS管断开,那么左边输出就接在VM的正极,A端断开,C端导通就是接在PGND的电源负极;如果有两路推挽电路,A、D端导通B、C端断开电流就是从左往右流动;B、C端导通,A、D端断开,电流就是从右往左流动。H桥可以控制电流流动的反向,所以就可以控制电机的转向。

二、TB6612驱动板

1、驱动引脚介绍

 图2-1TB6612驱动模块

VM:电机电源正极,是驱动电压输入端,范围是4.5V~10V

VCC:逻辑电平输入端,范围2.7V~5.5V,需要与控制器的电源保持一致。(这边我们是使用STM32,与STM32共用一个电源即可)

GND:接系统负极即可

AO1/2、BO1/2:两路电机的输出

PWMAB、AIN1/2、BIN1/2:这三个引脚则是控制A、B两路中的一路电机,连接到STM32的GPIO口即可,PWM引脚需要接到PWM信号输出端,其他两个引脚接任意两个普通GPIO口即可

STBY:待机控制引脚,接GND,芯片则不工作,处于待机状态;接逻辑电源VCC,芯片正常工作。这个引脚如果不需要待机模式,直接VCC即可;需要的话接GPIO口给高低电平,既可以控制。

2、驱动逻辑功能

A/BIN1A/BIN2模式状态
HH制动
HL正转
LH反转
LL制动

 当加入了PWM后,便可以通过占空比调节速度。

  • 一种是IN1和IN2固定,PWM脚输入PWM,此时是配合慢衰减调速。例如:IN1为1,IN2为0,PWM为PWM,则正转和慢衰减相互切换;
  • 另外一种是PWM脚为高电平,IN1、IN2中的一个固定另一个为PWM输入,此时是配合快衰减调速。例如,IN1为1,IN2为PWM输入,PWM为1,则正转与快衰减相互切换。

三、A4950驱动板

2、驱动引脚介绍

 图3-1A4950引脚

 

 图3-2芯片引脚图说明

 2、驱动逻辑介绍

AIN1AIN2

直流电机状态

(AO1和AO2)

任意任意停止
00停止
01正转
10反转
11刹车

A4950驱动板的四种驱动方式:
标号 1:芯片 IN1 端口输入一定的占空比 PWM,IN2 为低电平,此时芯片的输出端口会出去一个正电流。为电机正转。
标号 2:芯片IN1 端口输入低电平,IN2 端口输入一定的占空比 PWM,此时芯片的输出端口会出去一个负电流。为电机反转。
标号 3:芯片IN1 端口输入高电平,IN2 端口输入一定的占空比 PWM,此时芯片的输出端口会出去一个正电流。为电机正转。
标号 4:芯片IN1 端口输入一定的占空比 PWM,IN2 为高电平,此时芯片的输出端口会出去一个负电流。为电机反转。
我们可以选择标号 1和标号 4,只需要在一个 IN1 输入 pwm.另一个IN2 输入高电平或者低电平就可以实现控制电机的速度和正反转。

  • 当xIN中有一个恒为低电平,另一个为PWM时:采取正反转与滑动/快衰减,占空比越大,转速越快。
  • 当xIN中有一个恒为高电平,另一个为PWM时:采取正反转与制动/慢衰减,占空比越小,转速越快。(重点看一下,区别于TB6612)

 具体信息可以参考这个博主写的驱动芯片原理,写的很详细 电机驱动芯片——DRV8833、TB6612、A4950、L298N的详解与比较_朽木白露的博客-CSDN博客_电机驱动芯片原理


 四、代码程序(A4950驱动板)

需要的硬件有:F103C8T6,OLED屏,A4950驱动板,电机,若干杜邦线(公对母),(在这里我使用的是Jlink,所以我需要多加一个电源给驱动板)

Motor.c

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

void Motor_Init(void)
{
		PWM_Init();//PWM初始化
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开APB2时钟
	  
	  GPIO_InitTypeDef GPIO_InitStructure;
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
	  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA,&GPIO_InitStructure);

}

void Motor_SetSpeed(int8_t Speed)
{
	if(Speed >= 0)
	{	 
		//设置电机的正反转,由高电平和低电平来决定极性
		GPIO_SetBits(GPIOA,GPIO_Pin_2);//获得高电平
        PWM_Setcompare1(Speed);
	}
 	else 
	{	
	    GPIO_ResetBits(GPIOA,GPIO_Pin_2);//获得低电平
    	PWM_Setcompare1(-Speed);
		//这时候setcompare为负数,Setcompare必须传正数,所以speed前面必须加一个负号
	}
}

在Motor.c中GPIO的模式需要选用 GPIO_Mode_Out_PP(推挽输出模式)。

注意:setcompare为负数时,Setcompare必须传正数,所以speed前面必须加一个负号

PWM.c

#include "stm32f10x.h"                  // Device header


void PWM_Init(void)
{
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//注意是开启APB1的时钟函数,因为TIM2是APB1总线的外设
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//选择时基单元的时钟
	 
	
	  GPIO_InitTypeDef GPIO_InitStructure;
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	  GPIO_Init(GPIOA,&GPIO_InitStructure);
	
		TIM_InternalClockConfig(TIM2);
	  //定时器上电后默认是使用内部时钟,如果不调用,也是使用内部时钟,可以不写
	
		//TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);
	  //通过ETR引脚的外部时钟模式2配置
	
		TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	  TIM_TimeBaseInitStructure.TIM_ClockDivision =TIM_CKD_DIV1;//指定时钟分频
	  TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up;//计数器模式
		TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //周期,ARR自动重装器的值
		TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;//PSC 预分频器的值
		TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,是高级计数器才有的
	  TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
		//配置时基单元
		
	  TIM_OCInitTypeDef TIM_OCInitStructure;
		TIM_OCStructInit(&TIM_OCInitStructure);//给结构体赋初始值,不用一一列出
		TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2 ;//设置输出比较的模式
		TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
		TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//设置输出使能
		TIM_OCInitStructure.TIM_Pulse = 0;//设置CCR
		TIM_OC1Init(TIM2, &TIM_OCInitStructure);
		
		//周期ARR;预分频PSC;CCR这三个值,共同决定输出PWM的周期和占空比	
		TIM_Cmd(TIM2,ENABLE);//启动定时器
}

void PWM_Setcompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);
}

这里的PWM.c程序是根据上一篇博客修改的,不清楚怎么修改的可以参考上一篇文章喔

 PWM的驱动使用(呼吸灯)_tz得像个小孩的博客-CSDN博客

main.c

#include "stm32f10x.h"                  // Device header
#include  "Delay.h"
#include  "Timer.h"
#include  "OLED.h"
#include  "Key.h"
#include  "Motor.h"


uint8_t KeyNum;//
int8_t Speed;

int main(void)
{
      OLED_Init(); 
	  Motor_Init();
	  Key_Init();
	  Motor_SetSpeed(-80);
	
		OLED_ShowString(1, 1, "Speed:");
	while(1)
	{
			KeyNum = Key_GetNum();
			if (KeyNum == 1)
			{
					Speed += 20;
					if (Speed > 100)
					{
							Speed = -100;
					}
			}
			Motor_SetSpeed(Speed);
			OLED_ShowSignedNum(1, 7, Speed, 3);
	}
	
}

 程序效果

 程序中由于A4950驱动板的逻辑电路与TB6612不同,当Speed显示正数时,电机的转速随着数值的增大而增大;但是在Speed显示为负数时,电机的转速会随着数值(PWM的值)的减小,电机的速度会越来越快。

  • 当xIN中有一个恒为低电平,另一个为PWM时:采取正反转与滑动/快衰减,占空比越大,转速越快。
  • 当xIN中有一个恒为高电平,另一个为PWM时:采取正反转与制动/慢衰减,占空比越小,转速越快。(重点看一下,区别于TB6612)

 五、代码(TB6612驱动板)

PWM.c的程序大差不差,但是在接IO比A4950多了一个引脚,所以具体程序的区别在于Motor.c程序中,程序的呈现效果是Speed的数值为正为正转,负值则为反转,数值越大转速越快。这里TB6612的呈现效果与A4950不一样。

Motor.c

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

void Motor_Init(void)
{
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开APB2时钟
	  
	   GPIO_InitTypeDef GPIO_InitStructure;
	   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
	   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	   GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	   GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_5);
	PWM_Init();//PWM初始化
}

void Motor_SetSpeed(int8_t Speed)
{
	if(Speed >= 0)
	{		
			//设置电机的正反转,由高电平和低电平来决定极性
			GPIO_SetBits(GPIOA,GPIO_Pin_4);//获得高电平
			GPIO_ResetBits(GPIOA,GPIO_Pin_5);//获得低电平
			PWM_Setcompare3(Speed);
	}
	else
	{
			GPIO_SetBits(GPIOA,GPIO_Pin_5);//获得高电平
			GPIO_ResetBits(GPIOA,GPIO_Pin_4);//获得低电平
			PWM_Setcompare3(-Speed);
		//这时候setcompare为负数,Setcompare必须传正数,所以speed前面必须加一个负号
	}
}

 


总结:每个驱动板的驱动逻辑不相同,个人认为A4950驱动的程序没有调试好,有待改进。

如果本篇文章部分为个人理解,如果发现错误可以告诉我一下,进行改进,虚心学习。

  • 23
    点赞
  • 268
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
基于STM32PWM电机驱动TB6612A4950是两种常用的电机驱动模块。这两种模块都能够通过PWM信号输入实现电机的速度控制,适用于不同类型的电机。 首先,TB6612是一种双路H桥驱动模块,可以同时驱动两个电机。通过STM32PWM输出信号,可以控制TB6612的工作状态,从而控制电机的转速和方向。TB6612模块上有多个引脚,需要连接到STM32的相应引脚上。通过控制PWM占空比的大小,可以调节电机的速度,而通过控制不同的引脚信号,可以实现电机的正转、反转和停止。 其次,A4950是一种单路电机驱动模块,适用于直流无刷电机的驱动。通过STM32PWM输出信号,可以调节A4950的速度。A4950模块上也有多个引脚,需要连接到STM32的相应引脚上。与TB6612不同的是,A4950模块还需要连接电机的相应引脚,以控制电机的正转、反转和停止。 无论是TB6612还是A4950,都需要在STM32上进行相应的编程,在程序中配置PWM输出引脚和相应的占空比,以实现对电机的控制。在编程时,需要了解模块的引脚连接和控制信号的作用,通过STM32的相关库函数,可以直接对PWM输出进行设置和控制。 总结来说,基于STM32PWM电机驱动TB6612A4950是常用的电机驱动模块,通过PWM信号输入可以实现对电机的速度控制。通过了解模块的引脚连接和控制信号的作用,并在STM32上进行相应的编程,可以轻松实现对电机的驱动控制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tz得像个小孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值