赞
踩
本文介绍的步进电机驱动为毕设所用,学习时也借鉴了其他博主和商家的资料,介绍的都很详细。但对于刚入门的友友萌来说,可能还会存在的一些不解。而我就是被卡在驱动电源上。下文为我对4988驱动的一些理解,希望能帮助到刚学习步进电机的朋友。
4988驱动IC价格便宜驱动简单,但在驱动步进电机时,电机会存在的明显震动。下一篇文章将实现TMC2208驱动IC控制步进电机。
A4988 是一款完全的微步电动机驱动器,带有内置转换器,易于操作。该产品可在全、半、1/4、1/8 及 1/16 步进模式时操作双极步进电动机,输出驱动性能可达 35 V 及 ±1 A。A4988 包括一个固定关断时间电流稳压器,该稳压器可在慢或混合衰减模式下工作。转换器是 A4988 易于实施的关键。只要在“步进”输入中输入一个脉冲,即可驱动电动机产生微步。无须进行相位顺序表、高频率控制行或复杂的界面编程。A4988 界面非常适合复杂的微处理器不可用或过载的应用。在微步运行时,A4988 内的斩波控制可自动选择电流衰减模式(慢或混合)。在混合衰减模式下,该器件初始设置为在部分固定停机时间内快速衰减,然后在余下的停机时间慢速衰减。混合衰减电流控制方案能减少可听到的电动机噪音、增加步进精确度并减少功耗。提供内部同步整流控制电路,以改善脉宽调制 (PWM) 操作时的功率消耗。内部电路保护包括:带滞后的过热关机、欠压锁定(UVLO) 及交叉电流保护。不需要特别的通电排序。
A4988 采用表面安装 QFN 封装 (ES),尺寸为 5 mm × 5mm, 标称整体封装高度为 0.90 mm ,并带有外露散热板以增强散热功能。该封装为无铅封装(后缀–T),采用 100% 雾锡电镀引脚框。
如图1所示为HR4988步进电机驱动模块非A4988,是一款国产pin to pin完全可替换A4988的驱动芯片。至于为什么选择HR4988而不用A4988?也就是懵懂无知,买了一款绿色的驱动模块,在学习过程中弄坏了,就想试试红色的。但二者的配置过程一致。
VMOT – 电机电源正极(A4988可用电源电压为8V ~ 35V,HR4988为8~32V)注:此引脚用于连接为电机供电的电源 GND – 电机电源接地 2B, 2A – 电机绕组2控制引脚 1A, 1B – 电机绕组1控制引脚 VDD – 逻辑电源正极(3 – 5.5伏)注:此引脚用于为4988电机驱动板供电 GND – 逻辑电源接地 ENABLE – 使能引脚(低电平有效) 引脚说明:此当此引脚为低电平时,A4988才能进行电机驱动工作,当该引脚为高电平,A4988将不会进行电机驱动工作。如果该引脚悬空,则A4988默认为使能状态。即该引脚没有连接任何电平时,A4988可以正常工作。 MS1, MS2, MS3 – 驱动模式引脚 引脚说明:这三个引脚控制A4988微步细分驱动模式。通过这三个引脚的逻辑电平,我们可以调整A4988驱动电机模式为全、半、1/4、1/8 及 1/16 步进模式。Table1图中右侧的表格里有具体如何调节这三个引脚电频以及A4988在不同的电平组合下的驱动模式。表格中“L”代表低电平,“H”代表高电平。“FULL”为全步进,“HALF”为半步进,“QUATER”为1/4步进, “EIGHTH”为1/8步进, “SIXTEENTH”为1/16步进。当MS1, MS2, MS3这几个引脚悬空时,A4988默认为全步进电机驱动模式。 RESET – 复位引脚 引脚说明:该引脚为低电平有效,即当该引脚为低电平时,A4988将复位。如果该引脚悬空,则A4988默认为高电平。即该引脚没有连接任何电平时,A4988可以正常工作。 SLEEP – 睡眠引脚 引脚说明:当该引脚连接电平为低电平时,A4988将进入低能耗睡眠状态,即消耗最小的电能。如果无需使用SLeep功能,则可以将SLEEP引脚与RESET引脚连接,则A4988将持续保持正常能耗状态而不会进入低能耗状态。 STEP – 步进引脚 引脚说明:此引脚用于通过Arduino等微控制器向A4988发送脉冲控制信号,A4988接收到此信号后,会根据 MS1, MS2 和 MS3引脚控制电机运转。占空比50%。 DIR – 方向引脚 引脚说明:通过此引脚可以调整A4988控制电机运行方向。当此引脚为低电平,A4988将控制电机顺时针旋转。高电平则逆时针旋转。 |
驱动模式:
本次使用的二相步进电机步距角为1.8°,在全步模式下,给STEP一个脉冲信号,电机转动1.8°。半步模式下,一个脉冲信号电机的转动角度为1.8°/2,依次类推。
stm32f103c8t6最小系统;
ST-Link烧录器;
4988步进电机驱动模块;
步进电机驱动控制板;
42步进电机;
12V开关电源;
导线若干;
开发环境:Keil_5
硬件连接模拟图:
如图6为MCU与驱动器和电机的连接示意图,可在面包板上完成接线,外部驱动电源(8-35V)需要在电源正极与负极之间接一个47uF电容保护驱动器。而我在选择电源的时候选择了24V2A开关电源,接线的时候需要讲开关电源的负极与开发板GND连接(共地)。也许是正负极接反了(猜测),导致上电后烧坏驱动器和开发板。
后续使用的驱动芯片为HR4988,将面包板换为控制板(如下图7),控制板的电压要求为9V,在理论上可以接8~32V,但问客服就说只能接9V。最后使用12V1A开关电源给驱动IC供电。
控制板两个GND相连,SLEEP引脚也与RESET引脚连接,MS1、MS2、MS3采用拨动开关设置步进模式。使用控制板的好处就是只需将ENABLE、STEP 、DIR与MCU的IO相连,可节约IO资源(相较于面包板)。
ENABLE | PB3 |
DIR | PB5 |
STEP | PB8 |
控制板5V接开发板5V引脚,控制板GND接开关电源负极与开发板GND,控制板9V接12V开关电源正极。
将PB8设置为复用推挽输出模式,使用定时器4通道3输出PWM,控制电机运转。
- void MOTOR_Init(void)
- {
- //1.引脚初始化
- GPIO_InitTypeDef motor_gpio_init;
- motor_gpio_init.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_3;
- motor_gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
- motor_gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&motor_gpio_init); //DIR ENABLE 通用推挽输出模式
- motor_gpio_init.GPIO_Pin = GPIO_Pin_8;
- motor_gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB,&motor_gpio_init); //STEP 复用推挽输出
-
- //2.定时器初始化配置
- TIM_DeInit(TIM4);
- TIM_TimeBaseInitTypeDef motor_TimeInit;
- motor_TimeInit.TIM_Prescaler = 31; //预分频值
- motor_TimeInit.TIM_ClockDivision = TIM_CKD_DIV1;
- motor_TimeInit.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
- motor_TimeInit.TIM_Period = 3999; //重装载值
- motor_TimeInit.TIM_RepetitionCounter = 0; //重复计数值
- TIM_TimeBaseInit(TIM4,&motor_TimeInit); //基本计数模式
-
- TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //配置更新中断
- TIM_ClearFlag(TIM4,TIM_FLAG_Update); //清除更新中断位
-
- TIM_OCInitTypeDef motor_OCInit;
- TIM_OCStructInit(&motor_OCInit);
- motor_OCInit.TIM_OCMode = TIM_OCMode_PWM1;
- motor_OCInit.TIM_OutputState = TIM_OutputState_Enable;
- motor_OCInit.TIM_Pulse = 1499;
- TIM_OC3Init(TIM4,&motor_OCInit); //配置通道3PWM
- //失能motor
- MOTOR_STOP();
- MOTOR_ENABLE;
- MOTOR_DIR_CW; //顺时针
- //MOTOR_DIR_CCW;
- }
控制电机转动速度就是控制脉冲周期,一个脉冲电机步进一定角度,修改脉冲周期便可控制电机转动速度。
#define SET_MOTOR_SPEED(x) TIM_SetAutoreload(TIM4,x-1);TIM_SetCompare3(TIM2,x/2-1)
通过拨动步进开关,设置为1/16步进模式。实现电机正转一圈反转一圈反复循环。
- void TIM4_IRQHandler(void)
- {
- if(RESET != TIM_GetITStatus(TIM4,TIM_IT_Update))
- {
- TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位
- motor_sleep++;
- if(motor_sleep==3200) //改变转向
- {
- MOTOR_STOP(); //停止运转
- motor_sleep=0;
- motor_dir=!motor_dir;
- if(motor_dir) //顺时针
- {
- MOTOR_DIR_CW;
- MOTOR_START();
- }
- else
- {
- MOTOR_DIR_CCW;
- MOTOR_START();
- }
- }
- }
- }
mian.c
-
- #include "motor.h"
- #include "systick.h"
-
- void clock_config(void);
- void nvic_config(void);
-
- int main(void)
- {
- clock_config(); //配置RCC时钟
- nvic_config(); //配置中断优先级
- MOTOR_Init(); //motor初始化
- MOTOR_START();
- while(1)
- {
-
- }
- }
- void clock_config(void)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
- }
- void NVIC_IQR_Confing(uint8_t nvic_IRQChannel,uint8_t nvic_PreemptionPriority, uint8_t nvic_SubPriority)
- {
- NVIC_InitTypeDef nvic_Init;
- nvic_Init.NVIC_IRQChannel = nvic_IRQChannel;//中断号
- nvic_Init.NVIC_IRQChannelPreemptionPriority = nvic_PreemptionPriority;//抢占优先级
- nvic_Init.NVIC_IRQChannelSubPriority = nvic_SubPriority;//子优先级
- nvic_Init.NVIC_IRQChannelCmd = ENABLE;//启用中断优先级
- NVIC_Init(&nvic_Init);
- }
- void nvic_config(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断优先级分组
- NVIC_IQR_Confing(TIM4_IRQn,1,0);
- }
motor.c
-
-
- #include "motor.h"
- /*
- 引脚连接:
- PB5 - DIR 方向引脚
- PB8 - STEP TIM4_CH3 步进引脚
- PB3 - ENABLE 使能引脚
- */
- uint16_t motor_sleep;
- uint8_t motor_dir=1;
- void MOTOR_Init(void)
- {
- //1.引脚初始化
- GPIO_InitTypeDef motor_gpio_init;
- motor_gpio_init.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_3;
- motor_gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
- motor_gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&motor_gpio_init); //DIR ENABLE 通用推挽输出模式
- motor_gpio_init.GPIO_Pin = GPIO_Pin_8;
- motor_gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOB,&motor_gpio_init); //STEP 复用推挽输出
-
- //2.定时器初始化配置
- TIM_DeInit(TIM4);
- TIM_TimeBaseInitTypeDef motor_TimeInit;
- motor_TimeInit.TIM_Prescaler = 31; //预分频值
- motor_TimeInit.TIM_ClockDivision = TIM_CKD_DIV1;
- motor_TimeInit.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
- motor_TimeInit.TIM_Period = 3999; //重装载值
- motor_TimeInit.TIM_RepetitionCounter = 0; //重复计数值
- TIM_TimeBaseInit(TIM4,&motor_TimeInit); //基本计数模式
-
- TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //配置更新中断
- TIM_ClearFlag(TIM4,TIM_FLAG_Update); //清除更新中断位
-
- TIM_OCInitTypeDef motor_OCInit;
- TIM_OCStructInit(&motor_OCInit);
- motor_OCInit.TIM_OCMode = TIM_OCMode_PWM1;
- motor_OCInit.TIM_OutputState = TIM_OutputState_Enable;
- motor_OCInit.TIM_Pulse = 1499;
- TIM_OC3Init(TIM4,&motor_OCInit); //配置通道3PWM
- //失能motor
- MOTOR_STOP();
- MOTOR_ENABLE;
- MOTOR_DIR_CW; //顺时针
- //MOTOR_DIR_CCW;
- }
-
- //中断服务函数
- void TIM4_IRQHandler(void)
- {
- if(RESET != TIM_GetITStatus(TIM4,TIM_IT_Update))
- {
- TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位
- motor_sleep++;
- if(motor_sleep==3200) //改变转向
- {
- MOTOR_STOP(); //停止运转
- motor_sleep=0;
- motor_dir=!motor_dir;
- if(motor_dir) //顺时针
- {
- MOTOR_DIR_CW;
- MOTOR_START();
- }
- else
- {
- MOTOR_DIR_CCW;
- MOTOR_START();
- }
- }
- }
- }
- /*
- \brief: 设置motor运转速度
- \param: speed: 速度
- 速度=(1/2M) * speed * (1.8/16) 度/秒
- \retval: none
- */
- void MOTOR_Set_Speed(uint16_t speed)
- {
- TIM_SetAutoreload(TIM4,speed-1);
- TIM_SetCompare3(TIM4,speed/2-1);
- }
-
- //设置步进模式 (用于MS1、MS2、MS3与单片机IO连接时使用)
- #if 0
- void setMotorStepMod(uint8_t stepMod)
- {
- switch(StepMode)
- {
- case MOTOR_FULL_STEP:
- MOTOR_MS1(0);
- MOTOR_MS2(0);
- MOTOR_MS3(0);
- break;
- case MOTOR_HALF_STEP:
- MOTOR_MS1(1);
- MOTOR_MS2(0);
- MOTOR_MS3(0);
- break;
- case MOTOR_QUARTER_STEP:
- MOTOR_MS1(0);
- MOTOR_MS2(1);
- MOTOR_MS3(0);
- break;
- case MOTOR_EIGHTH_STEP:
- MOTOR_MS1(1);
- MOTOR_MS2(1);
- MOTOR_MS3(0);
- break;
- case MOTOR_SIXTEENTH_STEP:
- MOTOR_MS1(1);
- MOTOR_MS2(1);
- MOTOR_MS3(1);
- break;
- default :
- MOTOR_MS1(1);
- MOTOR_MS2(1);
- MOTOR_MS3(1);
- break;
- }
- }
- #endif
motor.h
- #ifndef _MOTOR_H_
- #define _MOTOR_H_
-
- #include "stm32f10x.h"
-
- #define MOTOR_DIR_CW GPIO_ResetBits(GPIOB,GPIO_Pin_5) //顺时针
- #define MOTOR_DIR_CCW GPIO_SetBits(GPIOB,GPIO_Pin_5) //逆时针
- #define MOTOR_ENABLE GPIO_ResetBits(GPIOB,GPIO_Pin_3)
- #define MOTOR_STOP() TIM_Cmd(TIM4,DISABLE) //停止转动
- #define MOTOR_START() TIM_Cmd(TIM4,ENABLE) //开始转动
-
- #define MOTOR_FULL_STEP 0 //满步
- #define MOTOR_HALF_STEP 1 //二分之一步
- #define MOTOR_QUARTER_STEP 2 //四分之一步
- #define MOTOR_EIGHTH_STEP 3 //八分之一步
- #define MOTOR_SIXTEENTH_STEP 4 //十六分之一步
-
- extern uint8_t motor_dir;
-
- void MOTOR_Init(void);
- void MOTOR_Set_Speed(uint16_t speed);
-
- #endif
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。