28BYJ-48步进电机的驱动

ULN2003的工作原理

28BYJ48可以用ULN2003来驱动,STM32使用开漏模式外接5V上拉电阻也可以产生5V电压,为什么不直接使用单片机的

GPIO来驱动的原因是虽然电压符合电机的驱动要求,但单片机引脚产生的驱动电流太小,因此驱动步进电机要使用专门的电机驱动模块来进行驱动

IN1、IN2、IN3、IN4分别接STM32的4个GPIO引脚,用4个引脚要控制驱动模块。

具体驱动程序

stepmotor.h

#ifndef     __STEPPING_MOTOR_H
#define     __STEPPING_MOTOR_H



#include "./SYSTEM/sys/sys.h"
/******************************************************************************************/
/* MOTOR IO操作函数 定义 */





#define MOTOR_A        GPIO_PIN_3
#define MOTOR_B        GPIO_PIN_4
#define MOTOR_C        GPIO_PIN_5
#define MOTOR_D        GPIO_PIN_6


#define MOTOR_A_H      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_SET)
#define MOTOR_A_L      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_3, GPIO_PIN_RESET)
#define MOTOR_B_H      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_4, GPIO_PIN_SET)
#define MOTOR_B_L      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_4, GPIO_PIN_RESET)
#define MOTOR_C_H      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_5, GPIO_PIN_SET)
#define MOTOR_C_L      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_5, GPIO_PIN_RESET)
#define MOTOR_D_H      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_SET)
#define MOTOR_D_L      HAL_GPIO_WritePin(GPIOG, GPIO_PIN_6, GPIO_PIN_RESET)



/******************************************************************************************/
/* MOTOR 函数 定义 */                    

void StepMotor_init(void);
void StepMotor_Move(uint8_t dir);
void StepMotor_Stop(void);




#endif

stepmotor.c

#include "./BSP/STEPPING_MOTOR/stepping_motor.h"
#include "./SYSTEM/delay/delay.h"

//此程序用来控制步进电机旋转固定角度后停下来。
//设置定时器的PSC和ARR可以控制步进电机运行的频率/速度
//此程序利用定时器更新中断和静态变量的方法使主程序中某一时刻置标志位后就使电机旋转固定角度。
extern uint8_t lastmove;   //lastmove=0电机正转一定角度,lastmove=1电机反转一定角度
TIM_HandleTypeDef g_tim_handle;
extern uint32_t pulse;     //设置要转的角度(运行多少个脉冲数量),每个脉冲转5.625/64度
void StepMotor_init(void)
{
    __HAL_RCC_GPIOG_CLK_ENABLE();
    __HAL_RCC_TIM2_CLK_ENABLE();
    

    GPIO_InitTypeDef gpio_struct;
    
    gpio_struct.Pin = MOTOR_A | MOTOR_B | MOTOR_C | MOTOR_D;
    gpio_struct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出
    gpio_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(GPIOC, &gpio_struct);
    
    g_tim_handle.Instance = TIM1;
    g_tim_handle.Init.Prescaler = 19;
    g_tim_handle.Init.Period = 7199;
    g_tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
    HAL_TIM_Base_Init(&g_tim_handle);
    
    HAL_NVIC_SetPriority(TIM1_UP_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(TIM1_UP_IRQn);
    HAL_TIM_Base_Start_IT(&g_tim_handle);
    //HAL_TIM_Base_Stop_IT(&g_tim_handle);
}


//步进电机驱动函数:     dir:1表示电机正转;0表示反转
void StepMotor_Move(uint8_t dir)
{
    static uint8_t step = 0;
    if(dir == 0)
    {
        if(step == 0)
            step = 8;
        step--;
    }
    if(0 == step)
    {
        MOTOR_A_H;
        MOTOR_B_L;
        MOTOR_C_L;
        MOTOR_D_L;
    }
    else if(1 == step)
    {
        MOTOR_A_H;
        MOTOR_B_H;
        MOTOR_C_L;
        MOTOR_D_L;
    }
    else if(2 == step)
    {
        MOTOR_A_L;
        MOTOR_B_H;
        MOTOR_C_L;
        MOTOR_D_L;
    }
    else if(3 == step)
    {
        MOTOR_A_L;
        MOTOR_B_H;
        MOTOR_C_H;
        MOTOR_D_L;
    }
    else if(4 == step)
    {
        MOTOR_A_L;
        MOTOR_B_L;
        MOTOR_C_H;
        MOTOR_D_L;
    }
    else if(5 == step)
    {
        MOTOR_A_L;
        MOTOR_B_L;
        MOTOR_C_H;
        MOTOR_D_H;
    }
    else if(6 == step)
    {
        MOTOR_A_L;
        MOTOR_B_L;
        MOTOR_C_L;
        MOTOR_D_H;
    }
    else if(7 == step)
    {
        MOTOR_A_H;
        MOTOR_B_L;
        MOTOR_C_L;
        MOTOR_D_H;
    }
    if(dir == 1)
    {
        step++;
        if(step == 8)
        {
            step = 0;
        }
    }
}


void StepMotor_Stop(void)
{
    MOTOR_A_L;
    MOTOR_B_L;
    MOTOR_C_L;
    MOTOR_D_L;
}


void TIM1_UP_IRQHandler(void)
{
    /* 以下代码没有使用定时器HAL库共用处理函数来处理,而是直接通过判断中断标志位的方式 */
    if(__HAL_TIM_GET_FLAG(&g_tim_handle, TIM_FLAG_UPDATE) != RESET)
    {
        static uint32_t i = 0;
        i++;
        if(lastmove == 0)
        {
            StepMotor_Move(1);
            if(i > pulse)
            {
                StepMotor_Stop();
                lastmove = 2;
                i = 0;
            }
        }
        else if(lastmove == 2)
        {
            i = 0;
            StepMotor_Stop();
        }
        else if(lastmove == 1)
        {
            StepMotor_Move(0);
            if(i > pulse)
            {
                StepMotor_Stop();
                lastmove = 2;
                i = 0;
                //HAL_TIM_Base_Stop_IT(&g_tim_handle);
            }
        }
        __HAL_TIM_CLEAR_IT(&g_tim_handle, TIM_IT_UPDATE);  /* 清除定时器溢出中断标志位 */
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值