stm32 42步进电机 上位机示例

脉冲到底是个啥东西?步进电机一直说发脉冲
步进电机通过接收脉冲信号来实现精确的位置控制。脉冲是一种短暂的电信号,它的变化可以触发步进电机转动一定的角度或步进。步进电机控制系统会根据输入的脉冲信号来精确定位和控制步进电机的转动,每个脉冲信号通常对应步进电机转动的一个固定的步进角度。

简单来说,当步进电机需要转动时,控制系统会发送一系列脉冲信号给步进电机,每个脉冲信号对应步进电机转动的一个步进角度。通过控制脉冲信号的频率和数量,可以精确地控制步进电机的转动,从而实现精准的位置控制和运动控制。

步进电机的相数是干嘛的,比如;两相是啥意思
步进电机的相数指的是步进电机的驱动方式中使用的线圈数量。常见的步进电机有两相、三相、四相和五相等不同的相数。

在两相步进电机中,驱动方式包含两个线圈(也称为相),每个线圈独立控制一个电机极性。两相步进电机通过交替激活这两个线圈来实现转动。具体来说,当一个线圈通电时,它会产生一个磁场,将电机转子吸引到对应位置;当另一个线圈通电时,前一个线圈的磁场会减弱,电机转子会被吸引到新的位置。通过交替激活两个线圈,可以实现步进电机的转动。

两相步进电机相对简单,结构紧凑,成本较低,广泛应用于一些低要求的应用领域。然而,由于只有两个线圈,步进角度较大,精度相对较低。

其他相数的步进电机,如三相、四相和五相步进电机,通过增加线圈的数量来提高步进角度的精度。随着相数的增加,步进电机的转动变得更加平滑和精确,但同时也增加了电机结构的复杂性和成本。

实物图:
在这里插入图片描述
上位机Qt软件图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路就是stm32一直给步进电机发脉冲,然后通过驱动器驱动步进电机转动,这个项目多了一个qt发送串口消息给stm32,stm32接收对应的命令然后执行不同的函数,但是这样无法实现步进电机的反馈,无法实现限位,回零等功能。
不过目前可以实现步进电机转动度数的控制,因为实物没负载也没测试有没有丢步的现象,还能实现正反转
stm32主要代码:
Motor.h:

#ifndef __MOTOR_H
#define __MOTOR_Hvoid Motor_Init(void);
void Motor_Run(uint32_t dir,uint32_t num,uint32_t speed);
void Motor_RunDegree(uint32_t dir,uint32_t degree,uint32_t speed);#endif

Motor.cpp:

#include "stm32f10x.h"
#include "Delay.h"void Motor_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIOA的时钟GPIO_InitTypeDef  GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3;  //PA5->EN;PA4->DIR;PA3->PWMGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA, GPIO_Pin_5 | GPIO_Pin_4| GPIO_Pin_3);	
}void Motor_Run(uint32_t dir,uint32_t num,uint32_t speed)  
{if(dir==1){GPIO_SetBits(GPIOA, GPIO_Pin_4);		}if(dir==0){GPIO_ResetBits(GPIOA, GPIO_Pin_4);			}for(uint32_t i=0;i<=(num*3200);i++) {		Delay_us(speed);                   GPIOA->ODR ^= GPIO_Pin_3;  				}	
}void Motor_RunDegree(uint32_t dir,uint32_t degree,uint32_t speed)  
{if(dir==1){GPIO_SetBits(GPIOA, GPIO_Pin_4);		}if(dir==0){GPIO_ResetBits(GPIOA, GPIO_Pin_4);			}for(uint32_t i=0;i<=degree;i++) {		Delay_us(speed);                   GPIOA->ODR ^= GPIO_Pin_3;  				}	
}

main.c:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Serial.h"
#include "string.h"
#include "Motor.h"int main(void){Serial_Init();Motor_Init();while (1){if (Serial_RxFlag == 1){if (strcmp(Serial_RxPacket, "1") == 0){GPIO_SetBits(GPIOA, GPIO_Pin_5);}else if (strcmp(Serial_RxPacket, "3") == 0){Motor_RunDegree(1,800,360);}else if (strcmp(Serial_RxPacket, "4") == 0){Motor_RunDegree(0,800,360);}else if (strcmp(Serial_RxPacket, "5") == 0){Motor_Run(1,1,300);}else if (strcmp(Serial_RxPacket, "6") == 0){Motor_Run(0,1,300);}else if (strcmp(Serial_RxPacket, "7") == 0){Motor_Run(1,1,400);}else if (strcmp(Serial_RxPacket, "8") == 0){Motor_Run(0,1,400);}else if (strcmp(Serial_RxPacket, "9") == 0){Motor_Run(1,1,500);}else if (strcmp(Serial_RxPacket, "10") == 0){Motor_Run(0,1,500);}else if (strcmp(Serial_RxPacket, "11") == 0){Motor_Run(1,2,300);}else if (strcmp(Serial_RxPacket, "12") == 0){Motor_Run(0,2,300);}else if (strcmp(Serial_RxPacket, "2") == 0){GPIO_ResetBits(GPIOA, GPIO_Pin_5);    }Serial_RxFlag = 0;}}
}

Qt的主要代码:

#include "widget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>//角度实时波形显示
Widget::Widget(QWidget *parent): QWidget(parent)
{portSteepr=new Port(this);InitWidget();InitSignalAndSlot();ButtonDisabled();
}Widget::~Widget(){}void Widget::InitWidget()
{setFixedSize(QSize(1200,800));LabelStatus=new QLabel(this);LabelStatus->move(100,200);PushButtonOpenDevice=new QPushButton(this);PushButtonOpenDevice->setText(tr("open device"));PushButtonOpenDevice->setFixedSize(120,60);PushButtonCloseDevice=new QPushButton(this);PushButtonCloseDevice->setText(tr("close device"));PushButtonCloseDevice->setFixedSize(120,60);PushButtonAdvance=new QPushButton(this);PushButtonAdvance->setText(tr("advance"));PushButtonAdvance->setFixedSize(120,60);PushButtonBackOff=new QPushButton(this);PushButtonBackOff->setText(tr("backoff"));PushButtonBackOff->setFixedSize(120,60);PushButton11300=new QPushButton(this);PushButton11300->setText(tr("pushbutton11300"));PushButton11300->setFixedSize(120,60);PushButton01300=new QPushButton(this);PushButton01300->setText(tr("pushbutton01300"));PushButton01300->setFixedSize(120,60);PushButton11400=new QPushButton(this);PushButton11400->setText(tr("pushbutton11400"));PushButton11400->setFixedSize(120,60);PushButton01400=new QPushButton(this);PushButton01400->setText(tr("pushbutton01400"));PushButton01400->setFixedSize(120,60);PushButton11500=new QPushButton(this);PushButton11500->setText(tr("pushbutton11500"));PushButton11500->setFixedSize(120,60);PushButton01500=new QPushButton(this);PushButton01500->setText(tr("pushbutton01500"));PushButton01500->setFixedSize(120,60);PushButton12300=new QPushButton(this);PushButton12300->setText(tr("pushbutton12300"));PushButton12300->setFixedSize(120,60);PushButton02300=new QPushButton(this);PushButton02300->setText(tr("pushbutton02300"));PushButton02300->setFixedSize(120,60);QVBoxLayout* vlayout1=new QVBoxLayout;QHBoxLayout* hlayout1=new QHBoxLayout;hlayout1->addWidget(PushButtonOpenDevice);hlayout1->addWidget(PushButtonCloseDevice);QHBoxLayout* hlayout2=new QHBoxLayout;hlayout2->addWidget(PushButtonAdvance);hlayout2->addWidget(PushButtonBackOff);QHBoxLayout* hlayout3=new QHBoxLayout;hlayout3->addWidget(PushButton01300);hlayout3->addWidget(PushButton11300);QHBoxLayout* hlayout4=new QHBoxLayout;hlayout4->addWidget(PushButton01400);hlayout4->addWidget(PushButton11400);QHBoxLayout* hlayout5=new QHBoxLayout;hlayout5->addWidget(PushButton01500);hlayout5->addWidget(PushButton11500);QHBoxLayout* hlayout6=new QHBoxLayout;hlayout6->addWidget(PushButton02300);hlayout6->addWidget(PushButton12300);vlayout1->addLayout(hlayout1);vlayout1->addLayout(hlayout2);vlayout1->addLayout(hlayout3);vlayout1->addLayout(hlayout4);vlayout1->addLayout(hlayout5);vlayout1->addLayout(hlayout6);setLayout(vlayout1);}void Widget::InitSignalAndSlot()
{connect(PushButtonOpenDevice,&QPushButton::clicked,this,&Widget::slotOpenDevice);connect(PushButtonCloseDevice,&QPushButton::clicked,this,&Widget::slotCloseDevice);connect(PushButtonAdvance,&QPushButton::clicked,this,&Widget::slotDriverSteeprAdvance);connect(PushButtonBackOff,&QPushButton::clicked,this,&Widget::slotDriverSteeprBackOff);connect(PushButton01300,&QPushButton::clicked,[=]{portSteepr->DriverSteeprMotor01300();});connect(PushButton11300,&QPushButton::clicked,[=]{portSteepr->DriverSteeprMotor11300();});connect(PushButton01400,&QPushButton::clicked,[=]{portSteepr->DriverSteeprMotor01400();});connect(PushButton11400,&QPushButton::clicked,[=]{portSteepr->DriverSteeprMotor11400();});connect(PushButton01500,&QPushButton::clicked,[=]{portSteepr->DriverSteeprMotor01500();});connect(PushButton11500,&QPushButton::clicked,[=]{portSteepr->DriverSteeprMotor11500();});connect(PushButton02300,&QPushButton::clicked,[=]{ButtonDisabled();portSteepr->DriverSteeprMotor02300();ButtonEnabled();});connect(PushButton12300,&QPushButton::clicked,[=]{portSteepr->DriverSteeprMotor12300();});
}void Widget::slotOpenDevice()
{ButtonEnabled();portSteepr->EnableSteepr();
}void Widget::slotCloseDevice()
{ButtonDisabled();portSteepr->DisEnableSteepr();
}void Widget::slotDriverSteeprAdvance()
{portSteepr->DriverSteeprAdvance();
}void Widget::slotDriverSteeprBackOff()
{portSteepr->DriverSteeprBackOff();
}void Widget::ButtonDisabled()
{PushButtonAdvance->setEnabled(false);PushButtonBackOff->setEnabled(false);PushButton01300->setEnabled(false);PushButton11300->setEnabled(false);PushButton01400->setEnabled(false);PushButton11400->setEnabled(false);PushButton01500->setEnabled(false);PushButton11500->setEnabled(false);PushButton02300->setEnabled(false);PushButton12300->setEnabled(false);
}void Widget::ButtonEnabled()
{PushButtonAdvance->setEnabled(true);PushButtonBackOff->setEnabled(true);PushButton01300->setEnabled(true);PushButton11300->setEnabled(true);PushButton01400->setEnabled(true);PushButton11400->setEnabled(true);PushButton01500->setEnabled(true);PushButton11500->setEnabled(true);PushButton02300->setEnabled(true);PushButton12300->setEnabled(true);}

然后是接线:
采用共阳极接线法:
PUL+ ENA+ DIR+接3.3V,ENA-接A5 DIR-接A4 PUL-接A3 然后USB转TTL接线 RX接A9 TX接A10
在这里插入图片描述
注意事项:
电机如果发热严重记得调节拨码开关的电流

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

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

相关文章

YOLOv8 训练自己的分割数据集

之前写过一篇 使用YOLOv8训练自己的【目标检测】数据集-【收集数据集】-【标注数据集】-【划分数据集】-【配置训练环境】-【训练模型】-【评估模型】-【导出模型】&#xff0c;里面带大家整个流程走过一遍了&#xff0c; 这篇文章我们来介绍如何使用 YOLOv8 训练分割数据集&a…

Linux篇:文件系统

一、共识原理&#xff1a; 文件文件内容文件属性 磁盘上存储文件存文件的内容&#xff08;数据块&#xff09;存文件的属性&#xff08;inode&#xff09; Linux的文件在磁盘中存储是将属性和内容分开存储的。 二、硬件简述&#xff1a; 1. 认识硬件 磁盘&#xff1a;唯一的一…

LabVIEW绘制带有多个不同标尺的波形图

LabVIEW绘制带有多个不同标尺的波形图 通过在同一波形图上使用多个轴&#xff0c;可以使用不同的标尺绘制数据。请按照以下步骤操作。 将波形图或图表控件放在前面板上。 1. 右键点击您要创建多个标尺的轴&#xff0c;然后选择复制标尺。例如&#xff0c;如果要为一个…

文件搜索工具HoudahSpot mac中文版特点

HoudahSpot mac是一款文件搜索工具&#xff0c;它可以帮助用户快速准确地找到文件和文件夹&#xff0c;支持高级搜索和过滤&#xff0c;同时提供了多种视图和操作选项&#xff0c;方便用户进行文件管理和整理。 HoudahSpot mac软件特点 高级搜索和过滤功能&#xff1a;软件支持…

手把手教会你--github的学习--持续更新

有什么问题&#xff0c;请尽情问博主&#xff0c;QQ群796141573 前言1.1 使用过程(1) 进入某个项目(2) 点击某个文件(3) 在源码区域下面(4) 源码区的头顶上 1.2 作者的其他项目1.3 搜索1.4 复制别人的代码(即项目)到自己的空间内1.5 上传自己的Bugs(bushi1.6 在线修改文件1.7 评…

【非监督学习 | 聚类】聚类算法类别大全 距离度量单位大全

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

JPA 自关联 设置单向多对一

Spring boot 3 JPA中&#xff0c;遇到一个需求&#xff0c;建一个数据字典表&#xff1a; Dictionary&#xff0c;存放两级数据&#xff0c;第一级为字典项目&#xff0c;第二级为项目内容&#xff0c;查询时要把parent_id对应父项的名称也一起查出来&#xff0c;返回前端。 …

Project DESFT 白皮书中文版——应用于普惠金融的可信数字凭证解决方案

1. 概述 Project DESFT 是由 Solv 基金会与 zCloak Network 联合设计孵化&#xff0c;以跨境贸易和金融服务为场景的分布式可信数字凭证解决方案&#xff08;Distributed Trusted Digital Credential Solution&#xff09;&#xff0c;项目获得新加坡金管局&#xff08;Monetar…

C++学习之路(四)C++ 实现简单的待办事项列表命令行应用 - 示例代码拆分讲解

本期示例介绍: 本期示例《待办事项列表应用》展示了一个简单的任务管理系统&#xff0c;用户可以通过命令行界面执行添加任务、删除任务和显示任务列表等操作。 功能描述&#xff1a; 添加任务功能&#xff1a; 用户可以输入任务描述&#xff0c;将新的任务添加到任务列表中。…

声音响度、声压级计权(A B C)实现

声压 sound pressure 声压就是大气压受到声波扰动后产生的变化&#xff0c;即为大气压强的余压&#xff0c;它相当于在大气压强上的叠加一个声波扰动引起的压强变化。由于声压的测量比较容易实现&#xff0c;通过声压的测量也可以间接求得质点速度等其它物理量&#xff0c;所以…

【开源】基于JAVA的天然气工程业务管理系统

项目编号&#xff1a; S 021 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S021&#xff0c;文末获取源码。} 项目编号&#xff1a;S021&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、使用角色3.1 施工人员3.2 管理员 四…

手把手教会你--渗透实战--Hack The Box-Starting Point-Meow--持续更新

有什么问题&#xff0c;请尽情问博主&#xff0c;QQ群796141573 前言 前言 请务必跟着博主复现一遍 参考&#xff1a; Hack The Box-Starting Point-Meow

pygame加载图像,并让小球做平抛运动

文章目录 load转换和存储自由落体 在游戏设计中&#xff0c;图像显示是必不可少的功能&#xff0c;pygame中的image模块便用于加载图像。 load 通过load函数&#xff0c;可以加载多种图像格式&#xff0c;如下表所示 旧版本bmp, gpeg, png, pcx, tiff, xpmc, lbm(以及pbm, p…

windows下docker环境搭建与运行实战

背景 学习docker使用&#xff0c;需要环境&#xff0c;今天主要的目标是在windows环境下安装docker环境。 为什么要这么搞&#xff0c;主要是企业内部服务器&#xff0c;都是跟公网隔离的&#xff0c;没有访问公网权限&#xff0c;所以镜像什么的&#xff0c;从公网拉取完全没…

卷积神经网络(Inception-ResNet-v2)交通标志识别

文章目录 一、前言二、前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;2. 导入数据3. 查看数据 二、构建一个tf.data.Dataset1.加载数据2. 配置数据集 三、构建Inception-ResNet-v2网络1.自己搭建2.官方模型 五、设置动态学习率六、训练模型七、模型评…

rust tokio select!宏详解

rust tokio select!宏详解 简介 本文介绍Tokio中select!的用法&#xff0c;重点是使用过程中可能遇到的问题&#xff0c;比如阻塞问题、优先级问题、cancel safe问题。在Tokio 中&#xff0c;select! 是一个宏&#xff0c;用于同时等待多个异步任务&#xff0c;并在其中任意一…

探索 Vue 中的 bus.$emit:实现组件通信的强大工具

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

运维高级--centos7源码安装Apache

安装必要的依赖项&#xff1a; sudo yum groupinstall "Development Tools" sudo yum install pcre pcre-devel zlib zlib-devel openssl openssl-devel这将安装编译和构建所需的基本工具&#xff0c;以及 Apache HTTP Server 所需的一些依赖项。 下载 Apache HTT…

Pycharm Available Packages显示Noting to show

使用Pycharm安装依赖包时Available packages 页面点击添加按钮后,没有任何包显示,并且无法搜索安装. 在各种网站查看到的方法如下: 1.网络问题,需要添加镜像源 点击Manage Repositories 添加一个可用的镜像源地址即可 2.打开了anaconda(那个绿色圈圈小图标),再点一下把它点…

如何在 Vim 中剪切、复制和粘贴

目录 前言 如何在 Vim 编辑器中复制文本 如何在 Vim 编辑器中剪切文本 如何在 Vim 编辑器中粘贴文本 如何通过选择文本来剪切和复制文本 通过选择文本复制 在 Vim 中选择文本来剪切文本 前言 在本篇 Vim 快速技巧中&#xff0c;你将学习到剪切和复制粘贴的相关知识。 剪…