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.hqwc.cn/news/219300.html

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

相关文章

HTTP状态码:404 Not Found错误之谜

文章目录 HTTP 404 Not Found错误 404出现形式导致 HTTP 404 错误的原因&#xff1f;推荐阅读 HTTP 404 Not Found 错误 404&#xff0c;也称为“HTTP 404 Not Found”&#xff0c;是当无法找到所请求的资源时 Web 服务器返回的HTTP 状态代码。 简单来说&#xff0c;这意味着…

【Spring篇】spring核心——AOP面向切面编程

目录 想要彻底理解AOP&#xff0c;我觉得你的先要了解框架的模块化思想&#xff0c;为此先记录框架在讲AOP 什么是java框架&#xff1f;为什么要出现框架&#xff1f; 我总结以下七点来讲述和帮助理解java框架思想 什么是AOP&#xff1f; 如何理解上面这句话呢&#xff1…

提示工程-Prompt Engineering

提示工程 提示工程 1、概述 Prompt Engineering&#xff1a; 提示工程 通过自然语言&#xff08;英语、汉语等&#xff09;来给AI下达指示&#xff0c;从而让AI完成你指定给他的工作的过程都可以称之为提示工程。&#xff08;面向自然语言编程&#xff09; 提示词要素 指令&…

华硕V4050E笔记本安装Win10不识别硬盘解决方法

笔记本硬件参数&#xff1a; ASUS VivoBook14 V4050E 型 号 V4050EP1135-0DAKXQ2X10 制造日期 2020-12 12M C P U 11th Gen Intel(R)Core(TM)i5-1135G72.4GHz 2.42GHz 4核心 8线程 L2&#xff1a;5MB L3&#xff1a;8MB 内 存 16.0GB &#xff08;8Gb X2 320…

显示器校准软件BetterDisplay Pro mac中文版介绍

BetterDisplay Pro mac是一款显示器校准软件&#xff0c;可以帮助用户调整显示器的颜色和亮度&#xff0c;以获得更加真实、清晰和舒适的视觉体验。 BetterDisplay Pro mac软件特点 - 显示器校准&#xff1a;可以根据不同的需求和环境条件调整显示器的颜色、亮度和对比度等参数…

BeanUtil的正确使用方式

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 在实际的开发中&#xff0c;我们常常会用到工具类去拷贝对象的属性&#xff0c;将一个对象的属性转换成另外一个…

【21年扬大真题】编写程序,通过指针p的改变,实现一维数组的输入及逆序输出

【21年扬大真题】编写程序&#xff0c;通过指针p的改变&#xff0c;实现一维数组的输入及逆序输出 例如&#xff0c;输入为1,2,3,4,5,6,7&#xff1b; 输出为7,6,5,4,3,2,1 法一&#xff1a;不改变原数组&#xff0c;仅逆序打印输出 #define _CRT_SECURE_NO_WARNINGS #includ…

Linux服务器SSH客户端断开后保持程序继续运行的方法

目录 1. nohup 命令&#xff1a; 2. tmux 或 screen&#xff1a; 3 final shell 断开后服务器如何继续执行令&#xff1f; 方法一&#xff1a;使用 nohup 命令 方法二&#xff1a;将命令放在后台执行 4 你可以使用 jobs 命令查看当前终端中正在后台运行的任务 &#xff…

rsyslog出现Unit rsyslog.service is masked不可用问题解决

博主在测试将日志发送到日志服务器的功能时遇到了rsyslog服务不可用的问题&#xff0c;具体来说&#xff0c;就是执行systemctl restart rsyslog或者 service rsyslog restart命令时&#xff0c;出现了标题中所述的Unit rsyslog.service is masked问题。网上查找了很多资料&…

使用VC++设计程序对一幅256级灰度图像进行全局固定阈值分割、自适应阈值分割

图像分割–全局固定阈值分割、自适应阈值分割 获取源工程可访问gitee可在此工程的基础上进行学习。 该工程的其他文章&#xff1a; 01- 一元熵值、二维熵值 02- 图像平移变换&#xff0c;图像缩放、图像裁剪、图像对角线镜像以及图像的旋转 03-邻域平均平滑算法、中值滤波算法、…

【DevOps】基于 KubeSphere 的 Kubernetes 生产实践之旅(万字长文)

基于 KubeSphere 的 Kubernetes 生产实践 1.KubeSphere 简介1.1 全栈的 Kubernetes 容器云 PaaS 解决方案1.2 选型理由&#xff08;从运维的角度考虑&#xff09; 2.部署架构图3.节点规划3.1 软件版本3.2 规划说明3.2.1 K8s 集群规划3.2.2 存储集群3.2.3 中间件集群3.2.4 网络规…

【开源】基于Vue+SpringBoot的农家乐订餐系统

项目编号&#xff1a; S 043 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S043&#xff0c;文末获取源码。} 项目编号&#xff1a;S043&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户2.2 管理员 三、系统展示四、核…