单向 DSHOT 输出实现概要设计

目录

  1. DSHOT 协议概述
  2. 总体设计思路
  3. 方案一:GPTMR + DMA
  4. 方案二:I2S 移位输出
  5. 方案三:PWM + DMA + HRAM(双比较 + 影子寄存器)
  6. 方案四:PWMV2 + DMAV2(FIX_BURST,1 路 DMA 服务 4 路 PWM)
  7. 方案对比与选型建议
  8. 共性关键设计点

1. DSHOT 协议概述

DSHOT(Digital Shot)是无刷电调(ESC)的数字油门协议。每帧固定 16 bit,MSB 先发,无起始/停止位,靠帧间空闲(低电平)分帧:

图 1-1 DSHOT 帧格式(16 bit)

每个 bit 采用脉宽编码,以固定的位周期 T 为时间基准:

  • 位周期 T:每一个 DSHOT bit(不论 0 还是 1)都占用同一个完整的位周期 T,由所选速率等级决定(见下表),bit 之间连续发送、无间隔;
  • 数据靠高电平宽度判决:在一个位周期 T 之内,高电平持续时间决定该 bit 的值 —— bit1 高电平 ≈ 75% T(低电平补足剩余 ≈25% T),bit0 高电平 ≈ 37.5% T(低电平补足剩余 ≈62.5% T)。

注意:“bit 0 的 T”指的就是这个完整的位周期 T,并非只有 37.5% T;37.5% T 只是 bit0 的高电平宽度,其余时间均为低电平,二者共同凑满一个 T。电调(ESC)判决阈值约 50%,实际实现有较大容差,例程中 2/3、5/8 等占空比均可被正确识别。

图 1-2 DSHOT 位编码波形

速率等级 位速率 位周期 T 一帧时长(16 bit)
DSHOT150 150 kbps 6.67 μs 106.7 μs
DSHOT300 300 kbps 3.33 μs 53.3 μs
DSHOT600 600 kbps 1.67 μs 26.7 μs
DSHOT1200 1200 kbps 0.83 μs 13.3 μs

2. 总体设计思路

单向 DSHOT 的本质是:以固定位周期连续输出 16 个宽度可变的脉冲。软件位翻转(bit-bang)无法满足 μs 级精度且占用 CPU,因此所有方案都遵循同一个模式:

图 2-1 通用实现模型

四种实现方式的差异只在于"波形发生器"与"供数方式"的组合:

方案 波形发生器 供数方式 可变量
① GPTMR + DMA GPTMR 输出比较 DMA 逐周期更新 CMP 比较值(脉宽)
② I2S I2S 移位寄存器 FIFO(CPU 或 DMA 填充) 位图(1 个 DSHOT 位 = 16 个 BCLK 位)
③ PWM + DMA PWM 输出比较(4 通道) 4 路 DMA 各自更新 1 路 CMP 比较值(脉宽)
④ PWMV2 + DMAV2 PWMV2 输出比较(8 通道) 1 路 DMAV2 FIX_BURST 更新 8 路 CMP 比较值(脉宽)

3. 方案一:GPTMR + DMA

3.1 原理

将 GPTMR 通道配置为输出比较模式,计数器 RELOAD 为 1 个位周期 T。GPTMR 比较器有两个关键特性:① 计数器计数到任一个比较值 CMP,通道输出即翻转一次;② 当 CMP0 = 32'hFFFFFFFF 时,通道输出强制保持为逻辑 0(初始极性)——空闲(IDLE)即利用此特性:此时即使 CMP1 每周期仍匹配一次,输出也被锁定为 0,不会产生有效脉冲。初始极性为低(cmp_initial_polarity_high = 0),故每周期先到 CMP1 = T/3 翻为高、再到 CMP0 翻回低

正是这两个特性决定了比较器分工:把 CMP1 固定为 T/3 作为每个位的边界(每周期必翻转一次、产生位起点),而只改变 CMP0 来调节脉宽——发送 bit 时 CMP0 取 T−12T/3 产生"翻回低"的数据沿;空闲时 CMP0 取 0xFFFFFFFF,数据沿永不产生,输出恒为逻辑 0(空闲电平)。由于 GPTMR 没有影子寄存器(见下方约束),单个 DSHOT 位必须跨两个定时器周期实现——详见图 3-2。

  • 以计数时钟 100 MHz 为例:RELOAD = 83 ≈ DSHOT1200,RELOAD = 166 ≈ DSHOT600;
  • 固定比较点 CMP1 = T/3 每周期把输出翻为(即每个位的起点 / 位边界);CMP0 由 DMA 在每个重载事件刷新,决定输出翻回的时刻(脉宽结束沿),从而决定高电平宽度:bit"1" → CMP0 = T−1(结束沿推到接近位尾,高电平最长 ≈ 2/3T),bit"0" → CMP0 = 2T/3(结束沿靠前,高电平最短 ≈ 1/3T);电调(ESC)只需测量高电平持续时间(从 CMP1 翻高到 CMP0 翻低)即可判决:≈2/3T 判为 1、≈1/3T 判为 0。
  • DMA 请求源选择 gptmr_dma_request_on_reload,即每个位周期开始瞬间把下一位的比较值写入 CMP0 寄存器(目的地址固定、源地址递增、handshake 模式);
  • 缓冲区共 18 个字[0][17]0xFFFFFFFFCMP0 = 32'hFFFFFFFF → 比较器永不命中,输出被强制为逻辑 0,即空闲电平),中间 16 个字对应 16 个数据位;缓冲区放在 AHB SRAM(ATTR_PLACE_AT(".ahb_sram"))以保证 DMA 零等待访问。

关键约束:GPTMR 无影子寄存器 → 必须跨周期实现

GPTMR 的比较器没有影子寄存器:软件 / DMA 写入 CMP0立即生效,无法像 PWM 那样等到周期边界再统一加载。若试图在单个定时器周期内同时表达"位起点电平 + 位中数据沿",中途改写 CMP 会当拍影响当前位、产生毛刺。

解决方式:把 1 个 DSHOT 位拆到"跨两个定时器周期"。以固定比较点 CMP1 = T/3 作为位边界(每周期必触发一次),数据沿由 CMP0 产生;于是"本周期 T/3 → 下一周期 T/3" 恰好等于一个完整 DSHOT 位周期(宽度 = 1 个定时器周期 T,但相对重载点偏移了 T/3)。DMA 在每次重载点写入的 CMP0 作用于当前周期内的数据沿,与位窗口天然对齐,全程无需中途改写。该方案采用等效脉宽编码:电调(ESC)只需测量高电平持续时间(位边界 CMP1 翻高 → 数据沿 CMP0 翻低)即可判决 0/1,与标准 DSHOT 兼容。

图 3-1 GPTMR + DMA 数据通路框图

图 3-2 GPTMR 跨周期生成单 bit 时序(无影子寄存器,CMP 写入立即生效)

3.2 发送流程

  1. 停止计数器并复位计数值(gptmr_stop_counter / gptmr_channel_reset_count);
  2. 按 MSB first 将 16 bit 帧展开为比较值数组,首尾填空闲值;
  3. 重设 DMA 源地址与传输长度(18 字),使能 DMA 通道;
  4. 启动计数器,硬件自动逐位发送;DMA 完成中断可用作"帧发送完成"标志。

3.3 资源占用与评价

项目 每路电机占用
定时器 1 个 GPTMR 通道(1 个 GPTMR 外设含 4 通道)
DMA 1 个 DMA 通道 + 1 个 DMAMUX 通道
CPU 仅帧编码(每帧一次,约数十条指令)

优点: 实现最简单、任意 GPTMR 引脚可用、单路资源少。
局限: 多路电机之间无硬件同步(各通道独立启动);4 路电机需 4 个 GPTMR 通道 + 4 个 DMA 通道。


4. 方案二:I2S 移位输出

4.1 原理

把 DSHOT 波形当作"数字音频流":1 个 DSHOT 位展开成 16 个 BCLK 位的位图,由 I2S 移位寄存器按位时钟恒速移出。占空比由位图中 1 的个数决定:

  • bit"1" → 0xFFC0(前 10 位高、后 6 位低,高电平 62.5% T);
  • bit"0" → 0xFC00(前 6 位高、后 10 位低,高电平 37.5% T);
  • BCLK = 16 × DSHOT 位速率。例:DSHOT2400 → BCLK = 38.4 MHz,由音频 PLL 精确产生(614.4 MHz ÷ 16);配置上采样率 = 位速率 ÷ 每帧通道数,通道长度/位深均为 16 bit,MSB_JUSTIFIED 协议、主机模式;
  • I2S 外设具有 4 条 TX 数据线(TXD0~3),共用同一 BCLK/FCLK,天然支持 4 路严格同步输出;
  • 一帧 DSHOT = 16 位 × 16 bit 位图 = 256 BCLK = 每线 8 个 32 bit FIFO 字,一次性写入 FIFO 即可。

图 4-1 I2S 实现 DSHOT 框图(位图展开 + 4 线同步输出)

4.2 发送流程

  1. 配置音频 PLL 与 I2S 分频,使 BCLK 精确等于 16 × 位速率;
  2. 帧编码后按"U32 传输字序"把 16 个位图交织写入缓冲(例程中偶/奇半字对调以匹配 FIFO 字序);
  3. i2s_stop → 向 4 条线各写 8 个字 → i2s_start,移位输出;
  4. 等待 FIFO 水位下降后,各线补写一个 0,保证发送完成后数据线保持空闲低电平(I2S 下溢时会重复最后数据,必须用 0 兜底)。

4.3 资源占用与评价

项目 4 路电机占用
外设 1 个 I2S(4 条 TX 数据线)
DMA 0(FIFO 深度足够容纳一整帧,CPU 直接填充;也可选配 DMA)
CPU 帧编码 + FIFO 填充(每帧 32 次寄存器写)

优点: 1 个外设带 4 路且严格同步;时钟来自音频 PLL,频率精度最高;不占 DMA。
局限: 引脚固定为 I2S TXD,灵活性差;空闲电平需软件兜底(补 0);内存放大 16 倍(每 DSHOT 位 16 bit)。


5. 方案三:PWM + DMA(双比较 + 影子寄存器)

5.1 原理

使用 1 个 PWM 外设输出 4 路 DSHOT。PWM 计数器 RELOAD = 1 个位周期 T。每路输出采用两个比较器——概念上与 GPTMR 的 CMP0/CMP1 一对完全对等:一个决定上升沿、一个决定下降沿;只是 PWM 的每个比较器都带有硬件影子寄存器,因此一个 DSHOT 位干净地落在一个周期 T 内,无需像 GPTMR 那样跨两个周期。

这 2 个比较器是 PWM 中 2 个独立的 CMP[n] 比较器通道(例如第 k 路 CMP[k] 与第 k+1 路 CMP[k+1]),每个只使用其 CMP[n] 寄存器的 CMP 位域——该寄存器虽也包含 XCMP 位域,但本方案并不使用。分工如下:

  • 固定比较器 CMP[k].CMP = 0:在每周期计数起点(count 0,即周期边界)强制输出为(上升沿),它定义了每个 DSHOT 位高脉冲的起点,固定在周期边界;
  • 可变比较器 CMP[k+1].CMP 由 DMA 逐位更新:决定输出翻回低的时刻(下降沿 / 数据沿),即高脉冲的终点
  • 输出非反转invert_output = false),重装载点把输出复位为初始低电平。

与 GPTMR 同一对比较器的差异:二者都是「固定上升沿 + 可变下降沿」的双比较结构(GPTMR 用 CMP1 固定上升、CMP0 可变下降;本方案用 CMP[k] 固定上升、CMP[k+1] 可变下降);唯一差别在于:GPTMR 无影子寄存器,上升沿只能固定在 T/3 并跨两个周期拼接 1 个位;PWM 有影子寄存器,上升沿可固定在周期起点 0、单个 bit 干净落在一个周期 T 内(无需跨周期)。

bit 取值由可变比较器 CMP[k+1].CMP 决定高电平宽度(高电平从周期起点 0 开始、到该比较值处结束):

bit 可变比较器 CMP[k+1].CMP 高电平区间 高电平宽度
1 2T/3 [0, 2T/3] ≈ 2/3 T
0 T/3 [0, T/3] ≈ 1/3 T

电调(ESC)只需测量高电平持续时间即可判决 0/1。

idle 天然为低、无需反转:空闲时把可变比较器 CMP[k+1].CMP 也置 0,使上升沿(count 0)与下降沿(count 0)重合、高脉冲宽度坍缩为 0,配合重装载点复位,输出始终停在低电平——与 DSHOT 空闲低电平要求一致。这与 GPTMR 用 CMP0 = 0xFFFFFFFF(比较值永不可达)锁低异曲同工:都是"空闲时无有效高脉冲",只是实现手段不同,都不需要 invert_output

其余要点:

  • 影子寄存器 + 周期边界锁存事件:DMA 在每个重装载点写入的可变比较值 CMP[k+1],经影子寄存器缓存在周期边界由 shadow-lock 事件原子加载到活动比较器,保证一个 bit 的比较值整周期生效、不中途改写、无毛刺。对应驱动 pwm_load_cmp_shadow_on_match(锁存点比较值 = RELOAD)、pwm_issue_shadow_register_lock_event,以及比较器的 update_trigger = pwm_shadow_register_update_on_hw_event
  • 一路 PWM 输出对应一路 DMA 通道:每路由 1 个专用触发比较器(CMP8~11)产生 DMA 请求,4 路请求时刻在 1 个位周期内错峰(见 §5.1.1);请求经 TRGM → DMAMUX → HDMA(通道 1~4)送到该路可变比较器 CMP[k+1] 的影子寄存器(目的地址固定、源地址递增、handshake);每个位周期各搬 1 个字(字的 PWM_CMP_CMP_SET 字段即 CMP[k+1] 的比较值),固定比较器 CMP[k].CMP = 0 仅在初始化时配置一次、不随 DMA 变化;
  • HRAM(AHB SRAM):缓冲放在与 HDMA 同总线域、零等待的内存(示例用 noncacheable 段;设计上推荐 .ahb_sram,见 §8.1),确保 DSHOT1200 下 4 路 DMA 并发不超时;
  • 缓冲 = 18 字/路:帧首 1 字空闲(上升沿 = 0 → idle 低)+ 16 个数据位 + 帧尾 1 字空闲(上升沿 = 0 → idle 低),首尾空闲字保证帧边界清晰、电调(ESC)可稳定分帧。

5.1.1 触发比较器与 DMA 请求错峰

每路输出各配 1 个专用触发比较器(CMP8~11),其比较值错开设置,使 4 路 DMA 请求在 1 个位周期内分散到达,避免 4 路同时请求 HDMA 造成总线争抢、比较值晚于重载点加载而出现坏位:

通道 触发比较器 比较值(计数器取值) DMA 请求时刻
ch0 CMP8 2 位起点 + 2 ticks
ch1 CMP9 4 位起点 + 4 ticks
ch2 CMP10 6 位起点 + 6 ticks
ch3 CMP11 8 位起点 + 8 ticks

表中比较值为计数器取数(从 0 起算):相邻通道错开 2 个 tick,4 路请求在 1 个位周期前段(0~8 ticks)均匀分布,避开重载边界、分散总线峰值压力,又远早于周期边界发生,保证比较值在周期边界的 shadow-lock 事件前已全部就位、原子锁存、无毛刺。

每个触发比较器命中后产生一次 DMA 请求,经 TRGM → DMAMUX → HDMA 三级路由到对应 HDMA 通道(handshake 模式、目的地址固定为 CMP[k+1] 影子、源地址递增):

#if TEST_CH0
    trgm_dma_request_config(HPM_TRGM0, TRGM_DMACFG_1, HPM_TRGM0_DMA_SRC_PWM0_CMP8);
    dmamux_config(BOARD_APP_DMAMUX, DMA_SOC_CHN_TO_DMAMUX_CHN(HPM_HDMA, 1), HPM_DMA_SRC_MOT0_1, true);
    pwm_enable_dma_request(PWM, PWM_DMAEN_CMPENX_SET(1<<8));
#endif
#if TEST_CH1
    trgm_dma_request_config(HPM_TRGM0, TRGM_DMACFG_0, HPM_TRGM0_DMA_SRC_PWM0_CMP9);
    dmamux_config(BOARD_APP_DMAMUX, DMA_SOC_CHN_TO_DMAMUX_CHN(HPM_HDMA, 2), HPM_DMA_SRC_MOT0_0, true);
    pwm_enable_dma_request(PWM, PWM_DMAEN_CMPENX_SET(1<<9));
#endif
#if TEST_CH2
    trgm_dma_request_config(HPM_TRGM0, TRGM_DMACFG_2, HPM_TRGM0_DMA_SRC_PWM0_CMP10);
    dmamux_config(BOARD_APP_DMAMUX, DMA_SOC_CHN_TO_DMAMUX_CHN(HPM_HDMA, 3), HPM_DMA_SRC_MOT0_2, true);
    pwm_enable_dma_request(PWM, PWM_DMAEN_CMPENX_SET(1<<10));
#endif
#if TEST_CH3
    trgm_dma_request_config(HPM_TRGM0, TRGM_DMACFG_3, HPM_TRGM0_DMA_SRC_PWM0_CMP11);
    dmamux_config(BOARD_APP_DMAMUX, DMA_SOC_CHN_TO_DMAMUX_CHN(HPM_HDMA, 4), HPM_DMA_SRC_MOT0_3, true);
    pwm_enable_dma_request(PWM, PWM_DMAEN_CMPENX_SET(1<<11));
#endif
  • pwm_enable_dma_request(PWM, PWM_DMAEN_CMPENX_SET(1 << n)):使能第 n 个触发比较器(CMP8~11 对应 bit8~11)的 DMA 请求;
  • trgm_dma_request_config(...):把 PWM 的 CMPn DMA 源(HPM_TRGM0_DMA_SRC_PWM0_CMP8~11)绑定到某个 TRGM 输出(TRGM_DMACFG_0~3,例程中 MOT0_x 对应的 DMACFG 索引);
  • dmamux_config(...):把该 TRGM 输出路由到 DMAMUX 的 HPM_DMA_SRC_MOT0_0~3,最终送达 HPM_HDMA 通道 1~4。

4 路 HDMA 通道各自 handshake 搬运 1 个字到对应 CMP[k+1] 影子寄存器后,由周期边界的 shadow-lock 事件统一加载,形成"错峰供数 → 统一锁存"的时序:既分散了总线峰值压力,又保证所有通道的比较值在周期边界原子生效、无毛刺。

5.2 发送流程

  1. 初始化:配置 4 路输出波形(可变比较器 CMP[k+1] update_trigger = on_hw_event、固定比较器 CMP[k].CMP = 0 一次写定)与影子锁存点;配置每路专用触发比较器与 TRGM/DMAMUX 路由,使能 PWM DMA 请求;
  2. 每帧:编码 → 填 4 份 18 字缓冲(首字 / 末字 = 0 → idle 低)→ 重配并使能 4 个 HDMA 通道 → 发出 shadow-lock 事件后启动计数器;
  3. 4 个 HDMA 均产生 TC(传输完成)中断后本帧结束,输出停在空闲电平。

5.3 资源占用与评价

项目 4 路电机占用
PWM 1 个 PWM 外设:8 个比较器(4 路 × 2:固定 CMP[k]=0 + 可变 CMP[k+1]=DMA)+ 4 个触发比较器(+ 1 个共享的影子锁存比较点)
DMA 4 个 HDMA 通道 + 4 个 DMAMUX 通道 + 4 个 TRGM DMA 路由
内存 4 × 18 字 @ HRAM

主要痛点: DMA 通道消耗大——每 4 路电机需 4 个 DMA 通道;4 路请求在同一位周期密集到达,依赖 HRAM 零等待与 DMA 优先级配置保证时序余量。这正是方案四要解决的问题。


6. 方案四:PWMV2 + DMAV2(DST_FIXBURST,1 路 DMA 服务 8 路 PWM)

6.1 原理

波形生成部分与方案三同构:PWMV2 计数器 RELOAD 为 位周期 T,每路输出各用双比较点(固定比较点 = 0,上升沿落在周期起点 count 0;可变比较点 = DMA 写入的数据值,下降沿为数据沿),比较值在周期边界(shadow-lock / reload 事件)原子加载,非反转、idle 低,一个 DSHOT 位干净落在一个周期 T 内(无需跨周期)。差异全部在供数通路上:

  • PWMV2 原生 DMA 请求选择:通过 DMA_EN 寄存器直接选择"哪个比较点或重载点"产生 DMA 请求(pwmv2_enable_dma_at_reload_point 选重载点;例程选 cmp0 == 0,即每个位周期起点 count 0)。与方案三不同,这里只需 1 个请求源、每个位周期 1 次请求,即可驱动全部 8 路;
  • DMAV2 的 DST_FIXBURST:置位 DST_FIXBURSTdma_set_dst_fixed_burst)后,每次 DMA 请求搬运一个 burst = 通道数 字的突发——burst 内目的地址递增(依次写入 CMP[0]、CMP[1]、…、CMP[7] 这 8 个连续比较寄存器),burst 结束后目的地址回卷到 CMP[0],等待下一次请求。例程取 burst = 8(= 8 路);
  • 源缓冲按位交织排布:例程把 16 个 bit × 8 路共 128 字排在 HRAM,布局为 HRAM[bit_k * 0x20 + ch_i * 4]——即以 bit 为主序、路为次序[bit15_ch0, bit15_ch1, …, bit15_ch7, bit14_ch0, …])。每个 burst(8 字)正好是一"位"的 8 路数据;
  • 帧边界由计数器 BURST 模式界定:例程不靠缓冲区里的空闲字,而是把每个 PWM 计数器配置为 CNT_BURST = 16——计数器发出 16 个位周期后自动停止。因此缓冲只需 16 个数据位(无需方案三的 2 字空闲填充),发完 16 个 burst 后计数器停在 idle 低电平;
  • 结果:1 路 HDMA 通道即可为全部 8 路 PWM 通道供数,即"用 1 路 DMA 通道 + 1 次 FIX_BURST 把全部路的同 bit 数据一次性搬入 CMP[0..7]"。

图 6-1 PWMV2 + DMAV2 框图(HPM6E00 上即 HDMA;1 路 DMA 经 MOT_GPR/DMAMUX 服务 8 路 PWM)

图 6-2 方案三 / 方案四供数通路对比

6.2 关键配置点(以 8 路为例)

配置项 取值 / 接口 说明
DMA 请求源 pwmv2_enable_dma_at_reload_point() 或选 cmp0 == 0 每个位周期起点 1 次请求
请求路由 DMAMUX(例程经 MOT_GPR 触发矩阵 → DMAMUX → HDMA ch0) PWMV2 请求线仍需路由到 HDMA
burst 长度 = 通道数(例程 8,对应 src_burst_size 8 beats) 一次请求写完全部路的同 bit CMP
DST_FIXBURST dma_set_dst_fixed_burst(ptr, ch, true) burst 内 dst++ 写 CMP[0..7],burst 间 dst 回卷
目的地址 CMP[0] 比较寄存器基址(8 个连续) 要求被服务比较器地址连续
源地址 HRAM,递增,位交织 128 字 [bit_k * 8 + ch_i],16 bit × 8 路
计数器 BURST pwmv2_set_counter_burst(cnt, 16) 发满 16 位后自动停,界定帧边界
影子加载 周期边界(reload / shadow-lock)统一加载 保证 8 路脉宽同周期原子更新

6.3 资源占用与评价(8 路)

项目 8 路电机占用
PWMV2 1 个外设:8 路输出,每路 2 比较点(固定=0 上升沿 + 可变=DMA 下降沿)+ 1 个 DMA 请求线
DMA 1 个 HDMA 通道(即 DMAV2 实例,对比方案三节省 3 个)
内存 128 字交织缓冲 @ HRAM(16 bit × 8 路;无空闲填充,靠计数器 BURST 界定帧)

优点: 资源效率最高的 PWM 类方案——8 路同步(同一组计数器 + 同点加载),仅 1 个 DMA 通道即服务全部 8 路(burst = 8),请求链路最短;FIX_BURST 把"1 次请求 → N 路同 bit"打包,总线峰值远低于方案三的 4 路错峰。
局限: 仅支持带 DMAV2 的新系列(如 HPM6E00/HPM5E00 等);要求被服务的比较器(CMP[0..N-1])地址连续。


7. 方案对比与选型建议

维度(按 4 路电机) ① GPTMR+DMA ② I2S ③ PWM+DMA+HRAM ④ PWMV2+DMAV2+HRAM
波形外设 4 个 GPTMR 通道 1 个 I2S(4 线) 1 个 PWM(4 输出·各 2 个独立 CMP + 影子寄存器) 1 个 PWMV2(4 输出·各 2 个独立 CMP + 影子寄存器)
DMA 通道 4 0 4 1
多路同步性 无硬件同步 严格同步(同移位时钟) 同步(同计数器) 同步(同计数器)
引脚灵活性 高(任意 GPTMR 引脚) 低(固定 I2S TXD) 中(PWM 引脚) 中(PWM 引脚)
每帧 CPU 开销 中(填 FIFO 32 次写)
内存开销 18 字/路 8 字/路(位图放大 16×) 18 字/路 64 字(4 路交织,16 字/路;8 路例程 128 字)
频率精度 受总线时钟整除限制 最高(音频 PLL 可微调) 受总线时钟整除限制 受总线时钟整除限制
芯片依赖 全系列 带多线 I2S 的系列 带 PWM(v1) 系列(HPM6700/6300 等) 带 PWMV2/DMAV2 系列(HPM6E00 等,HPM6E00 上 DMAV2 即 HDMA)
典型场景 单路/散点电机、引脚受限 四轴飞控、DMA 紧张、要求极致同步 PWM(v1) 平台的四电机方案 新平台四/八电机,资源最优

8. 共性关键设计点

8.1 缓冲区放置(HRAM)

  • DMA 源缓冲统一放 AHB SRAM(ATTR_PLACE_AT(".ahb_sram")):与 HDMA 同总线域、零等待,避免高位速率下因总线争抢导致比较值更新晚于重载点而出现坏位;
  • 若使用带 cache 的内存,需保证 DMA 一致性(clean cache 或使用 noncacheable 段)。

首选 HRAM(HDMA + AHB SRAM): HDMA 与 AHB SRAM 属于同一总线域,DMA 读写缓冲零等待、带宽最足,存取效率最高,是 DSHOT 高位速率(DSHOT1200+)下最稳妥的放置方式。

不要用 XDMA 或 AXI-SRAM: XDMA 或挂在 AXI-SRAM(AXI 总线域)上的缓冲,相对 HDMA + HRAM 组合效率明显更低——跨总线域访问有额外延迟、且易与 CPU/其它主设备争抢 AXI 带宽。在 DSHOT 位周期很短(微秒级)的约束下,这类放置可能因一次 DMA 搬运耗时过长、来不及在周期边界的 shadow-lock 事件前把 CMP 比较值更新就位,导致输出坏位甚至整帧错乱。因此源缓冲务必放在 HRAM,使"错峰供数 → 统一锁存"的时序始终有余量。

8.2 DMA 的选择

四类方案的差异最终都收敛到"由谁、用什么 DMA、在何时把比较值搬进 CMP 影子寄存器",选型要点:

  • DMA 控制器选型:PWM 类方案(方案③④)优先选与 HRAM 同总线域、零等待的 HDMA;PWMV2 方案进一步利用 DMAV2FIX_BURST 特性(见 §6),在一个 burst 内连续写 4 个 CMP 影子寄存器,使通道数与请求次数都降到 1/4;
  • DMA 请求源:统一在"位周期起点附近"产生——方案①③用定时器重载点(gptmr_dma_request_on_reload / PWM 重载事件),方案③的 4 路还通过在 1 个位周期内错峰(CMP8~11 比较值取 2/4/6/8)分散请求,避免 4 路同时抢占 HDMA 总线;
  • 传输参数:均为 handshake 模式目的地址 = 对应 CMP 影子寄存器(固定)源地址递增;每个位周期搬运 1 个字(方案③)或 1 个 burst 含 4 个字(方案④);
  • 通道数权衡:方案③「1 路输出对应 1 路 DMA 通道」实现简单、各路独立,但 4 路电机吃 4 个通道;方案④ 用 DMAV2 FIX_BURST「1 路 DMA 通道服务 4 路 PWM」,显著省通道。DMA 控制器的能力(是否支持 FIX_BURST / 多比较器请求)直接决定方案的可扩展性——这也是方案四相对方案三的核心改进点。

0
0

订阅

发表回复 0

Your email address will not be published. Required fields are marked *

captcha
Enter the characters shown in the image:
Reload

This CAPTCHA helps ensure that you are human. Please enter the requested characters.