
使用 MCU 的 Timer 来解析 DShot600本质上就是测量每个 bit 的高电平时间然后判断它是 0 还是 1。DShot600 实际上就是一种固定周期 PWM 编码协议。1. DShot600 时序DShot600速度600000 b i t / s 600000bit/s600000bit/s所以T b i t 1 / 600 k T_{bit}1/600kTbit1/600k得到T b i t 1.667 u s T_{bit}1.667usTbit1.667us每个bit总长度固定1.667us区别只在高电平宽度。bit高电平低电平00.625us1.042us11.25us0.417us大约0 37.5% 1 75%这就是 DShot。并不是传统 PWM。而是固定周期不同占空比编码数据类似111001010... ↓ ■■■■□□□□ ■■■■□□□□ ■■□□□□□□ ■■□□□□□□ ■■■■□□□□ ...16bit 一帧。 (NuttX)2. MCU 如何接收最简单方案Timer Input Capture捕获上升沿 下降沿记录 CNT 值。计算Ton falling-rising Tbit next_rising-current_rising然后dutyTon/Tbit判断if(duty0.55)bit1;elsebit0;结束。3. 更简单的方法实际上 DShot600bit长度固定1.667us所以根本不用测周期。只测高电平时间即可。Ton0.9us →0Ton0.9us →1阈值取(0.6251.25)/2 ≈0.94us即可。4. STM32 推荐配置例如TIM284MHzPSC0计数精度11.9ns那么0.625us ≈52counts 1.25us ≈105counts完全够。配置CH1Input Capture RisingCH2Input Capture Falling或者PWM Input ModeSTM32 自带。它会自动CCR1 period CCR2 high_time直接得到TonCCR2;TCCR1;duty(float)Ton/T;这是 STM32 官方推荐方法。 (Stm32World)5. 边沿捕获模式最常见很多 ESC 固件都是这么干。例如 AM32。DMA 保存所有边沿时间戳。然后软件解码。 (DeepWiki)假设R F R F R F ↑ ↑ ↑ ↑ ↑ ↑ 100 152 240 292 380 485代表Ton1152-10052 Ton2292-24052 Ton3485-380105对应52 52 105得到0 0 16. DMA方案推荐DShot6001.67us/bit16bit26.7us/frameCPU中断每个边沿32次IRQ 26us很容易爆。所以推荐TIM IC DMA配置Capture both edges DMA-buffer[64]自动记录t0 t1 t2 t3 ...DMA完成for(i0;i16;i){Tont[2*i1]-t[2*i];if(Tonthreshold)bit1;elsebit0;}得到16bit frame7. DShot数据格式DShotBBBBBBBBBBB T CCCC 11bit throttle 1bit telemetry 4bit crc例如10101010101 1 0110解析uint16_tframe;throttle(frame5)0x7FF;telemetry(frame4)1;crcframe0xF;CRCcrc(value^(value4)^(value8))0x0F;验证if(crc_calccrc_rx){valid1;}8. 最推荐的实现对于 STM32G431、STM32F4、ESP32-S3方案ATIM PWM Input CCR1Period CCR2HighTime IRQ解析优点简单。缺点一次只能测一个PWM。方案B最佳TIM Input Capture Both Edge DMA buffer[64] ↓ 软件解码 ↓ 16bit frame ↓ CRC校验这是目前很多 ESC如 AM32、Bluejay的接收思路。 (DeepWiki)9. STM32 代码框架volatileuint16_tcap[64];HAL_TIM_IC_Start_DMA(htim2,TIM_CHANNEL_1,cap,32);DMA完成voiddecode(){uint16_tframe0;for(inti0;i16;i){uint16_tToncap[2*i1]-cap[2*i];frame1;if(Ton80)frame|1;}check_crc(frame);}其实 DShot 接收可以总结成一句话DShot600 用 Timer 输入捕获测高电平宽度再根据 0.625us 和 1.25us 判断 0/1拼出16bit数据最后做CRC校验。这个方案比传统 UART 解码更稳也比 EXTI 中断可靠得多是 MCU 接收 DShot600 的标准做法。