当前位置:首页 > 工业控制 > 电路设计项目集锦
[导读]BLHeli_S — 这是较早且广泛使用的固件版本。它适用于赛灵思公司的 EFM8 8051 类型的微控制器。支持脉冲宽度调制(PWM)、单脉冲(OneShot)和双脉冲(DShot)输入协议。虽然不再进行积极开发,但仍能在数百万块电路板上找到使用。

ESC 自身拥有固件程序。目前最常用的两个开源固件系列是:

BLHeli_S — 这是较早且广泛使用的固件版本。它适用于赛灵思公司的 EFM8 8051 类型的微控制器。支持脉冲宽度调制(PWM)、单脉冲(OneShot)和双脉冲(DShot)输入协议。虽然不再进行积极开发,但仍能在数百万块电路板上找到使用。

Bluejay — 一款基于 BLHeli_S 开源版本的衍生产品,同样适用于 SiLabs EFM8。它增加了双向 DShot 功能(将发动机转速数据反馈至飞行控制器)、扩展型 DShot 通信协议(包含温度、电流、电压数据)以及可配置的 PWM 频率(24/48/96 千赫兹)。这是对 BLHeli_S 的现代替代品。

BLHeli_32 — 一款专为基于 STM32 的电动机控制器设计的独立闭源固件。此处未作介绍。

ESC 如何接收指令——信号线

飞行控制器通过一根导线加上地线与每个电子调速器进行通信。这根信号线承载着所有信息:飞行过程中的油门指令,以及设置时的串行配置数据。

该线路所采用的三种主要输入协议为:

PWM(模拟)——最古老的方法。风扇控制器会发送一个宽度在 1000 微秒至 2000 微秒之间的脉冲,每秒重复约 400 次。这种方法简单但速度较慢且精度不高。

DShot — 一种全数字协议。飞行控制器会发送一个 16 位的帧,其中包含 0 到 2047 的油门值以及一个循环冗余校验码,传输速率有 150、300 或 600 千比特每秒。无需校准,不受模拟噪声影响,并支持特殊指令(电机方向、保存设置、进入启动加载程序)。这是所有现代版本的标准配置。

串行(UART)——仅用于配置和固件闪存操作。同一根信号线会切换为 1 位半双工 UART,波特率为 19200。PC 上的 ESC 配置软件通过此链路与 ESC 启动加载程序进行通信。

关键的见解在于:在飞行过程中,这根导线传输的是 DShot 帧数据;而在配置阶段,它则传输的是串行 UART 字节。飞行控制器需要在这两种用途之间切换使用这根导线。

飞行控制员如何使用 MSP 来配置电动机控制器(ESC)

MSP 代表“多翼飞行器串行协议”。它是 Betaflight、Cleanflight 及类似飞行控制器固件所使用的命令协议,用于通过 USB 与地面站软件(如 Betaflight 配置器)进行通信。当你将飞行控制器插入电脑时,你就是在通过虚拟串行端口进行 MSP 通信。

MSP 是一种简单的请求-响应协议。PC 发送带有功能代码和可选数据包的分帧命令。FC 对其进行处理并返回响应。功能代码涵盖了从读取传感器数据和 PID 值到保存设置和重新启动的所有内容。

其中一种功能代码是“ESC 透传命令”。当个人电脑(运行着 BLHeli 配置器或 ESC 配置器程序)想要直接与电机 ESC 进行通信时,它会向飞行控制器发送一个特殊的 MSP 命令,要求其进入透传模式,为特定的电机设置这一模式。

在“通过模式”下飞行控制员所执行的操作:

该控制器会停止向选定的电机输出引脚发送 DShot 帧。随后,它会将通过 USB 串行端口接收到的每个字节进行位操作处理,并以原始 UART 字节的形式(波特率为 19200,半双工模式)传输至电机信号引脚。ESC 的响应会通过同一引脚返回,并转发回 USB 端口。而 PC 软件并不知道它是在通过中间环节进行通信——在它的视角中,它是在直接与 ESC 进行通信。

这条链条看起来是这样的:

PC(ESC 配置器)——通过 USB/MSP 接口——连接到 FC CPU——经由位控 UART 转换——连接到 ESC 信号引脚——再连接到 ESC 引导加载程序

其不足之处在于:FC CPU 在执行软件位串行通信接口(UART)的同时,还负责运行其常规调度程序(传感器读取、PID 循环、LED 更新)。任何中断或任务抢占都会导致串行时序出现抖动。在进行固件闪存操作时,这可能会导致字节帧错误、引导加载程序超时,甚至在最糟糕的情况下,造成部分写入的闪存损坏,从而损坏 ESC。

利用 RP2040:多核策略

为解决传统固件中存在的抖动和卡顿问题,我们的 Pico 实现采用了 RP2040 的双核架构:

•核心 1:背景任务:此核心完全用于脉冲宽度调制解码(遥控输入)。通过将接收脉冲的测量工作单独分配给核心 1,我们确保接收信号的高频采样不会干扰核心 0 上至关重要的电机控制逻辑。

•核心 0:实时引擎:这是“主”核心。它负责处理与 RPi Zero 2W 的高优先级 SPI 从机通信,并管理所有的 PIO 状态机。

通过这种方式分配工作量,核心 0 能够“重置”自身,从而管理 PIO FIFO(串行输入/输出缓冲区)。无论是推送 DSHOT 帧还是传输 MSP 串行数据包,实时核心都不会因 RC 信号处理的后台开销而分心。

技术对决:PIO 与位操作之争

Pico 实现中的真正创新之处在于摒弃了传统飞行控制器(如 Betaflight 所采用的)那种“软件位操作”的模式。

贝塔飞行方案:在贝塔飞行的 serial_4way_avrootloader.c 文件中,CPU 通过使用严格的 micros() 休眠等待循环来处理 19200 波特的 UART 协议。这会阻塞 CPU,并且对中断抖动非常敏感。如果处理器因为在执行高优先级任务而处于忙碌状态,从而错过了某个位转换,那么串行帧就会被损坏。

Pico PIO 方法:在 RP2040 上,我们将 UART 协议移至 PIO 状态机处理。CPU 只需将字节放入 FIFO 中,而 PIO 硬件则以纳秒级精度处理 8N1 编码(起始/停止位)。这种方式是无阻塞且确定性的——位定时不受 CPU 正在执行的操作的影响。

硬件半双工模式:皮科固件会专门负责半双工模式的转换管理。当一个传输帧完成后,PIO 状态机会立即重新初始化,以确保能够以零延迟捕获电子稳定器的响应。

Pico 上 DShot 与 ESC 串行接口的转换:

主要的难题在于,DShot 和 ESC 串行协议实际上是基于同一个电机信号引脚的不同使用方式,它们之间存在根本的不兼容性。DShot 是一种持续的高速输出。而 ESC 串行协议则是一种较低波特率的半双工双向链接。电机引脚必须从一种模式转变为另一种模式——并且这种转变必须是干净的,否则 ESC 将无法进入其引导加载程序。

在 Pico 上,电机引脚的控制权在 PIO 状态机之间进行传递。完整的转换过程为:

步骤 1 — 停止 DShot 输出:DShot 的 PIO 状态机已被停止,电机引脚被释放至一个已知的高电平闲置状态。

步骤 2 — 发出中断脉冲:一个独立的 PIO 程序将该引脚保持为低电平至少 20 毫秒(实际操作中使用 50 毫秒以确保留有余量)。这是启动引导程序的信号。ESC 会监测此信号,如果脉冲时间过短,它将不会进入引导程序模式。

第 3 步 — 释放与闲置:在开始串行通信之前,该引脚先处于高电平状态,持续一小段时间以进行恢复。

第 4 步 — 启动 PIO 串行引擎:同样的电机引脚被分配给了一个基于 PIO 的半双工 UART 状态机,该状态机配置为 19200 波特、8 位数据位、无奇偶校验位。这里使用了 PIO — 而不是软件 UART — 具体原因是因为 ESC 启动加载程序对时间控制要求严格。任何由中断抢占或调度器抖动引起的字节间间隔都可能导致加载程序终止会话。

第 5 步 — 运行 4 路 BLHeli 协议:Python 电子调速器配置器通过 PIO UART 发送 BLHeli 四路命令(test_alive、get_version、get_name、init_flash、read_eeprom)。响应通过同一引脚返回,并由相同的 PIO 状态机读取。该协议使用 CRC-16/XMODEM 编码格式,并在每一帧中包含一个同步字节(主机端为 0x2F,ESC 端为 0x2E)。

第 6 步 — 退出并恢复 DShot:退出时,PIO 串行引擎被停止,引脚所有权又回到了 DShot 状态机的状态。

这是通过一个单独的 ESC(电子调速器)和电机进行验证的。测试脚本位于该仓库的“python/hw/test_hw_esc_passthrough.py”文件中。

为何采用 FPGA:Pico PIO 方法验证了协议和 Python 核心模块的可行性。但该方法每次只能控制一个电机,PIO 指令存储器限制了状态机的复杂程度,而且任何未来的扩展(遥测、双向 DShot、日志记录)都会与这些有限的 PIO 资源发生冲突。而 FPGA 则用 RTL 替代了 PIO,后者能完成相同的工作——但能同时控制四个电机,传输速度更高,无需 CPU 参与,也不存在资源竞争。

问题

当你想要调整电机电子调速器(ESC)的参数——比如改变工作顺序、消除磁滞或改变电机方向时——你需要让一个配置工具直接与它进行通信。在标准的 Betaflight/Cleanflight 配置中,这是通过 MSP 通道来实现的:飞行控制器的 CPU 会拦截 USB 串行数据流,并将其直接传输到电机信号引脚上。

目标是使用 FPGA 来实现这一功能,但目前该项目仍在测试阶段。

FPGA 架构

该卸载器的核心是一个专门的 RTL(寄存器传输级)设计,它将整个关键的时序路径都转移到了硬件门电路中。

硬件设备

rt-fc-offloader 是一个开源的 FPGA 项目(采用唐纳诺 9K 芯片和 Gowin 工具链),它位于 Raspberry Pi Zero 2W 飞行控制器与最多四个电子调速器之间。在正常飞行过程中,它会以 RTL 语言确定性地生成 DShot 脉冲——无需 CPU 参与。但当需要配置一个电子调速器时,同样的硬件会切换工作模式。

关键寄存器位于地址 0x40000400 处——即“串行/DShot 选择器”:

模式 值 影响

DShot(默认设置)0x01 由 DShot 脉冲引擎驱动的电机垫片

串行直通 0x00 电机垫片连接至电动机控制器串行接口(FCSP 通道 0x05)

引导加载程序故障 0x14 选定区域强制置为低电平(保持 20 多毫秒,然后释放)

如何进入ESC引导程序

BLHeli/Bluejay 电子控制单元通过信号线上的断开序列来启动其引导程序:

将电机信号引脚强制设为低电平,持续时间至少为 20 毫秒。

松开插销

启动 19200 波特的半双工串行通信

在 Betaflight 中,这种中断处理是通过软件实现的——存在因中断延迟而带来的风险。而在 rt-fc-offloader 中,force_low 位只需进行一次寄存器写入操作,而 RTL 则会根据您所要求的时间精确地保持该状态。精度可达纳秒级别。

FCSP 传输层

该 Pi 通过 USB-UART 与 FPGA 进行通信,所使用的协议为飞行控制器串行协议(FCSP):

•通道 0x01(控制通道)——威斯博恩寄存器读取/写入(切换、波特率配置)

•通道 0x05(ESC_SERIAL)—— 与所选电机垫片进行数据传输的原始字节通道

一旦进入串行模式,所有配置器的数据传输都只是 0x05 通道的帧。没有地址头,也没有额外开销——在 1 Mbaud 的链路速度下,每帧可传输多达 512 字节的数据。

硬件的 UART 引擎能够自动处理 1 位串行半双工通信:引脚默认为输入(监听)状态,发送一个字节的瞬间会切换为输出状态,然后在一段保护时间过后再切换回输入状态。Python 从不触及方向寄存器。

闪存式紧急停止(ESC)固件

一旦进入紧急停止(ESC)模式,相同的 FCSP 通道 0x05 就会承载完整的 BLHeli 闪存协议。同样的字节通道,现在以 19200 波特、8 数据位、1 停止位的格式传输启动器命令集。

BLHeli 引导加载程序协议:

步骤 会发生什么情况

•握手主机逐字节发送“BLHeli”字符串

•识别设备后,ESC 会回复启动信息、芯片标识以及引导加载程序版本。

•设置地址 服务器发送 0xFF 加 16 位地址 加 CRC16

•设置缓冲区后,主机发送 0xFE 加上大小再加上 CRC16 的数据,随后再发送原始固件字节。

•程序闪存 主机发送 0x01 + CRC16 — 串口控制器将缓冲区写入闪存

•擦除页面 主机发送 0x02 + CRC16 — ESC 用于擦除闪存页面

•读取闪存 主机发送 0x03 + 计数 + CRC16 — 从机回复数据

•运行应用程序后,主机发送 0x00 0x00 加上 CRC16 —— 以 ESC 信号重启固件

每个命令都会返回一个状态字节:0x30 表示成功,0xC0 至 0xC5 表示错误。校验码采用的是 CRC-16/IBM 格式(多项式为 0xA001)。

为何此方案优于 Betaflight 的传输方式:在 Betaflight 中,CPU 会同时传输字节并执行飞行任务。如果调度器将一个字节的传输延迟哪怕只延长一个 UART 帧的时间,那么引导加载程序就可能会超时并损坏闪存。而在 rt-fc-offloader 中,从 FCSP 到 UART 的路径完全是硬件实现的——没有任务切换、没有抢占、没有抖动。

“python-imgui-esc-configurator”配套应用程序将所有这些内容整合到了一个图形用户界面中——选择电机、点击“闪存”、选择一个.hex 文件,完成即可。

本文编译自hackster.io

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

LumiBand 是一款与音乐同步的 LED 手环,专为音乐节、俱乐部和现场活动设计。它最初于 2020 年推出时仅是一款搭载 ATtiny85 微控制器、配备 15 个 NeoPixel 灯珠和一个基本电容式麦克风的产...

关键字: LED 手环 ATtiny85 微控制器

在工业伺服与电动汽车驱动领域,三相永磁同步电机(PMSM)的高性能控制离不开磁场定向控制(FOC)。随着对转速精度与动态响应要求的提升,传统的单核MCU方案已显疲态。FPGA(现场可编程门阵列)与DSP(数字信号处理器)...

关键字: FPGA 三相电机

在FPGA上构建RISC-V SoC时,从复位向量到串口打印“Hello World”的启动流程,是验证软核能否“自主呼吸”的关键。本文将基于常见的PicoRV32或VexRiscv软核,详解从硬件复位到软件驱动的完整链...

关键字: RISC-V FPGA

在软件无线电(SDR)和雷达接收机中,数字下变频(DDC)是连接高速ADC与基带处理的关键桥梁。其核心任务是将高频宽带信号搬移到基带,并降低数据率。本文将详解如何利用NCO(数控振荡器)生成正交载波,并结合CORDIC(...

关键字: FPGA DDC

在FPGA高速数据流设计中,AXI4-Stream(AXIS)是连接DMA、DSP和视频IP的“血管”。但很多工程师只关注TDATA和TLAST,却忽略了TKEEP信号,导致在非对齐数据传输时出现数据错位、CRC校验失败...

关键字: FPGA AXI4-Stream协议

在FPGA开发中,Vivado HLS(High-Level Synthesis)是将C/C++算法转化为硬件IP核的利器。然而,未经优化的C代码综合后往往性能低下。流水线(Pipelining)是打破顺序执行瓶颈、将吞...

关键字: Vivado HLS C++ FPGA

在异构计算与高速数据采集领域,PCIe Gen3 x4 提供了接近 4GB/s 的理论带宽,是连接 FPGA 与 CPU 的“高速公路”。对于大多数开发者而言,XDMA(DMA/Bridge Subsystem for...

关键字: FPGA PCIe 异构计算

在FPGA开发中,时钟域交叉(CDC)是导致亚稳态和数据错乱的“头号杀手”。当信号从clk_a跨越到异步的clk_b时,若处理不当,轻则数据跳变,重则系统死锁。本文将对比4种最核心的CDC方案,帮你从“能用”进阶到“可靠...

关键字: FPGA CDC 时钟域交叉

这是一个使用 RT-Spark(Spark-1)开发板的简单用户界面(UI)项目,该开发板采用的是 STM32F407ZGT6 微控制器芯片。该项目专注于读取开关输入,并通过控制 LED 和在 RT-Spark 内置的液...

关键字: 开发板 微控制器 STM32F407ZGT6

在基于STM32的嵌入式开发中,RAM(随机存取存储器)是影响系统性能和稳定性的核心资源之一。与PC端动辄数GB的内存不同,STM32系列微控制器的RAM容量通常在几KB到几百KB之间,部分高端型号可达数MB。有限的资源...

关键字: RAM 微控制器
关闭