目录
TB6612电机驱动模块
A4988 步进电机驱动模块
淘宝使用说明
引脚说明
逻辑控制图
L298N电机驱动模块
步进电机
TB6612FNG是东芝半导体公司生产的一款直流电机驱动器件,它具有大电流MOSFET-H桥结构,双通道电路输出,可同时驱动2个电机。
TB6612FNG每通道输出高1 A的连续驱动电流,启动峰值电流达2A/3A(连续脉冲/单脉冲);4种电机控制模式:正转/反转/制动/停止;PWM支持频率高达100 kHz;待机状态;片内低压检测电路与热停机保护电路;工作温度:-20~85℃;SSOP24小型贴片封装。
TB6612FNG的主要引脚功能:AINl/AIN2、BIN1/BIN2、PWMA/PWMB为控制信号输入端;AO1/A02、B01/B02为2路电机控制输出端;STBY为正常工作/待机状态控制引脚;VM(3~13.5 V)和VCC(2.7~5.5 V)分别为电机驱动电压输入和逻辑电平输入端。
相比L298N的热耗性和外围二管续流电路,它无需外加散热片,外围电路简单,只需外接电源滤波电容就可以直接驱动电机,利于减小系统尺寸。对于PWM信号,高达100 kHz的频率。
TB6612的的用法:
TB6612是双驱动,也就是可以驱动两个电机
下面分别是控制两个电机的IO口
STBY口接单片机的IO口清零电机部停止,置1通过AIN1 AIN2,BIN1,BIN2 来控制正反转
VM 接15V以内电源(3~13.5 V)
VCC 接5V电源(2.7~5.5 V)
GND 就不多说了啊
驱动1路
PWMA 接单片机的PWM口
真值表:
AIN1 0 0 1
AIN2 0 1 0
停止 正传 反转
A01
AO2 接电机1的两个脚
驱动2路
PWMB 接单片机的PWM口
真值表:
BIN1 0 0 1
BIN2 0 1 0
停止 正传 反转
B01
BO2 接电机2的两个脚
A4988是一款带转换器和过流保护的DMOS微步进电机驱动器,它用于操作双极步进电机,在步进模式,输出驱动的能力35V和±2A。
转换器是A4988易于实施的关键。只要在“STEP”引脚输入一个脉冲,即可驱动电动机产生微步。无须进行相位顺序表、高频率控制行或复杂的界面编程。A4988界面非常适合复杂的微处理器不可用或过载的应用。
2 产品特点
1、控制简单,只需要控制STEP与DIR两个端口;
2、精度调整,五种不同的步进模式:全、半、1/4、1/8、1/16;
3、可调电位器可以调节输出电流,从而获得更高的步进率;
4、兼容3.3V和5V逻辑输入;
STEP、DIR分别连接单片机的两个控制端口,EN可以使用单片机端口控制,也可以直接连接GND使能;MS1、MS2、MS3按照上一节“步进模式设置”,接高低电平,设置步进模式,来选择不同的步距角。设置脉冲的频率,来控制旋转速度。
2B、2A、1A、1B分别接步进电机红、蓝、黑、绿线。
VMOT、GND接12V左右直流电源(电压大小更具步进电机不同,选择合适电压)。
VDD、GND接3.3V或5V。
7 实验代码
//初始化步进电机控制端口
//STEP1 PCout(4)
//DIR1 PCout(5)
void STEP_Init(void)
{
RCC->APB2ENR|=1<<4; //使能PORTC时钟
GPIOC->CRL&=0XFF00FFFF;
GPIOC->CRL|=0X00330000;
}
//dir:为方向控制,TRUE:正转 FALSE:反转
//period为周期
//steps:脉冲个数
void Step_Control(u8 dir,u16 period,u32 steps)
{
u32 i;
for(i=0; i <= steps;i++)
{
DIR = dir;
STEP = 1;
delay_us(1);
STEP = 0;
delay_us(period);
}
}
#define TRUE 1
#define FALSE 0
//端口定义
#define STEP PCout(4)
#define DIR PCout(5)
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
STEP_Init(); //步进电机驱动端口初始化
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
LED = !LED;
Step_Control(FALSE,1600,200);
delay_ms(1000);
Step_Control(TRUE,1600,400);
delay_ms(1000);
}
}
程序实现功能:电机反转1圈、正转2圈。
不改变程序,设置不同的步进模式,观察步进电机的旋转角度。
(1)睡眠模式:Sleep管脚电平置0,进入睡眠模式,驱动器输出待机模式;Sleep管脚置1,驱动器处于正常工作状态;
(2)正反转模式:正转模式DIR管脚置0或1,反转模式置1或0;
(3)复位模式:复位模式下容易消耗能量,产生的冲击电流较大。直接RESET管脚置1,在不影响系统工作时RESET管脚置0复位。一旦驱动芯片复位,系统将回归到原始A4988 I/O端口控制状态;
(4)使能模式:使能模式控制系统是否开始工作,ENBALBE管脚置0开始工作,置1停止工作;
(5)细分模式:通过MS1、MS2、MS3控制细分系数,A4988细分为1/16细分为最小,通过计算角度值可得最小细分角度为全步进角度的1/16。A4988驱动逻辑控制如表1所示。
使用方法:
拿到一个步进电机时,首先检测步进电机两条线之间的电阻,两条线之间电阻小的(在蠕动泵上测试为33Ω左右),接4988的1A、1B端(或2A、2B端),其中调换1A、1B端(或2A、2B端)的顺序可以改变电机的旋转方向。
使用中,把使能脚和细分脚全部接地,即不设置细分(步进值为1),复位脚和睡眠脚用跳线帽短接。
direction方向控制
step脉冲控制
Sleep管脚电平置0,进入睡眠模式,驱动器输出待机模式;Sleep管脚置1,驱动器处于正常工作状态;
Reset与Sleep连接,也可同时置高电平工作
MS1、MS2、MS3控制细分系数
ENBALBE使能模式控制系统是否开始工作,ENBALBE管脚置0开始工作,置1停止工作抱死
VMOT、GND接12V左右直流电源,步进电机工作电压(电压大小更具步进电机不同,选择合适电压)。
VDD、GND接3.3V或5V,芯片工作电压。
控制简单,只需要控制STEP与DIR两个端口;其余按照逻辑控制表接线
控制DIR、STEP
使能信号输入电压范围(ENA ENB):
低电平:-0.3≤Vin≤1.5V(控制信号无效)
高电平:2.3V≤Vin≤Vss(控制信号有效)
注意事项:
1.当你的驱动电压(上图标识为12V输入,实际可以接受的输入范围是7-12V)为7V-12V的时候,可以使能板载的5V逻辑供电,当使用板载5V供电之后,接口中的+5V供电不要输入电压,但是可以引出5V电压供外部使用。(这种即为常规应用!)
2.当驱动电压高于12V,小于等于24V(芯片手册中提出可以支持到35V,但是按照经验一般298保守应用最大电压支持到24V已经很了不起!)时,比如要驱动额定电压为18V的电机。首先必须拔除板载5V输出使能的跳线帽。然后在5V输出端口外部接入5V。
5V使能即一个电平为5V的控制信号,当此信号输入有效时,且电机驱动模块中电源供电正常时,电机驱动模块输出电流。否则即使电源供电正常,电机上也无电流。电压对L298N内部逻辑电路供电。(这种是高压驱动的非常规应用!)
#include "cnc_step_control.h"
#include "main.h"
void step_gpio_config(void)
{
GPIO_InitTypeDef GPIO_Initstructure;
RCC_APB2PeriphClockCmd( STEP_X_APB2Periph, ENABLE );
GPIO_Initstructure.GPIO_Pin = STEP_X_PIN;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init( STEP_X_PORT,&GPIO_Initstructure);
GPIO_ResetBits(STEP_X_PORT,STEP_X_PIN);
GPIO_Initstructure.GPIO_Pin = DIR_X_PIN;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init( DIR_X_PORT,&GPIO_Initstructure);
GPIO_ResetBits(DIR_X_PORT,DIR_X_PIN);
GPIO_Initstructure.GPIO_Pin = MS1_PIN;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init( MS1_PORT,&GPIO_Initstructure);
GPIO_SetBits(MS1_PORT,MS1_PIN);
GPIO_Initstructure.GPIO_Pin = MS2_PIN;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init( MS2_PORT,&GPIO_Initstructure);
GPIO_SetBits(MS2_PORT,MS2_PIN);
GPIO_Initstructure.GPIO_Pin = MS3_PIN;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init( MS3_PORT,&GPIO_Initstructure);
GPIO_SetBits(MS3_PORT,MS3_PIN);
GPIO_Initstructure.GPIO_Pin = EN_PIN;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init( EN_PORT,&GPIO_Initstructure);
GPIO_ResetBits(EN_PORT,EN_PIN);
}
// 中断优先级配置
void step_TIM3_NVIC_Config(void)//采用最后面的优先级 group:0 preemption :15 sub:0
{
NVIC_InitTypeDef NVIC_InitStructure;
// 设置中断组为 0
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
// 设置中断来源
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn ;
// 设置主优先级为 0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15;
// 设置抢占优先级为 3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/* 频率确定
就按核心板的时钟频率为72Mhz计算
X = 72MHZ/(ARR+1)(PRESC+1)
采样频率设置为1000hz
*/
#define TIM3_ARR 900-1
#define TIM3_PRESCARE 80-1
void step_TIM3_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
// 开启定时器时钟,即内部时钟 CK_INT=72M
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器5时
//初始化TIM5
// 自动重装载寄存器周的值(计数值)
TIM_TimeBaseStructure.TIM_Period=TIM3_ARR;
// 累计 TIM_Period 个频率后产生一个更新或者中断
// 时钟预分频数为 71,则驱动计数器的时钟 CK_CNT = CK_INT / (71+1)=1M
TIM_TimeBaseStructure.TIM_Prescaler= TIM3_PRESCARE;
// 时钟分频因子 ,基本定时器没有,不用管
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 重复计数器的值,基本定时器没有,不用管
TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
// 初始化定时器
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// 清除计数器中断标志位
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM3, ENABLE);
}
void CNC_step_Init(void)
{
printf("\r\n cnc_step_Init \r\n");
step_TIM3_NVIC_Config();
step_TIM3_Config();
step_gpio_config();
};
u8 PWM_X = 10;
u8 PWM_Y;
u8 PWM_Z;
int speed_motor1 = 0;
int motor_id = 0;
char stepX_flag = 1;
char stepY_flag = 0;
char stepZ_flag = 0;
char stepperFlag = 1;
char stepX_direct = 0;
char stepY_direct = 0;
char stepZ_direct = 0;
int step_countX = 0;
int step_countY = 0;
int step_countZ = 0;
void runing(void)
{
if(stepX_flag ==1)
{
step_countX ++;
if(step_countX == PWM_X/2)
{
step_X(1);
}
if(step_countX == PWM_X)
{
step_countX=0;
step_X(0);
}
}
if(stepY_flag ==1)
{
step_countY ++;
if(step_countY == PWM_Y/2)
{
step_Y(1);
}
if(step_countY == PWM_Y)
{
step_countY=0;
step_Y(0);
}
}
if(stepZ_flag ==1)
{
step_countZ ++;
if(step_countZ == PWM_Z/2)
{
step_Z(1);
}
if(step_countZ == PWM_Z)
{
step_countZ=0;
step_Z(0);
}
}
}
void TIM3_IRQHandler(void) //采集
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //如果TIM3设置的数值溢出
{
if(stepperFlag == 1)
runing();
TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);
}
}
/*
控制步进电机速度与方向
参数:
参数1:电机id
参数2:方向
参数3:速度
*/
void set_stepmoter_XYZ(step_XYZ id,char direct,int PWM)
{
stepX_direct = direct;
switch (id)
{
case STEP_X:
stepX_direct = direct;
PWM_X = PWM;
break;
case STEP_Y:
stepY_direct = direct;
PWM_Y = PWM;
break;
case STEP_Z:
stepZ_direct = direct;
PWM_Z = PWM;
break;
default:
break;
}
start();
printf("id:%d\t direct:%d\t speed:%d\t \r\n",id, direct, PWM);
}
void stop(void)
{
stepperFlag = 0;
}
void start(void)
{
stepperFlag = 1;
}
#ifndef __BASE_STEP_CONCTROL_H
#define __BASE_STEP_CONCTROL_H
#include "stm32f10x.h"
#include "main.h"
#define MOTOR_PERIOD 1000 //与平路周期有关
/********************基本定时器 TIM 参数定义,只限 TIM6、 7************/
////////////////////////////////////////////////////////////////////////////////////////////////////////
#define BASIC_TIM TIM3 ////
#define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd ////
#define BASIC_TIM_CLK RCC_APB1Periph_TIM3 ////
#define BASIC_TIM_IRQ TIM3_IRQn ////
#define BASIC_TIM_IRQHandler TIM3_IRQHandler ////
#define STEP_X_APB2Periph RCC_APB2Periph_GPIOC //// ////
#define STEP_X_PORT GPIOC ////
#define STEP_X_PIN GPIO_Pin_14 ////
#define step_X(n) GPIO_WriteBit( STEP_X_PORT, STEP_X_PIN,(BitAction) n) ////
#define DIR_X_APB2Periph RCC_APB2Periph_GPIOC //// ////
#define DIR_X_PORT GPIOC ////
#define DIR_X_PIN GPIO_Pin_13 ////
#define DIR_X(n) GPIO_WriteBit( DIR_X_PORT, DIR_X_PIN,(BitAction) n) ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#define STEP_Y_APB2Periph RCC_APB2Periph_GPIOC //// ////
#define STEP_Y_PORT GPIOC ////
#define STEP_Y_PIN GPIO_Pin_14 ////
#define step_Y(n) GPIO_WriteBit( STEP_Y_PORT, STEP_Y_PIN,(BitAction) n) ////
#define STEP_Z_APB2Periph RCC_APB2Periph_GPIOC //// ////
#define STEP_Z_PORT GPIOC ////
#define STEP_Z_PIN GPIO_Pin_15 ////
#define step_Z(n) GPIO_WriteBit( STEP_Z_PORT, STEP_Z_PIN,(BitAction) n) ////
/////////////////////////////////////////////////////////////////////////////////////////////////////
#define MS1_APB2Periph RCC_APB2Periph_GPIOA //// ////
#define MS1_PORT GPIOC ////
#define MS1_PIN GPIO_Pin_3 ////
#define MS1_X(n) GPIO_WriteBit( MS1_PORT, MS1_PIN,(BitAction) n)
#define MS2_APB2Periph RCC_APB2Periph_GPIOA //// ////
#define MS2_PORT GPIOC ////
#define MS2_PIN GPIO_Pin_4 ////
#define MS2_X(n) GPIO_WriteBit( MS2_PORT, MS2_PIN,(BitAction) n)
#define MS3_APB2Periph RCC_APB2Periph_GPIOA //// ////
#define MS3_PORT GPIOC ////
#define MS3_PIN GPIO_Pin_5 ////
#define MS3_X(n) GPIO_WriteBit( MS3_PORT, MS3_PIN,(BitAction) n)
#define EN_APB2Periph RCC_APB2Periph_GPIOA //// ////
#define EN_PORT GPIOC ////
#define EN_PIN GPIO_Pin_6 ////
#define EN_X(n) GPIO_WriteBit( EN_PORT, EN_PIN,(BitAction) n) ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////
void CNC_step_Init(void);
void set_stepmoter_XYZ(step_XYZ id,char direct,int speed);
static void CNC_Step_SET(void);
void start(void);
void stop(void);
#endif /* __SYSTICK_H */