STM32步进闭环控制、速度控制(张大头Emm_V4.2驱动器)速度控制 角度控制 位置控制

这篇具有很好参考价值的文章主要介绍了STM32步进闭环控制、速度控制(张大头Emm_V4.2驱动器)速度控制 角度控制 位置控制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

本文继续简述使用stm32对张大头步进电机进行速度控制和角度控制。
张大头与stm32的硬件连接请看这个

要注意哈!usart模式要先通过张大头的小屏幕进行设置的哈!!要配置好波特率和地址。这些在张大头提供的pdf说明文档里面都有写!


一、cubemx配置

基础配置不说了,由于我们需要用stm32的usart,所以打开一个usart,波特率要和电机设置的匹配,我使用的是115200
STM32步进闭环控制、速度控制(张大头Emm_V4.2驱动器)速度控制 角度控制 位置控制,stm32,单片机,嵌入式硬件
然后生成代码即可。

二、代码

首先要知道,控制转速和控制旋转的角度发送的字节长度不同。所以本文中默认了电机的功能,只能在角度控制和速度控制中选择一个。

1.datou.h文件

先看.h文件,文件中有两个结构体,一个是速度的,一个是角度控制的,角度控制里面有一个专门记录当前位置的值,这样方便进行角度控制。
还有一个枚举,这个枚举是来控制角度模式下的电机转动方向的,用1个0 来表示,那个不动的2 是电机角度模式下到达指定位置的速度的高字节,由于一般情况下到达指定位置的速度是设定好的,所以在角度控制模式下我没有写相应的修改函数。extern StepperMotorControl moto1;这些声明的变量都是.c文件中的,当需要几个电机的时候就创建几个这样的变量。

#ifndef __DATOU_H
#define __DATOU_H

#include "main.h"

typedef struct 
{
    uint8_t controlBytes[6];
    uint8_t lastControlBytes[6];

} StepperMotorControl;
typedef struct 
{
    uint8_t controlBytes[9];
    uint8_t lastControlBytes[9];
	float now_angle;
} StepperMotorControl_location;
typedef  enum 
{
	forward=0x12,		//正
	reverse=0x02		//反
}Command;
extern StepperMotorControl moto1;
extern StepperMotorControl moto2;
extern StepperMotorControl moto3;
extern StepperMotorControl moto4;
void StepperMotorControl_init(StepperMotorControl *control, uint8_t address);
void set_speed(StepperMotorControl *control, uint8_t direction, uint16_t speed);
void set_acceleration(StepperMotorControl *control, uint16_t acceleration);
extern StepperMotorControl_location moto_9;//下
extern StepperMotorControl_location moto_8;//上
void StepperMotorControl_init_location(StepperMotorControl_location *control, uint8_t address) ;
void set_angle_control_location(StepperMotorControl_location *control, float target_angle_num);

2.datou.c文件

有了对.h文件的大体了解,现在我们来说一下.c文件
其中要注意的是在速度模式下只有3个可以调用的函数,角度模式下有2个可以调用的函数

  • 速度模式下
    初始化
void StepperMotorControl_init(StepperMotorControl *control, uint8_t address);

设置速度

void set_speed(StepperMotorControl *control, uint8_t direction, uint16_t speed);

设置加速度

void set_acceleration(StepperMotorControl *control, uint16_t acceleration);
  • 角度模式下
    初始化
void StepperMotorControl_init_location(StepperMotorControl_location *control, uint8_t address) ;

设置角度

void set_angle_control_location(StepperMotorControl_location *control, float target_angle_num);

文件中有些static 的函数,这些函数是用来进行一些调用和判断以及发送的,外部使用的时候不需要调用这些函数。

#include "datou.h"

#include <stdint.h>
#include <string.h>
#include <stdio.h>

#include <usart.h>
StepperMotorControl moto1;//一号轮
StepperMotorControl moto2;//二号轮
StepperMotorControl moto3;//三号轮
StepperMotorControl moto4;//四号轮
/******************************************************
Function:    		void StepperMotorControl_init(StepperMotorControl *control, uint8_t address) 
Description: 		指定电机初始化函数(这个函数是用来指定电机的速度的)
Calls:				 	NONE 
Input: 					StepperMotorControl *control这个变量是结构体变量,这个结构体里面有2个成员
								分别对应了当前发送的数据,上次发送的数据
								address	是电机设定的地址
******************************************************/

void StepperMotorControl_init(StepperMotorControl *control, uint8_t address) 
{
    uint8_t defaultBytes[6] = {0x00, 0xF6, 0x10, 0x00, 0xaf, 0x6B};
    memcpy(control->controlBytes, defaultBytes, 6);
    memcpy(control->lastControlBytes, defaultBytes, 6);
    control->controlBytes[0] = address;
}

static uint8_t hasChanged(StepperMotorControl *control) 
{
    for (uint8_t i = 0; i < 6; i++) {
        if (control->controlBytes[i] != control->lastControlBytes[i]) 
				{
            return 1;
        }
    }
    return 0;
}

static void updateLastControlBytes(StepperMotorControl *control) 
{
    for (uint8_t i = 0; i < 6; i++) {
        control->lastControlBytes[i] = control->controlBytes[i];
    }
}

static void sendCommand(StepperMotorControl *control) 
{
    if (hasChanged(control)) {

				HAL_UART_Transmit(&huart3, control->controlBytes, 6, 100);
        updateLastControlBytes(control);
    }
}
/******************************************************
Function:    		void set_speed(StepperMotorControl *control, uint8_t direction, uint16_t speed) 
Description: 		设置电机的转速
Calls:				 	static void sendCommand(StepperMotorControl *control) 
Input: 					StepperMotorControl *control这个变量是结构体变量,这个结构体里面有2个成员
								分别对应了当前发送的数据,上次发送的数据
								direction 是电机的方向
								speed	是电机的速度
******************************************************/
void set_speed(StepperMotorControl *control, uint8_t direction, uint16_t speed) 
{
    if (direction) {
        control->controlBytes[2] = (0x10) | ((speed >> 8) & 0x0F); // 逆时针方向
    } else {
        control->controlBytes[2] = (0x00) | ((speed >> 8) & 0x0F); // 顺时针方向
    }
    control->controlBytes[3] = speed & 0xFF;
    sendCommand(control);
}
/******************************************************
Function:    		void set_acceleration(StepperMotorControl *control, uint16_t acceleration) 
Description: 		设置电机的加转速
Calls:				 	static void sendCommand(StepperMotorControl *control) 
Input: 					StepperMotorControl *control这个变量是结构体变量,这个结构体里面有2个成员
								分别对应了当前发送的数据,上次发送的数据
								acceleration	是电机的加速度
******************************************************/
void set_acceleration(StepperMotorControl *control, uint16_t acceleration) 
{
    control->controlBytes[4] = acceleration;
    sendCommand(control);
}

StepperMotorControl_location moto_9;//下
StepperMotorControl_location moto_8;//上


/******************************************************
Function:    		void StepperMotorControl_init_location(StepperMotorControl_location *control, uint8_t address) 
Description: 		指定电机初始化函数(这个函数是用来指定电机的位置的)
Calls:				 	NONE 
Input: 					StepperMotorControl_location *control这个变量是结构体变量,这个结构体里面有3个成员
								分别对应了当前发送的数据,上次发送的数据,以及当前的位置值
								address	是电机设定的地址
******************************************************/

void StepperMotorControl_init_location(StepperMotorControl_location *control, uint8_t address) 
{
	
	
    uint8_t defaultBytes[9] = {0x00, 0xFD, 0x12, 0x00, 0xaf,0x00,0x00,0x00,0x6B};
    memcpy(control->controlBytes, defaultBytes, 9);
    memcpy(control->lastControlBytes, defaultBytes, 9);
    control->controlBytes[0] = address;
}
static uint8_t hasChanged_location(StepperMotorControl_location *control) 
{
    for (uint8_t i = 0; i < 9; i++) {
        if (control->controlBytes[i] != control->lastControlBytes[i]) 
				{
            return 1;
        }
    }
    return 0;
}
static void updateLastControlBytes_location(StepperMotorControl_location *control) 
{
    for (uint8_t i = 0; i < 9; i++) {
        control->lastControlBytes[i] = control->controlBytes[i];
    }
}

static void sendCommand_location(StepperMotorControl_location *control) 
{
    if (hasChanged_location(control)) {

				HAL_UART_Transmit(&huart3, control->controlBytes, 9, 100);
        updateLastControlBytes_location(control);
    }
}

static void set_location(StepperMotorControl_location *control, Command com, int pulse_num) 
{		
	control->controlBytes[2] =com;
	
	control->controlBytes[6] = pulse_num>>8;/* 脉冲数中字节 */
	control->controlBytes[7] = pulse_num-((pulse_num>>8)<<8);	/* 脉冲数低字节 */

    sendCommand_location(control);
}


/******************************************************
Function:    	void set_angle_control_location(StepperMotorControl_location *control, float target_angle_num)
Description: 	控制指定电机的角度
Calls:				 static void set_location(StepperMotorControl_location *control, Command com, int pulse_num) 
Input: 					StepperMotorControl_location *control这个变量是结构体变量,这个结构体里面有3个成员
								分别对应了当前发送的数据,上次发送的数据,以及当前的位置值(由于需要通过用角度的差值来计算脉冲数,所以需要记录当前的位置)
								target_angle_num	是目标角度
******************************************************/
#define a_circle_pulse 3200.0//这是一圈需要的脉冲数
void set_angle_control_location(StepperMotorControl_location *control, float target_angle_num)
{
	double error_angle=target_angle_num-(control->now_angle);
	int need_pulse=(int)(error_angle/360.0*a_circle_pulse);
	if(error_angle!=0)
	{
		if(need_pulse<0)
		{
			set_location(control,reverse, -need_pulse);//注意此处的reverse可能需要改成forward,这个要根据你的物理结构而定
		}
		else
		{
			set_location(control,forward, need_pulse);//注意此处的forward可能需要改成reverse,这个要根据你的物理结构而定
		}
		control->now_angle=target_angle_num;
		
	}
}

3. 主函数编写以及函数调用

在主函数中

	/*底盘电机初始化*/		
	StepperMotorControl_init(&moto1,0x01);
	StepperMotorControl_init(&moto2,0x02);
	StepperMotorControl_init(&moto3,0x03);
	StepperMotorControl_init(&moto4,0x04);	
	
	HAL_Delay(100);	
	/*云台电机初始化*/		
	StepperMotorControl_init_location(&moto_9,0x09);//下云台是9
	StepperMotorControl_init_location(&moto_8,0x08);
	HAL_Delay(100);

	set_angle_control_location(&moto_8,-900);//电机转-900度
	HAL_Delay(2000);
	set_speed(&moto1,1,200) ;//电机正转且速度为200


总结

代码的可读性可能不算高,emm,望大佬指正。谢谢!文章来源地址https://www.toymoban.com/news/detail-626896.html

到了这里,关于STM32步进闭环控制、速度控制(张大头Emm_V4.2驱动器)速度控制 角度控制 位置控制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 小白从零开始:STM32双闭环(速度环、位置环)电机控制(硬件篇)

    小白从零开始:STM32平铺式双闭环(速度环、位置环)电机控制(硬件篇) 小白从零开始:STM32双闭环(速度环、位置环)电机控制(软件篇) 小白从零开始:小程序阿里云平台控制stm32(硬件篇) 杭州研究生手把手教你搞不定STM32 使用工具: 1.PCB设计: 立创EDA+嘉立创 2.硬件

    2024年02月16日
    浏览(39)
  • MKS SERVO42&57D 闭环步进电机_系列12 STM32_CAN例程

    具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法。 硬件开源! 网盘: 08_例程-STM32系列(CAN) 设置波特率: 菜单 → CanRate → 500K 设置从机地址: 菜单 → CanID → 01 需要一个TTL转CAN电平模块。 接线说明 代码说明 代码功能:STM32 主板通过CAN接口读取

    2024年02月10日
    浏览(39)
  • MKS SERVO42&57D 闭环步进电机_系列11 STM32_脉冲和串口例程

    MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法,采用高精度编码器,通过位置反馈,有效防止电机丢步。适合小型机械臂,3D打印机,雕刻机,写字机,

    2024年02月12日
    浏览(55)
  • 闭环控制步进电机对比传统开环控制的优点

    在工业自动化中,步进电机的应用非常的广泛,例如工业机器人、3D打印机、计算机硬盘等都有步进电机的身影。传统的步进电机可以控制转子的角度位置,而不需要传感器来控制位置,是一种开环控制系统,在这样的控制方式下,步进电机控制脉冲的输入并不依赖于转子的

    2023年04月17日
    浏览(54)
  • STM32控制42步进电机

    首先采用TB6600驱动外接12VDC电源。 STM32选c8t6最小系统板 接线TB6600跟32接线有共阴级接法(把ENA-,DIR-,PUL-与32共地)也有共阳接法(把ENA+,DIR+,PUL+与32共地)。这里选共阴级接法。 判断42步进电机的4根线哪两根是A相(A-和A+),哪两根是B相(B-和B+),方法:将任意两根线短接起来

    2024年02月16日
    浏览(74)
  • STM32基于CAN总线协议控制步进电机

    如上图所示,实现了以下功能: 1.两块stm32单片机通过CAN控制器与收发器进行半双工通信; 2.stm32主机通过检测按键,切换不同的模式,将不同模式的case值发送给stm32从机; 3.stm32从机根据收到的case值,控制步进电机进行不同的运动操作; 4.OLED用于显示收发内容与按键状态等

    2024年01月19日
    浏览(50)
  • STM32控制四个步进电机(包含运行程序)

    软件: keil 5(其他版本也ok) 硬件: 步进电机(我用的是42)×4;单片机开发板(本例使用STM32F407ZGT6);电机驱动器×4;外部按键;杜邦线。 实验效果: 四个步进电机对应四个外部按键,按下对应的外部按键选择需要控制的电机。 在开发板上按下KEYO,步进电机以500HZ的频率

    2024年04月29日
    浏览(42)
  • 用STM32定时器中断产生PWM控制步进电机

    控制步进电机可以使用PWM、定时器中断、延时,这里用的就是 定时器中断来让它转动。 板子用的是正点原子的STM32F103 mini板,驱动器是DM420(DM420驱动器资料),用开关电源供电,电机就是普通的42步进电机,步距角为1.8°,虽然按照图片来看它是个蠕动泵。如下图 PUL+——PB0,

    2023年04月09日
    浏览(52)
  • 【STM32F429】HAL库的PWM中断,精确控制脉冲数,控制步进电机

    这两天在调步进电机,希望是使得步进电机每次都达到期望的高度。在查了一天的资料,发现大部分上传的资料都是使用CubeMX生成的,可复制性很高,但未免有失可读性,故上传我的心得经验。 本来原子哥的例程里有整合度很高的,已经封装好的精确控制步进电机前进距离的

    2024年02月08日
    浏览(52)
  • stm32F103单片机pwm控制伺服驱动器进而控制步进电机

    1.需要一台步进电机,私服驱动器,stm32单片机;先按照说明文档,连接好硬件相关线路,对应好sign+,sign-,puls+,puls-线路,其中sign只是个io口拉高拉低操作,puls是pwm波形输出口,虽然有两根线,但只是需要控制一个IO口输出波形即可; 采用主从模式,TIM1为主定时器,tim3未从定

    2024年02月04日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包