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);  /* 清除定时器溢出中断标志位 */
    }
}

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2023-12-09 08:46:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-09 08:46:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-09 08:46:04       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-09 08:46:04       20 阅读

热门阅读

  1. 代码随想录 62. 不同路径

    2023-12-09 08:46:04       37 阅读
  2. 给鼠标描述符打上注释防止忘记

    2023-12-09 08:46:04       32 阅读
  3. DETR 目标检测

    2023-12-09 08:46:04       35 阅读
  4. c 语言常用的加密算法——MD5

    2023-12-09 08:46:04       42 阅读
  5. UDP群聊

    UDP群聊

    2023-12-09 08:46:04      36 阅读
  6. Jenkins安装

    2023-12-09 08:46:04       46 阅读
  7. 达梦(主备)搭建

    2023-12-09 08:46:04       29 阅读
  8. WPF(Windows Presentation Foundation)的 ToolBar控件

    2023-12-09 08:46:04       39 阅读
  9. 个人简介(非学习类笔记)

    2023-12-09 08:46:04       41 阅读