基于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/BIN1 | A/BIN2 | 模式状态 |
H | H | 制动 |
H | L | 正转 |
L | H | 反转 |
L | L | 制动 |
当加入了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、驱动逻辑介绍
AIN1 | AIN2 |
直流电机状态 (AO1和AO2) |
任意 | 任意 | 停止 |
0 | 0 | 停止 |
0 | 1 | 正转 |
1 | 0 | 反转 |
1 | 1 | 刹车 |
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 headervoid 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;//设置CCRTIM_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驱动的程序没有调试好,有待改进。
如果本篇文章部分为个人理解,如果发现错误可以告诉我一下,进行改进,虚心学习。
基于STM32的PWM电机驱动TB6612、A4950相关推荐
- K_A08_009 基于 STM32等单片机驱动TB6612模块按键控制直流电机正反转加减速启停
目录 一.资源说明 二.基本参数 1.参数 2.引脚说明 三.驱动说明 TB6612模块驱动说明 对应程序: ENA ENB输出PWM 四.部分代码说明 接线说明 1.STC89C52RC+TB661 ...
- 基于STM32的pwm温度风扇(带人体检测)
一.硬件方案 本次设计采用STM32单片机做主控芯片,通过DS18B20采集温度,将温度显示在 LCD1602上.通过人体传感器检测周围是否有人存在,并根据温度的不同,利用STM32对风扇进行调速. ...
- 基于STM32使用PWM调速控制直流电机
PWM调速控制直流电机 网上找的历程,实现可以,但是无法随我自己的意愿改变速度,还是有问题. 代码如下: #include "delay.h" #include "sys ...
- (学习)基于STM32的PWM控制直流电机转速(CubeMX+HAL库)
使用到的各元件: 1.12V电源一个 2.单片机:STM32F103C8T6 3.直流电机4个 4.电机驱动模块:L298N 5.降压模块两个 6:杜邦线若干 对于直流电机的转动控制如下表 两边电平 ...
- 基于STM32的PWM驱动LED呼吸灯
一,PWM基本原理 所谓PWM,就是脉冲宽度调制技术,其具有两个很重要的参数:频率和占空比.频率,就是周期的倒数:占空比,就是高电平在一个周期内所占的比例.如当周期T=T1+T2:T1为高电平时间,T ...
- 基于STM32制作的音乐播放器,用PWM控制蜂鸣器
目录 效果展示 前言 一.设计背景 1.1.知识储备 二.系统设计方案 2.1.实现功能 2.2.硬件部分 2.3.软件部分 三.软件设计 3.1.设计流程图 3.2.音乐频率的设置 3.3.编程主要 ...
- stm32 带通滤波器_带通滤波 - 基于STM32芯片和TFT-LCD的便携式心电图仪设计
相关推荐 3月10日,纽约州州长安德鲁-库默(Andrew Cuomo)曾在上月宣布,纽约大都市圈的公共交通系... 发表于 2018-04-16 08:50 • 88次阅读 LCD驱动我们只需要写硬 ...
- a4988 脉宽要求_基于STM32的微型步进电机驱动控制器设计
基于STM32的微型步进电机驱动控制器设计 摘 要: 设计了一种微型步进电机驱动控制器,通过上位机界面修改步进电机转速.旋转角度.细分系数.该设计以STM32F103T8U6作为主控制器,以A4988 ...
- 基于STM32,TB6612,TCRT5000的简易红外循迹小车
提醒:本文章只叙述此小车相关大概内容(如模块的设置,C语言基础实现等),单片机详细教学不涉及. 摘要 循迹小车是学习单片机的"地基",它能够让初学者认识单片机内部硬 ...
- 基于STM32的MDK软件仿真输出PWM波形
文章目录 一.PWM相关 1.PWM是什么 2.PWM原理 3.PWM应用 4.PWM信号输出 二.实验相关 1.实验要求 2.实验过程 (1)实验代码 (2)Keil仿真设置 (3)实验结果 三.总 ...
最新文章
- java字符串统计英文字符用什么不同_JAVA程序。输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。...
- ios 将矩形图片裁剪成圆形图片
- boost::bind 介绍
- 深度学习(三十二)半监督阶梯网络学习笔记
- Android基础(四) Fragment Part 1
- 前端 new实例后销毁实例_干货|仪器设备检定校准后的确认(实例)
- C# 通过一个控制台打开另一个控制台
- c语言中的有符号数和无符号数
- 更改用户ID和组ID
- servlet输出中文乱码
- 第一易,唯一难,为什么它是ofo、天学网的不二选择
- 史上最全的数据库面试题,面试前刷一刷!
- 实现调用阿里云API第一章——API请求与认证
- 一次培训机构的Java面试
- 封装class,让className可以在IE8及其以下版本的浏览器中使用
- 下载高清的壁纸,这几个网站就够了
- 《惢客创业日记》2018.11.23(周五) 郭鑫年,你是不是死了?
- 中医针灸学综合练习题库【8】
- List中remove()方法的陷阱以及终极的解决方法!
- 研究音频编解码要看什么书
热门文章
- 上海交大教授:何援军——包围盒(包容体/包围盒子)
- 01.CCNA 200-301 题库_1-50
- java输出日志_Java日志打印方法
- php 万能密码,网络安全系列之十 万能密码登录网站后台
- java activiti 工作流引擎_Activiti工作流引擎简介详解
- 学习《华为基本法》(大结局):法的修订与接班人
- bracktrack5r3安装+bt5r3下安装vmwaretools
- win7系统激活工具
- java fakepath_IE浏览器上传文件时本地路径变成”C:\fakepath\”的问题
- 嵌入式linux指纹识别项目,基于嵌入式应用平台的指纹识别系统设计