28BYJ-48步进电机的驱动

news2024/10/7 17:37:12

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1296807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IBM Qiskit量子机器学习速成(四)

量子核机器学习 一般步骤 量子核机器学习的一般步骤如下 定义量子核 我们使用FidelityQuantumKernel类创建量子核,该类需要传入两个参数:特征映射和忠诚度(fidelity)。如果我们不传入忠诚度,该类会自动创建一个忠诚度。 注意各个类所属的…

leaflet:经纬度坐标转为地址,点击鼠标显示地址信息(137)

第137个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中将经纬度坐标转化为地址,点击鼠标显示某地的地址信息 。主要利用mapbox的api将坐标转化为地址,然后在固定的位置显示出来。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果 文章目录 示…

UniDBGrid序号列添加标题

有人想要在UniDBGrid的序号列加上标题,就是这里 可以使用如下代码 UniSession.AddJS(MainForm.UniDBGrid1.columnManager.columns[0].setText("序号"));

VMware安装Ubuntu20.04并使用Xshell连接虚拟机

文章目录 虚拟机环境准备重置虚拟网络适配器属性(可选)配置NAT模式的静态IP创建虚拟机虚拟机安装配置 Xshell连接虚拟机 虚拟机环境准备 VMware WorkStation Pro 17.5:https://customerconnect.vmware.com/cn/downloads/details?downloadGr…

样本数量对问卷信度效度分析的影响及应对策略

问卷调研是一种常见的数据收集方法。明确问卷的真实性和效率是保证其靠谱性和有效性的重要一步。但问卷的真实性和品质会受到样本数量的影响吗? 一、问卷信度的认识 1、信度的概念和重要性:在问卷实验中,信度是指问卷测量值的稳定性和一致性。高信度代…

go grpc高级用法

文章目录 错误处理常规用法进阶用法原理 多路复用元数据负载均衡压缩数据 错误处理 gRPC 一般不在 message 中定义错误。毕竟每个 gRPC 服务本身就带一个 error 的返回值,这是用来传输错误的专用通道。gRPC 中所有的错误返回都应该是 nil 或者 由 status.Status 产…

希尔排序详解:一种高效的排序方法

在探索排序算法的世界中,我们经常遇到需要对大量数据进行排序的情况。传统的插入排序虽然简单,但在处理大规模数据时效率并不高。这时,希尔排序(Shell Sort)就显得尤为重要。本文将通过深入解析希尔排序的逻辑&#xf…

分享十几个适合新手练习的软件测试项目

说实话,在找项目的过程中,我下载过(甚至付费下载过)N多个项目、联系过很多项目的作者,但是绝大部分项目,在我看来,并不适合你拿来练习,它们或多或少都存在着“问题”,比如…

编写一个程序, 给出两个时间,计算出两个时间之差,如给出1120表示11:20,1330表示13:30, 将时间间隔以分钟为单位输出。

如下: #include<stdio.h>int main(){int a,b;printf("请输入第一个时间a:");scanf("%d",&a);printf("请输入第二个时间b:");scanf("%d",&b);int hour1a/100;//取小时int minute1a%100;//取分钟int hour2b/100;int minu…

HCIP --- BGP 基础 (中)

BGP的数据包 Open、Update、Notification、Keepalive、Route-refresh BGP的公共头部 Marker &#xff1a;标记 &#xff08;可以兼容字段、版本&#xff09; 全F Length&#xff1a; 标明数据包多长多大 Type&#xff1a;表明数据包类型&#xff08;可选 12345&#xff09; …

如何切换用户和更改用户密码

https://blog.csdn.net/u012759006/article/details/89681615 https://blog.csdn.net/Z_CAIGOU/article/details/120925716 1、sudo su 切换到root用户 2、passwd 用户名 之后输入你修改后的密码两次&#xff0c;成功。 文章知识点与官方知识档案匹配&#xff0c;可 一般情…

C语言 扫雷游戏

代码在一个项目里完成&#xff0c;分成三个.c.h文件(game.c,game.h,main.c) 在Clion软件中通过运行调试。 /大概想法/ 主函数main.c里是大框架(菜单,扫雷棋盘初始化&#xff0c;随机函数生成雷&#xff0c;玩家扫雷) game.h函数声明(除main函数和游戏函数外的一些函数声明) ga…

Kafka安全性探究:构建可信赖的分布式消息系统

在本文中&#xff0c;将研究Kafka的安全性&#xff0c;探讨如何确保数据在传输和存储过程中的完整性、机密性以及授权访问。通过详实的示例代码&#xff0c;全面讨论Kafka安全性的各个方面&#xff0c;从加密通信到访问控制&#xff0c;帮助大家构建一个可信赖的分布式消息系统…

品牌控价成本如何把控

品牌在发展&#xff0c;价格就需要持续关注&#xff0c;当出现乱价、低价、窜货时就应投入人力去治理&#xff0c;但企业生存&#xff0c;还要考虑成本&#xff0c;如何在保证控价效果的基础上&#xff0c;做到使用最低成本呢&#xff0c;这些问题除了控价本身外&#xff0c;也…

苹果IOS在Safari浏览器中将网页添加到主屏幕做伪Web App,自定义图标,启动动画,自定义名称,全屏应用pwa

在ios中我们可以使用Safari浏览自带的将网页添加到主屏幕上&#xff0c;让我们的web页面看起来像一个本地应用程序一样&#xff0c;通过桌面APP图标一打开&#xff0c;直接全屏展示&#xff0c;就像在APP中效果一样&#xff0c;完全体会不到你是在浏览器中。 1.网站添加样式 在…

去掉手机端顶部间隙

Unigui手机端打开时&#xff0c;在顶部有一条白色间隙 使用以下方法可以去除间隙 在ServerModule的customcss里添加以下代码 body{ margin:0!important; padding:0!important; }

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《考虑垃圾处理与调峰需求的可持续化城市多能源系统规划》

这个标题涵盖了城市多能源系统规划中的两个重要方面&#xff1a;垃圾处理和调峰需求&#xff0c;并强调了规划的可持续性。 考虑垃圾处理&#xff1a; 含义&#xff1a; 垃圾处理指的是城市废弃物的管理和处置。这可能涉及到废物分类、回收利用、焚烧或填埋等方法。重要性&…

使用pyftpdlib组件实现FTP文件共享

目录 一、引言 二、技术背景 三、实现逻辑 1、创建FTP服务器&#xff1a; 2、实现文件共享&#xff1a; 3、设置用户权限&#xff1a; 4、处理异常&#xff1a; 5、优化与扩展&#xff1a; 四、代码实现 五、测试与评估 测试用例&#xff1a; 评估方法&#xff1a;…

ubuntu22.04安装 nvidia-cudnn

nvidia-cudnn 是 NVIDIA CUDA 深度神经网络库&#xff08;CUDA Deep Neural Network library&#xff09;的缩写。这是一个由 NVIDIA 提供的库&#xff0c;用于加速深度学习应用程序。它包含了针对深度神经网络中常用操作&#xff08;如卷积、池化、归一化、激活层等&#xff0…

gcc tips - GCC使用技巧与高级特性

目录 1. 获取 GCC 编译器预定义的宏 2. 列出依赖的头文件 3. 保存预处理结果到文件&#xff08;展开define, 展开include header&#xff09; 4. 写回调跟踪记录函数运行 -finstrument-functions 5. -fdump-rtl-expand 画函数调用关系图 GCC&#xff0c;全称GNU Compiler …