Bug 故事:两个 DAC 通道并联,我改了 5 个地方才修好(改了5个地方才修好)
📅 2026/7/7 5:33:31
👁️ 次浏览
tags: 嵌入式,调试,DAC,SPI,多通道,Bug故事 category: 嵌入式 type: original series: debug-troubleshootBug 故事两个 DAC 通道并联我改了 5 个地方才修好改了5个地方才修好一句话: 为了输出更大的电流把 DAC 的两个通道并联使用。写完通道 A 之后忘记同步写通道 B导致只有一半电流输出。这个 bug 藏在 5 个代码位置里——初始化、设定值、递增、递减、协议解析——花了三个小时排完。系列文章《嵌入式调试排错》 — 编译错误、看门狗、DAC踩坑、协议对齐——真实Bug故事排查方法论 一个宏搞定 全网独家解决方案 ✅ 改了5个地方才修好 15条指令找出7处错误背景为什么要并联电路里需要驱动一个负载最大 600mA。但单片 DAC 每个通道只能输出 300mA。硬件同事的办法把两个 DAC 通道的输出引脚焊在一起让它们并联供电。CH3 出 300mACH4 也出 300mA合起来 600mA。原理没问题但固件里埋了一个坑。坑写完通道 A忘了通道 B这个 DAC 是通过 SPI 总线控制的。设定电流值时写一个寄存器就完事// 单通道模式300mA 量程 void DAC_SetCurrent(uint8_t u8Channel, uint16_t u16Code) { SPI_CS_Low(); SPI_Write(u8Channel, u16Code); // 通道 A SPI_CS_High(); }当 CH3 和 CH4 并联使用时你脑子里知道它们是同一个东西。所以写代码的时候自然就写成// 并联模式 — 初始版本有 bug void SOA_SetCurrent(uint16_t u16Code) { SPI_CS_Low(); SPI_Write(CH3, u16Code); // 写完通道 A // 忘了写通道 B SPI_CS_High(); }结果只有通道 A 在输出电流通道 B 还在输出上次的值。负载只拿到一半电流。这个问题本身不难发现——如果代码只有一个地方写电流值的话。为什么修了 5 个地方一个真实的嵌入式项目里设定电流值不是只有一个入口的。我翻了一遍代码发现电流值可以从这几个地方被改变位置场景1初始化— 上电默认值2直接设定— 串口发命令设电流 XXX3递增— 串口发命令电流 104递减— 串口发命令电流 -105协议批量写入— 上位机一口气写多个参数这 5 个位置每个都只写了通道 A没写通道 B。修法是一样的——每个位置加一行写通道 B// 修好之后 SPI_Write(CH3, u16Code); // 通道 A SPI_Write(CH4, u16Code); // 通道 B — 一个字节都不能少修完第 1 个位置用串口直接设定电流对了。修完第 2 个递增也对。修到第 5 个——上位机批量写入——才发现还有一个遗漏。5 个位置全修完三个小时过去了。教训怎么避免这种 bug1. 封装不要撒胡椒如果一开始就把并联写入封装成一个函数void DAC_WriteDualChannel(uint16_t u16Code) { SPI_CS_Low(); SPI_Write(CH3, u16Code); SPI_Write(CH4, u16Code); SPI_CS_High(); }然后所有地方只调这个函数——bug 根本不存在。撒胡椒式地到处写 SPI_Write出了问题只能在每一处补。2. 不要靠脑子记硬件细节CH3 和 CH4 是并联的——这个信息只存在脑子里不在代码里。过三个月换个同事维护他看到SPI_Write(CH3, code)会自然认为这就够了。用宏定义把这个关系显式化#define DAC_CH_SOA_A CH3 #define DAC_CH_SOA_B CH4 #define DAC_SOA_IS_DUAL 1 // 标记这个通道是并联的3. 并联通道应该强制同步最彻底的修法在 DAC 驱动的初始化时标记哪些通道是并联的。写任意一个时自动同步另一个。这样上层代码完全不需要知道并联这件事// 驱动层 — 自动同步并联通道 void DAC_WriteChannel(uint8_t u8Ch, uint16_t u16Code) { SPI_CS_Low(); SPI_Write(u8Ch, u16Code); // 查同步表这通道有没有并联的兄弟 uint8_t u8Partner g_au8SyncPartner[u8Ch]; if (u8Partner ! 0xFF) { SPI_Write(u8Partner, u16Code); // 自动同步 } SPI_CS_High(); }硬件细节封装在驱动层上层代码完全不用关心。总结教训一句话封装并联写入应该是一个函数不是到处撒的 SPI_Write显式化硬件细节写在宏里不要只存脑子里同步机制并联关系应该在驱动层自动处理上层无知这个 bug 不是技术多难而是一个硬件细节泄露到了 5 个代码位置。封装做好的话它根本不会发生。实测对比封装前: 5处代码各自写SPI_Write | 封装后: 1个函数统一处理bug永久消灭有用的话点个收藏下次调试直接用。有问题欢迎评论区交流看到了都会回。下一篇《一个宏搞定》——编译错误、看门狗、DAC踩坑、协议对齐——真实Bug故事排查方法论
1. 项目概述:为什么“跨平台移植Modbus”这件事,值得花半小时认真对待Modbus协议本身不挑平台——它只认功能码、寄存器地址、CRC校验和字节序。但真正让工程师头皮发紧的,从来不是协议本身,而是把一套在STM32上跑得稳如老狗的Mod…
📅 2026/7/7 5:31:31
如今,越来越多的人选择走出国门求学深造、海外就业或是开启长期旅居生活,毕业证相关的涉外认证手续,早已成为留学申请、海外学历核验、跨国签证办理环节中不可或缺的核心材料。不少第一次接触这类业务的人,常常会把公证、海牙认证…
📅 2026/7/7 5:31:31
一、病因与分类血小板增多症在儿童中可分为原发性和继发性两大类。继发性血小板增多症更为常见,多由感染、贫血、缺铁、外伤或手术等因素诱发,通常不伴有严重的血栓或出血事件。一旦原发病因得到控制,血小板计数可恢复正常,预后良…
📅 2026/7/7 5:31:31
KLayout Python API生产环境实战:自动化版图处理架构深度解析 【免费下载链接】klayout KLayout Main Sources 项目地址: https://gitcode.com/gh_mirrors/kl/klayout
KLayout Python API(pya)为集成电路版图设计提供了企业级的自动化…
📅 2026/7/7 11:22:37
前言
在Linux的世界里,文本编辑器是每位开发者、运维人员最亲密的伙伴。无论你是编写代码、修改配置文件,还是记录笔记,都离不开一款趁手的编辑器。
今天,我们将系统学习Linux中最核心的两类编辑器——Vim(专业级&…
📅 2026/7/7 11:22:37
终极微信小程序图表库指南:wx-charts完整教程 【免费下载链接】wx-charts 微信小程序图表库,Charts for WeChat Mini Program 项目地址: https://gitcode.com/gh_mirrors/wx/wx-charts
微信小程序开发中,数据可视化一直是开发者面临的…
📅 2026/7/7 11:22:37
快速发展的社会中,人们的生活水平都在提高,生活节奏也在逐渐加快。为了节省时间和提高工作效率,越来越多的人选择利用互联网进行线上打理各种事务,然后线上管理系统也就相继涌现。与此同时,人们开始接受方便的生活方式…
📅 2026/7/7 11:22:37
BMS 电流标定策略基于量产 60V BMS(STM32F072 SH367306 2,0.5mΩ 采样电阻),拆解电流采样链路的完整标定策略。涵盖四层处理的物理根源、工程考量与取舍逻辑。一、问题的起点:0.5mΩ 上的 15mV
先建立一个量级概念。…
📅 2026/7/7 11:22:37
模型降级策略:服务可用,不等于回答质量可以随便降
一、模型降级不能只按价格从高到低切
大模型应用为了控成本和保障可用性,通常会准备多个模型。主模型超时或限额时,切到便宜模型或本地小模型。这个策略有用,但不能简…
📅 2026/7/7 11:20:36
CentOS SSH连接故障排查:从基础检查到深度修复的完整指南引言当你尝试通过Xshell或其他SSH客户端连接CentOS服务器时,突然遭遇"Connection refused"或"Connection timed out"的错误提示,这种经历对任何运维人员或开发者来…
📅 2026/7/7 0:00:45
B站评论删除API逆向工程实战:关键参数解析与自动化操作指南1. 理解B站评论删除机制的核心逻辑在视频平台内容管理中,评论删除功能涉及复杂的权限验证和数据交互流程。B站的评论删除API采用了一套基于Web安全标准的防护机制,主要依赖三个关键参…
📅 2026/7/7 0:00:45
1. 项目概述:为什么Java安全是红蓝对抗的焦点在当前的网络安全攻防演练,也就是我们常说的红蓝对抗中,Java应用一直是双方交锋的核心战场。这不仅仅是因为Java在企业级应用、金融系统和大型互联网后台中无处不在,更因为其技术栈的复…
📅 2026/7/7 0:00:45
1. 项目背景与核心需求 在嵌入式系统开发中,快速精确的数据检索是一个常见但极具挑战性的需求。特别是在工业控制、医疗设备和物联网终端等场景下,系统往往需要在毫秒级时间内完成关键参数的读取和写入操作。传统基于Flash存储的方案存在擦写次数有限、操…
📅 2026/7/6 10:35:30
1. 工业电流环信号传输的基础认知在工业自动化领域,4-20mA电流环传输技术已经持续服役超过半个世纪。这种看似简单的信号传输方式之所以能经久不衰,核心在于其独特的抗干扰能力——电流信号在长距离传输时几乎不受线路电阻和电压波动的影响。我曾在化工厂…
📅 2026/7/7 9:08:28
最近在项目里尝试用 YOLO 做目标检测,从环境搭建到模型训练,再到推理部署,整个过程踩了不少坑。网上的资料虽然多,但要么版本老旧,要么步骤零散不成体系,对于刚入门的新手来说,很容易卡在某个环…
📅 2026/7/7 6:33:36
目录
第一步:选对模板,省心一半
第二步:打开扫码点餐功能
开启功能按钮
桌台管理与桌码生成
第三步:个性化设计,打造品牌感
调整点餐页面
设置点餐规则 你还在让顾客站着排队点餐吗?2025年ÿ…
📅 2026/7/7 9:08:31
在业务中快速构建一个能理解私有文档、准确回答专业问题的智能助手,是很多开发团队面临的共同挑战。传统方案往往需要从零开始搭建复杂的 RAG(检索增强生成)系统,涉及文档解析、向量化、检索、大模型调用等多个环节,整…
📅 2026/7/7 9:08:30
FAE放射组学分析工具:医学影像特征探索的完整解决方案 【免费下载链接】FAE FeAture Explorer 项目地址: https://gitcode.com/gh_mirrors/fae/FAE
你是否曾经面对海量医学影像数据感到无从下手?想要从CT、MRI等影像中提取有价值的定量特征&#…
📅 2026/7/7 4:32:18