当前位置: 首页 > news >正文

如何通过485通信控制汇川电机

0. 先整体架构

STM32 通过 RS485 + Modbus RTU 控制 4 台汇川SV660C伺服电机

- 使能伺服

- 写目标位置

- 写运行速度

- 启动/停止

- 读编码器位置

1. CRC16校验(最核心的底层函数)

c

static uint16_t Modbus_CRC16(uint8_t *buf, uint16_t len)

{

uint16_t crc = 0xFFFF; // 初始值固定 0xFFFF

uint16_t i, j;

for(i=0; i<len; i++) // 逐字节算CRC

{

crc ^= buf[i]; // 和当前字节异或

for(j=0; j<8; j++) // 逐bit移位

{

if(crc & 0x0001) // 最低位为1

{

crc >>= 1;

crc ^= 0xA001; // 多项式 0xA001(Modbus标准)

}

else

{

crc >>= 1; // 最低位为0,直接右移

}

}

}

return crc;

}

作用

Modbus 必须要 CRC16 校验,否则伺服不认你的指令。

关键点

- 输出是 uint16_t

- 发送时:低字节在前,高字节在后

2. 写多个寄存器(0x10功能码)

c

static void SV660C_Write_Reg(

uint8_t slave_addr, // 从站地址(1~4)

uint16_t reg_addr, // 要写的寄存器地址

uint32_t data) // 要写入的32位数据(位置、速度等)

{

uint8_t buf[16] = {0};

uint16_t crc;

uint8_t len = 0;

// 1. 从站地址

buf[len++] = slave_addr;

// 2. 功能码:0x10 = 写多个寄存器

buf[len++] = 0x10;

// 3. 寄存器地址 高8位 + 低8位

buf[len++] = (reg_addr >> 8) & 0xFF;

buf[len++] = reg_addr & 0xFF;

// 4. 要写的寄存器个数

buf[len++] = 0x00; // 高8位

buf[len++] = 0x02; // 低8位 → 一共写2个16位寄存器 = 32位

// 5. 字节总数:4字节

buf[len++] = 0x04;

// 6. 填入32位数据(高字节先发)

buf[len++] = (data >> 24) & 0xFF;

buf[len++] = (data >> 16) & 0xFF;

buf[len++] = (data >> 8) & 0xFF;

buf[len++] = data & 0xFF;

// 7. 计算CRC

crc = Modbus_CRC16(buf, len);

// 8. CRC低字节、高字节放入报文

buf[len++] = crc & 0xFF;

buf[len++] = (crc >> 8) & 0xFF;

// 9. 通过串口2(RS485)发送

USART2_Send_Data(buf, len);

delay_ms(5);

}

作用

给伺服发 32 位数据(位置、速度、控制字)

为什么用 0x10?

因为汇川位置/速度是 32bit,必须一次写两个16位寄存器。

3. 读寄存器(0x03功能码)

c

static int32_t SV660C_Read_Reg(uint8_t slave_addr, uint16_t reg_addr)

{

uint8_t buf[8] = {0};

uint16_t crc;

uint8_t len = 0;

int32_t res = 0;

// 1. 构建读指令 0x03

buf[len++] = slave_addr;

buf[len++] = 0x03; // 读保持寄存器

buf[len++] = (reg_addr >> 8) & 0xFF;

buf[len++] = reg_addr & 0xFF;

buf[len++] = 0x00; // 读2个寄存器

buf[len++] = 0x02;

// 2. CRC

crc = Modbus_CRC16(buf, len);

buf[len++] = crc & 0xFF;

buf[len++] = (crc >> 8) & 0xFF;

// 3. 清空接收,发指令

USART2_ClearRxBuffer();

USART2_Send_Data(buf, len);

delay_ms(5);

// 4. 判断是否接收完成

if(USART2_RX_STA & 0x8000)

{

uint8_t *rxbuf = USART2_RX_BUF;

// 校验地址和功能码

if(rxbuf[0] == slave_addr && rxbuf[1] == 0x03)

{

// 拼接4字节 → 32位有符号位置

res = (rxbuf[3] << 24)

| (rxbuf[4] << 16)

| (rxbuf[5] << 8)

| rxbuf[6];

}

}

return res;

}

作用

读伺服的32位数据:实际位置、转速、状态等

4. 伺服使能(最关键!)

c

static void SV660C_Servo_Enable(uint8_t slave_addr)

{

// 1. 设置操作模式

SV660C_Write_Reg(slave_addr, SV660C_OP_MODE, 1);

// 2. 控制字:0x0006 → 准备

SV660C_Write_Reg(slave_addr, SV660C_CTRL_WORD, 0x0006);

// 3. 控制字:0x000F → 真正使能

SV660C_Write_Reg(slave_addr, SV660C_CTRL_WORD, 0x000F);

delay_ms(10);

}

对应汇川标准流程

- 0x0006 :伺服准备

- 0x000F :伺服上电使能

不执行这段 → 电机不动、不刹车、无响应。

5. 4轴初始化

c

void SV660C_FourAxis_Init(void)

{

// 初始化RS485串口 19200 8N1

USART2_Init(19200);

delay_ms(100);

// 4个轴都使能

SV660C_Servo_Enable(1);

SV660C_Servo_Enable(2);

SV660C_Servo_Enable(3);

SV660C_Servo_Enable(4);

// 4个轴都设置运行速度

SV660C_Write_Reg(1, SV660C_PROFILE_SPEED, MOTOR_SPEED);

SV660C_Write_Reg(2, SV660C_PROFILE_SPEED, MOTOR_SPEED);

SV660C_Write_Reg(3, SV660C_PROFILE_SPEED, MOTOR_SPEED);

SV660C_Write_Reg(4, SV660C_PROFILE_SPEED, MOTOR_SPEED);

}

作用

开机调用一次,4台伺服全部准备好。

6. 4轴同时正转

c

void FourMotor_Forward(void)

{

// 写目标位置

SV660C_Write_Reg(1, SV660C_TARGET_POS, MOVE_STEP);

SV660C_Write_Reg(2, SV660C_TARGET_POS, MOVE_STEP);

SV660C_Write_Reg(3, SV660C_TARGET_POS, MOVE_STEP);

SV660C_Write_Reg(4, SV660C_TARGET_POS, MOVE_STEP);

// 启动运行(控制字 0x001F)

SV660C_Write_Reg(1, SV660C_CTRL_WORD, 0x001F);

SV660C_Write_Reg(2, SV660C_CTRL_WORD, 0x001F);

SV660C_Write_Reg(3, SV660C_CTRL_WORD, 0x001F);

SV660C_Write_Reg(4, SV660C_CTRL_WORD, 0x001F);

}

- SV660C_TARGET_POS :目标位置寄存器

- 0x001F :启动位置模式运行

7. 4轴同时反转

c

void FourMotor_Backward(void)

{

// 目标位置 = 负数

SV660C_Write_Reg(1, SV660C_TARGET_POS, -MOVE_STEP);

SV660C_Write_Reg(2, SV660C_TARGET_POS, -MOVE_STEP);

SV660C_Write_Reg(3, SV660C_TARGET_POS, -MOVE_STEP);

SV660C_Write_Reg(4, SV660C_TARGET_POS, -MOVE_STEP);

// 启动

SV660C_Write_Reg(1, SV660C_CTRL_WORD, 0x001F);

...

}

反转原理

给负的位置指令即可。

8. 读编码器位置

c

int32_t SV660C_Read_Encoder(uint8_t slave_addr)

{

return SV660C_Read_Reg(slave_addr, SV660C_ACTUAL_POS);

}

void FourMotor_Read_Encoders(int32_t *enc_data)

{

enc_data[0] = SV660C_Read_Encoder(1);

enc_data[1] = SV660C_Read_Encoder(2);

enc_data[2] = SV660C_Read_Encoder(3);

enc_data[3] = SV660C_Read_Encoder(4);

}

作用

读4个电机实时位置,用于闭环、限位、回零。

9. 配套的 sv660c.h 宏定义

c

#define SV660C_OP_MODE 0x6060

#define SV660C_CTRL_WORD 0x6040

#define SV660C_TARGET_POS 0x607A

#define SV660C_PROFILE_SPEED 0x6081

#define SV660C_ACTUAL_POS 0x6064

10. 超简总结(10秒记住整个逻辑)

1. CRC16 保证指令有效

2. 0x10 写32位数据(位置/速度/使能)

3. 0x03 读32位位置

4. 0x0006 → 0x000F 伺服使能

5. 0x001F 启动运行

6. 正转给+位置,反转给-位置

如果你愿意,我可以下一步帮你:

http://www.cnnetsun.cn/news/1319311.html

相关文章:

  • RHEL9.7虚拟机部署全攻略
  • AI从业者警惕:2028智能危机或致白领失业率超10%?
  • 三十七选择
  • sdut-程序设计基础Ⅰ-实验6-二维数组
  • 2026年降AI率工具哪个好?亲测这3款真的有效
  • windows基础操作
  • 学术速递 | ICCV 2025 Accepted Papers For Image Fusion
  • 【分享】[特殊字符]Wall[特殊字符]超强的免费安卓壁纸[特殊字符]支持自定义壁纸[特殊字符]什么类型的壁纸都有[特殊字符]
  • 关于Linux密码破解
  • 1/2L7812CV稳压芯片解析
  • 大模型分布式训练:DP、TP、PP 三大并行策略通俗讲解
  • 【杂谈】-人工智能蓬勃演进背后的隐性支撑体系
  • GLM-4V-9B图文理解SOP:标准操作流程图+异常处理决策树+FAQ手册
  • 从零配置Synplify Premier工程:手把手教你玩转FDC约束文件与安全设计(2025新版)
  • 立创EDA实战:基于FM8118芯片的小黄人新年主题加湿器设计与制作
  • 从TI杯D题手势识别装置出发:OpenMV与Arduino的嵌入式视觉开发指南
  • KVCache长上下文场景下性能与精度平衡的管理策略优化
  • Podman国内镜像加速终极指南:阿里云镜像源配置详解(2023最新版)
  • JWT 算法混淆攻击
  • YOLO26涨点改进| 1区Top 2025 | 全网独家创新、细节涨点改进篇| 3个月喜提一区YOLO真神!引入FSPPF漏斗空间金字塔池化模块,含多种组合创新点,助力小目标检测、图像分割高效涨点
  • 冯诺依曼与哈佛架构对比解析
  • STM32家庭环境监测系统:本地智能+MQTT云联+离线语音三重控制
  • 纯模拟电路实现的音频频谱可视化与机械摇摆系统
  • springboot党员之家服务系统 微信小程序毕业论文
  • Lingyuxiu MXJ LoRA算力优化案例:中小企业GPU资源利用率翻倍实践
  • 基于STM32的多模态智能LED照明系统设计
  • 使用Chainlit调用glm-4-9b-chat-1m注意事项:等待模型加载完成再提问
  • Phi-3 Forest Lab应用场景:开源项目维护者——ISSUE分类、PR描述润色、文档补全
  • Ostrakon-VL-8B零售创新:结合地理围栏,自动触发新开门店首周AI巡检
  • 【ISO14229_UDS诊断】-2.1-$27服务安全访问SecurityAccess实战解析