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

【Servo】一个简单的伺服驱动器嵌入式架构,联想

旋转伺服驱动器的嵌入式软件架构

旋转伺服驱动器的嵌入式软件主要负责 电机控制、数据处理、通信交互、状态监控 等功能。为了确保系统的 实时性、可靠性和模块化,通常将软件划分为以下功能模块:


1. 软件功能模块划分

🔹 核心控制模块

模块名称功能描述
FOC(磁场定向控制)采用 矢量控制算法 计算 电流分量 Id/Iq,优化电机性能。
PI 控制器速度、电流、位置闭环控制,实现精确控制目标。
SVPWM(空间矢量脉宽调制)生成 PWM 信号,驱动 逆变器 控制电机。
速度/位置环根据编码器反馈进行 速度、位置闭环控制,确保精度。

🔹 传感器 & 数据采集模块

模块名称功能描述
电流采样(ADC 采样)通过 ADC 采样电流 进行电流环控制(一般 3 通道)。
电压检测监测 母线电压、三相电压,用于过压/欠压保护。
温度检测监测 驱动器温度,防止过热损坏。
编码器/位置反馈处理 增量编码器、旋转变压器、绝对值编码器 反馈数据。

🔹 运动控制模块

模块名称功能描述
插补算法计算平滑轨迹,实现高精度运动。
加减速规划梯形加速、S 形加速,防止速度突变。
目标位置计算根据输入命令计算目标位置。

🔹 通信模块

模块名称功能描述
CANopen/Modbus/EtherCATPLC、上位机 进行通信,接收/发送数据。
UART/RS485用于调试或与外部设备通信(HMI、PC)。
SPI/I2C连接 外部传感器、存储器 进行数据交互。

🔹 保护与故障诊断模块

模块名称功能描述
过流保护监测电流,超过阈值时关闭 PWM 以防损坏。
过温保护过温时降额运行或停止驱动器。
欠压/过压保护低于/高于母线电压阈值时停止驱动器。
编码器异常检测检测 编码器丢失、脉冲丢失 等错误。

🔹 用户接口 & 参数管理

模块名称功能描述
参数存储(EEPROM/Flash)存储用户配置,如 电机参数、PID 参数
键盘/显示(HMI)驱动显示屏和按键,实现 手动操作
诊断和日志记录故障信息,提供调试数据。

🔹 任务管理 & RTOS

模块名称功能描述
任务调度通过 FreeRTOS / RT-Thread 调度各个任务,保证实时性。
中断管理处理 PWM 触发、ADC 采样、通信中断 等事件。
低功耗管理控制 MCU 进入低功耗模式,节省能耗。

2. 软件层级划分

🔹 驱动层(HAL - 硬件抽象层)

组件说明
GPIO控制 LED、继电器、输入/输出信号
ADC/DAC采样 电流、电压、温度
PWM生成 逆变器控制信号
UART/SPI/I2C通信接口,连接外部设备。

🔹 中间层(MCU 控制层)

组件说明
FOC 算法计算 Id/Iq 电流,控制电机。
闭环控制PID 位置、速度、电流控制
编码器解析处理 增量编码器、旋转变压器 数据。

🔹 应用层

组件说明
上位机通信通过 CANopen/Modbus 控制驱动器。
人机交互(HMI)处理 按键输入、LCD 显示
故障处理过流、过压、欠压等保护机制。

3. 任务优先级 & 调度

🔹 高优先级任务(实时任务)

任务描述运行频率
FOC 算法计算 PWM 输出,控制电机10-20kHz
电流环控制采样电流,更新 PI 控制器10-20kHz
PWM 触发控制 MOSFET 开关10-20kHz

🔹 中等优先级任务

任务描述运行频率
速度环控制计算速度 PI 控制1-5kHz
位置环控制计算目标位置500Hz-1kHz
通讯处理解析 CANopen/Modbus 数据1kHz

🔹 低优先级任务

任务描述运行频率
参数存储保存参数到 EEPROM/Flash1Hz-10Hz
诊断与日志记录报警信息10Hz
温度监测过热保护1Hz

4. 小结

  • 旋转伺服驱动器的嵌入式软件划分为:

    • 核心控制(FOC, PWM, PI)
    • 传感器处理(电流采样, 编码器反馈)
    • 运动控制(速度环, 位置环, 插补算法)
    • 通信(CANopen, Modbus, UART)
    • 保护机制(过流, 过温, 过压)
    • 用户交互(HMI, 参数存储, 诊断日志)
    • 实时任务管理(RTOS调度, 中断处理)
  • 软件架构采用分层设计

    • 驱动层(HAL):操作硬件外设
    • 中间层(控制算法):核心计算逻辑
    • 应用层:用户交互 & 故障处理

旋转伺服驱动器嵌入式软件层级划分

旋转伺服驱动器的嵌入式软件通常采用 分层架构 设计,以提高 可维护性、可扩展性和模块化开发能力

1. 软件分层架构

🔹 典型的 4 层架构
层级主要功能具体模块
应用层(Application Layer)与上位机/用户交互,处理用户命令和系统状态管理上位机协议解析、HMI(人机交互)、参数管理、故障诊断、日志记录
控制层(Control Layer)伺服控制核心算法,执行位置/速度/电流控制FOC 算法、位置环、速度环、电流环、SVPWM、插补算法、滤波器
驱动层(Driver Layer)直接驱动硬件外设,负责数据采集与控制信号输出PWM 生成、电流/电压/位置采样、ADC 采样、编码器解码、GPIO 读写
硬件抽象层(HAL - Hardware Abstraction Layer)屏蔽底层硬件差异,提供统一接口MCU 低级驱动、寄存器操作、RTOS 底层支持、Flash 读写

2. 应用层模块(Application Layer)

应用层的主要职责是:
与上位机(PLC、PC)进行通信
提供用户交互(HMI/LCD/按键)
存储和管理参数
诊断和日志记录

🔹 具体模块

模块功能描述
通信协议(Protocol Stack)解析 CANopen、Modbus、EtherCAT、RS485、UART 等通信协议,实现远程控制
HMI(人机交互)处理 LCD 显示、按键输入,支持用户手动配置参数
参数管理(Parameter Manager)读取/存储 伺服电机参数、PID 参数、编码器设定,存储到 EEPROM/Flash
故障诊断(Fault Diagnosis)监测 过流、过压、欠压、过温、编码器故障 等,提供故障代码
日志记录(Logging)记录故障日志、运行日志,便于调试和维护
远程控制处理 上位机发送的运动控制命令,如 启动、停止、复位、模式切换

3. 偏向上位机交互的模块

以下模块主要负责 与上位机(PLC、PC)交互,接收/发送指令:

  1. 通信协议解析

    • Modbus:用于 PLC 通信,控制伺服驱动器的 启停、模式切换
    • CANopen/EtherCAT:工业总线协议,用于 多轴协同控制
    • UART/RS485:用于 PC 调试、诊断、参数读取
  2. HMI 交互

    • LCD 显示当前电机状态、报警信息、实时参数。
    • 按键调整运行模式、输入目标转速或位置。
  3. 参数管理

    • 上位机发送设定指令,修改 PI 参数、惯量补偿、编码器偏移
    • 将参数存储到 EEPROM/Flash,掉电不丢失。
  4. 故障诊断

    • 实时检测电机状态,如果过流/过压等,发送报警到上位机
    • 例如,PLC 通过 CANopen 读取驱动器状态字,判断是否正常运行。
  5. 日志记录

    • 存储历史报警信息,便于 PC 端诊断分析
    • 上位机可以通过 UART/CANopen 读取报警日志

4. 交互数据流

  上位机(PLC/PC)
        ▲  ▲
        │  │
 CANopen / Modbus / EtherCAT / UART
        │  │
        ▼  ▼
 +----------------------------+
 |  应用层(Application Layer) |
 |----------------------------|
 |  通信协议解析               | ⇄  解析上位机命令
 |  HMI 交互                  | ⇄  显示电机状态
 |  参数管理                  | ⇄  读取/存储参数
 |  故障诊断                  | ⇄  发送报警信息
 |  日志记录                  | ⇄  读取历史记录
 +----------------------------+
        │
        ▼
 +----------------------------+
 |  控制层(Control Layer)    |  ⇄  计算运动控制
 |----------------------------|
 |  位置环 / 速度环 / 电流环   |
 |  FOC 算法                   |
 |  插补 & 轨迹规划            |
 +----------------------------+
        │
        ▼
 +----------------------------+
 |  驱动层(Driver Layer)     |  ⇄  直接操作硬件
 |----------------------------|
 |  PWM 生成                  |
 |  ADC 采样                   |
 |  编码器解码                 |
 +----------------------------+

5. 小结

1️⃣ 软件总共分为 4 层

应用层(Application)—— 与上位机交互,管理用户参数和报警日志。
控制层(Control)—— 计算 FOC 算法、位置/速度控制,负责电机运行。
驱动层(Driver)—— 直接与硬件交互,包括 PWM、ADC、编码器
硬件抽象层(HAL)—— 屏蔽底层硬件,提供统一接口。

2️⃣ 应用层(Application)包含哪些模块

  • 通信协议解析(CANopen、Modbus、EtherCAT) → 远程控制
  • HMI 交互(LCD、按键、菜单系统) → 本地调试
  • 参数管理(EEPROM/Flash 存储) → 读取/修改伺服参数
  • 故障诊断(报警、过流、过压等) → 确保安全运行
  • 日志记录(存储历史报警) → 提供维护数据

3️⃣ 偏向上位机交互的模块

通信协议解析(CANopen, Modbus, EtherCAT, UART)
HMI 交互(LCD、按键)
参数管理(EEPROM 读写)
故障诊断(过流、过温、编码器异常检测)
日志记录(报警历史查询)

**词汇联想 ---- 更详细的某个模块,比如 “Modbus 通信流程” 或 “FOC 算法计算过程” **

Modbus 通信流程解析(适用于伺服驱动器)

Modbus 是一种 主从式(Master-Slave) 通信协议,常用于 PLC(主机)控制伺服驱动器(从机)。它支持 串行(RTU/ASCII)以太网(TCP) 传输。

1. Modbus 主要特点

主从模式:上位机(PLC/PC)主动发送指令,伺服驱动器被动响应
地址寻址:支持 247 个从机(RTU 模式),通过 从机地址(Slave ID) 区分设备。
寄存器映射:采用 功能码 + 寄存器地址 读写 伺服驱动器参数
错误检测:RTU 模式使用 CRC 校验,保证数据完整性。


2. Modbus 通信流程

📌 主从设备数据流

    PLC(Modbus Master)
        │
        ▼
  请求(READ/WRITE)
        │
        ▼
  伺服驱动器(Modbus Slave)
        │
        ▼
  响应(DATA/ERROR)

📌 通信步骤

Step 1PLC 发送 Modbus 请求(READ/WRITE)
Step 2伺服驱动器解析请求(检查从机地址 + 功能码 + CRC)
Step 3伺服驱动器执行操作(读/写寄存器)
Step 4伺服驱动器返回响应(成功数据或错误码)
Step 5PLC 解析响应数据,控制伺服驱动器运行


3. Modbus 数据帧格式

Modbus 数据帧由 地址 + 功能码 + 数据 + 校验 组成。

📌 RTU 模式数据帧

字段字节描述
从机地址(Slave ID)1目标设备地址(1-247)
功能码(Function Code)1读/写操作代码
数据区(Data)N具体寄存器地址 & 数据
CRC 校验(Error Check)2计算数据完整性

示例(读取 03 寄存器数据)

[01] [03] [00] [0A] [00] [01] [C5] [CD]
  • 01 → 设备地址(从机 1)
  • 03 → 读取保持寄存器
  • 00 0A → 寄存器地址 0x000A
  • 00 01 → 读取 1 个寄存器
  • C5 CD → CRC 校验码(低字节在前)

4. Modbus 主要功能码

功能码(Hex)操作描述
0x03读保持寄存器(Read Holding Registers)读取 伺服参数(位置、速度、扭矩等)
0x06写单个寄存器(Write Single Register)设置 目标转速、目标位置
0x10写多个寄存器(Write Multiple Registers)批量写入多个参数

5. 伺服驱动器 Modbus 寄存器映射

伺服驱动器通常通过 Modbus 03/06/10 功能码 访问内部寄存器,例如:

寄存器地址功能数据类型说明
0x0001运行状态16-bit0 = 停止1 = 运行
0x0002伺服使能16-bit0 = 禁用1 = 使能
0x0003目标转速16-bitRPM
0x0004目标位置32-bit编码器单位
0x0005实际转速16-bitRPM
0x0006实际位置32-bit反馈位置

6. Modbus 典型指令示例

📌 读取伺服状态

PLC 读取 1 号伺服驱动器的运行状态(0x0001 寄存器)

[01] [03] [00] [01] [00] [01] [D5] [CA]

解析

  • 01 → 从机地址
  • 03 → 读取保持寄存器
  • 00 01 → 目标寄存器地址 0x0001
  • 00 01 → 读取 1 个寄存器
  • D5 CA → CRC 校验

伺服返回(状态 = 运行)

[01] [03] [02] [00] [01] [79] [84]
  • 02 → 返回 2 字节数据
  • 00 01 → 运行状态 = 1
  • 79 84 → CRC 校验

📌 设定目标转速

PLC 设置 1 号伺服目标转速 1500 RPM

[01] [06] [00] [03] [05] [DC] [88] [35]

解析

  • 01 → 设备地址
  • 06 → 写单个寄存器
  • 00 03 → 目标转速寄存器地址 0x0003
  • 05 DC → 1500(十进制)
  • 88 35 → CRC 校验

伺服返回

[01] [06] [00] [03] [05] [DC] [88] [35]

(确认写入成功)


📌 伺服驱动器使能

PLC 发送指令,使能 1 号伺服驱动器

[01] [06] [00] [02] [00] [01] [18] [0A]

解析

  • 00 02 → 伺服使能寄存器
  • 00 01 → 使能

伺服返回

[01] [06] [00] [02] [00] [01] [18] [0A]

7. Modbus 伺服驱动器通信架构

+------------------------+
|  PLC/上位机(Modbus 主机)|
+------------------------+
        │
   Modbus RTU/TCP
        │
+------------------------+
|  伺服驱动器(Modbus 从机)|
|  - 解析 Modbus 指令      |
|  - 读/写伺服参数        |
|  - 反馈运行状态        |
+------------------------+

8. 小结

Modbus 采用主从模式,PLC/PC 控制伺服驱动器。
支持多种功能码0x03 读参数,0x06 写单个参数,0x10 批量写入)。
通信流程:主机发送指令 -> 伺服解析 -> 读取/写入数据 -> 伺服响应
适用于 CANopen、Modbus RTU/ASCII、Modbus TCP


💡 ** 完整的 Modbus 代码示例(C 语言嵌入式实现) **

完整的 Modbus RTU 代码示例(C 语言嵌入式实现)

以下代码实现 Modbus RTU 从机(伺服驱动器) 的核心功能,包括:
接收 Modbus RTU 请求(读取寄存器、写入寄存器)
解析功能码(0x03 读取寄存器, 0x06 写单个寄存器, 0x10 写多个寄存器)
生成响应数据帧并通过 UART 发送
支持 CRC 校验


📌 1. 伺服驱动器 Modbus RTU 框架

+-------------------------------------+
|      伺服驱动器(Modbus 从机)       |
+-------------------------------------+
| UART 接收 Modbus 请求               | ⇄  PLC 发送读取/写入指令
| 解析数据帧(地址+功能码+数据+CRC)  |
| 处理功能码(0x03/0x06/0x10)       |
| 访问寄存器数据(位置、速度等)       |
| 计算 CRC 并返回 Modbus 响应          |
+-------------------------------------+

📌 2. Modbus 伺服驱动器寄存器

#define MODBUS_ADDRESS    1   // 从机地址
#define REG_COUNT         10  // 伺服寄存器数量

// 伺服寄存器表
uint16_t servo_registers[REG_COUNT] = {
    0x0000, // 0x0000: 伺服运行状态(0=停止,1=运行)
    0x0000, // 0x0001: 伺服使能状态(0=关闭,1=使能)
    0x05DC, // 0x0002: 目标速度(默认 1500 RPM)
    0x0000, // 0x0003: 目标位置
    0x0000, // 0x0004: 实际速度反馈
    0x0000, // 0x0005: 实际位置反馈
    0x0000, // 0x0006: 电流反馈
    0x0000, // 0x0007: 负载扭矩
    0x0000, // 0x0008: 报警状态
    0x0000  // 0x0009: 运行时间
};

📌 3. CRC16 校验计算

Modbus RTU 采用 CRC-16(多项式 0xA001 进行校验:

uint16_t Modbus_CRC16(uint8_t *data, uint16_t length) {
    uint16_t crc = 0xFFFF;
    for (uint16_t i = 0; i < length; i++) {
        crc ^= data[i];
        for (uint8_t j = 0; j < 8; j++) {
            if (crc & 0x0001) {
                crc >>= 1;
                crc ^= 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }
    return crc;
}

📌 4. 解析 Modbus 请求

void Modbus_ParseRequest(uint8_t *request, uint16_t length) {
    if (length < 8) return; // 最小 Modbus RTU 帧长

    // 校验 CRC
    uint16_t received_crc = (request[length - 1] << 8) | request[length - 2];
    uint16_t calculated_crc = Modbus_CRC16(request, length - 2);
    if (received_crc != calculated_crc) return; // CRC 校验失败

    uint8_t slave_id = request[0];  // 从机地址
    uint8_t function_code = request[1]; // 功能码
    uint16_t reg_address = (request[2] << 8) | request[3]; // 寄存器地址
    uint16_t reg_count = (request[4] << 8) | request[5];   // 读取数量

    if (slave_id != MODBUS_ADDRESS) return; // 不是本设备,忽略

    switch (function_code) {
        case 0x03: // 读取寄存器
            Modbus_HandleReadRequest(reg_address, reg_count);
            break;
        case 0x06: // 写单个寄存器
            Modbus_HandleWriteRequest(reg_address, reg_count);
            break;
        default:
            break;
    }
}

📌 5. 读取保持寄存器(功能码 0x03)

void Modbus_HandleReadRequest(uint16_t reg_address, uint16_t reg_count) {
    uint8_t response[256];
    uint16_t length = 0;

    response[length++] = MODBUS_ADDRESS; // 从机地址
    response[length++] = 0x03; // 功能码
    response[length++] = reg_count * 2; // 字节数

    for (uint16_t i = 0; i < reg_count; i++) {
        uint16_t value = servo_registers[reg_address + i];
        response[length++] = value >> 8;
        response[length++] = value & 0xFF;
    }

    uint16_t crc = Modbus_CRC16(response, length);
    response[length++] = crc & 0xFF;
    response[length++] = crc >> 8;

    UART_Send(response, length); // 通过串口发送响应
}

📌 6. 写单个寄存器(功能码 0x06)

void Modbus_HandleWriteRequest(uint16_t reg_address, uint16_t value) {
    if (reg_address < REG_COUNT) {
        servo_registers[reg_address] = value; // 更新寄存器值
    }

    uint8_t response[8];
    response[0] = MODBUS_ADDRESS;
    response[1] = 0x06;
    response[2] = reg_address >> 8;
    response[3] = reg_address & 0xFF;
    response[4] = value >> 8;
    response[5] = value & 0xFF;

    uint16_t crc = Modbus_CRC16(response, 6);
    response[6] = crc & 0xFF;
    response[7] = crc >> 8;

    UART_Send(response, 8); // 通过串口返回确认
}

📌 7. 串口接收 Modbus 数据

#define UART_BUFFER_SIZE 256
uint8_t uart_buffer[UART_BUFFER_SIZE];
uint16_t uart_index = 0;

void UART_Receive_Handler(uint8_t byte) {
    uart_buffer[uart_index++] = byte;

    if (uart_index >= 8) { // Modbus 最小帧长
        Modbus_ParseRequest(uart_buffer, uart_index);
        uart_index = 0; // 清空缓冲区
    }
}

📌 8. 伺服 Modbus RTU 总体流程

  1. UART 接收 Modbus 数据
  2. 解析 Modbus 请求(地址 + 功能码 + CRC 校验)
  3. 处理功能码(读/写寄存器)
  4. 返回 Modbus 响应

✅ 小论

🚀 完整的 Modbus RTU 代码,支持:

  • 读取寄存器(0x03)
  • 写入寄存器(0x06)
  • CRC 校验
  • UART 串口收发

http://www.kler.cn/a/591029.html

相关文章:

  • JVM G1内存管理核心概念解析:Region、Card Table、CSet与RSet
  • 机试准备第19天
  • Java1.8与testNg兼容问题:bad class file和SocketTimeoutException: Read timed out
  • synchronized底层加锁原理
  • HTTP服务器的工作逻辑
  • 力扣hot100_二分查找(1)_python版本
  • 小样本学习入门指南:以图像识别为例
  • 【数据结构之树】
  • PE(Processing Element,处理单元)在Vitis HLS中的应用与实现
  • 深入理解 Linux 的 top 命令:实时监控系统性能
  • Python绝美樱花树
  • 结合基于标签置信度的特征选择方法用于部分多标签学习-简介版
  • 第18章-综合以上功能 基于stm32的智能小车(远程控制、避障、循迹) 基于stm32f103c8t6_HAL库_CubeMX_超详细,包含代码讲解和原理图
  • Matlab 汽车电子驻车系统仿真分析
  • Java算法之解题套路
  • 超图神经网络的详细解析与python示例
  • 国产编辑器EverEdit - 模式的原理与作用
  • HP LoadRunner 12.02全面性能测试工具的功能与使用指南
  • 【大模型】Token计算方式与DeepSeek输出速率测试
  • 本周安全速报(2025.3.11~3.17)