版本协议

CC BY-NC-SA 4.0

标签
专业版
#第11届立创电赛#没什么用的电流表EMME-A3.0-REV1

创建时间:3个月前

描述

<h1>EMME_A3.0 — USB 3.0 Type-A 直通式电流表</h1> <p><img src="https://image.lceda.cn/oshwhub/pullImage/1e86ba56c778460bb66bf9143dbc7674.jpg" alt="正面亮屏.jpg"></p> <p><span style="color:#C0C0C0;">> <strong>项目代号</strong>:EMME_A3.0_Rev1.0 > <strong>产品类型</strong>:USB 3.0 Type-A 直通式电流表 > <strong>硬件平台</strong>:STM32F103CBT6 > <strong>设计起始</strong>:2026 年 6 月</span></p> <hr> <h2>1. 项目功能介绍</h2> <h3>1.1 项目背景与目标</h3> <p>本项目 <strong>EMME_A3.0</strong> 是一款 <strong>USB 3.0 Type-A 直通式电流表</strong>,设计目标为:</p> <ul> <li><strong>串联测量</strong>:Type-A 公头接入主机(PC/充电器),Type-A 母座接入负载设备,对通过线缆的 <strong>电压、电流、功率</strong> 进行实时测量,USB 差分信号(DP/DN/SSTX/SSRX)全部直通,不干扰正常数据传输。</li> <li><strong>高精度</strong>:采用 TI INA226 高精度电流传感器 + 10mΩ 采样电阻,配合 16 位 ΔΣ ADC,实现 高精度测量。</li> <li><strong>本地显示</strong>:内置 1.47 英寸 ST7789 彩屏(172×320, RGB666),以科技风格深色 UI 实时显示测量数据。</li> <li><strong>电量累计</strong>:支持充电状态的自动检测与 mAh/mWh 累计,方便评估电池实际容量。</li> <li><strong>温度监测</strong>:板载 TMP112 温度传感器,实时监测模块工作温度。</li> <li><strong>上位机通信</strong>:通过 USB Type-C 接口(支持正反插两种连接方式)与 PC 通信,配合 Web 上位机实现参数读写、多点校准、数据记录导出等功能。</li> <li><strong>配置持久化</strong>:校准系数、配置信息、刷新率等参数存入 AT24C02C EEPROM,掉电不丢失。</li> </ul> <h3>1.2 解决的问题</h3> <table> <tr> <th>问题场景</th> <th>EMME_A3.0 的解决方案</th> </tr> <tr> <td>低成本</td> <td>基于 STM32F103 + INA226 方案,BOM 成本低</td> </tr> <tr> <td>USB 3.0 高速信号传输</td> <td>完整直通 USB 3.0 差分线(SSTX/SSRX),阻抗匹配 90Ω</td> </tr> <tr> <td>通过Web上位机记录历史数据</td> <td>配套 Web 上位机,支持 CSV 数据导出</td> </tr> <tr> <td>校准过程复杂,需要专业设备</td> <td>上位机支持多点校准(最小二乘法线性拟合),使用普通万用表即可完成</td> </tr> <tr> <td>线缆发热但无法感知</td> <td>板载温度传感器</td> </tr> </table> <h3>1.3 核心功能一览</h3> <ul> <li>✅ <strong>实时电压测量</strong>(0~36V,1.25mV 分辨率)</li> <li>✅ <strong>实时电流测量</strong>(±8.192A,约 0.25mA 分辨率)</li> <li>✅ <strong>实时功率计算</strong>(电压 × 电流)</li> <li>✅ <strong>充电累计</strong>(mAh / mWh)</li> <li>✅ <strong>运行时间统计</strong>(总运行时长 / 充电时长)</li> <li>✅ <strong>温度监测</strong>(宽温度范围采样)</li> <li>✅ <strong>USB 线缆插入检测</strong>(DP/DN 电压采样)</li> <li>✅ <strong>多点校准</strong>(电压增益/偏移、电流增益/偏移,EEPROM 存储)</li> <li>✅ <strong>UI 可配置</strong>(刷新率、屏幕方向)</li> <li>✅ <strong>双通道上位机通信</strong>(CH340X 串口 + STM32 USB CDC)</li> </ul> <hr> <h2>2. 项目属性</h2> <ul> <li><em>本项目为首次公开</em>:项目此前未在任何公开平台(如 GitHub、Gitee、立创开源平台、电子发烧友等)发布源码或设计文档。</li> <li><em>项目为完全原创</em>:硬件原理图、PCB 设计、固件代码、上位机软件、UI 设计均由作者独立完成,未复制、引用或改编任何现有开源项目的核心代码或设计。</li> <li><em>项目未在其他比赛中获奖</em>:项目未参加过任何电子设计竞赛、创客大赛、创新创业比赛等赛事,亦未获得任何奖项。</li> <li><em>项目未在学校参加过答辩</em>:项目不属于课程设计、毕业设计、科研项目,未在学校或相关机构进行过答辩或评审。</li> </ul> <hr> <h2>3. 开源协议</h2> <p>本项目采用 <strong><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank">CC BY-NC-SA 4.0</a></strong> 协议开源:</p> <table> <tr> <th>条款</th> <th>含义</th> </tr> <tr> <td><strong>BY</strong>(署名)</td> <td>使用时需注明原作者(ElinM)及项目来源</td> </tr> <tr> <td><strong>NC</strong>(非商业性使用)</td> <td>不得用于任何商业目的,包括但不限于产品销售、商业演示、付费课程等</td> </tr> <tr> <td><strong>SA</strong>(相同方式共享)</td> <td>基于本项目的衍生作品必须以相同协议(CC BY-NC-SA 4.0)发布</td> </tr> </table> <hr> <h2>4. 硬件部分</h2> <h3>4.1 硬件架构概述</h3> <p>EMME_A3.0 采用 <strong>串联式</strong> 电压电流采样架构:USB Type-A 公头接入信号源(如 PC 或充电器),USB Type-A 母座接入负载设备。VBUS 线路中串联 10mΩ 采样电阻,由 INA226 传感器检测电压降来计算电流,同时测量负载端电压。USB 数据差分线(USB 2.0 DP/DN 和 USB 3.0 SSTX/SSRX)全部直通并通过 90Ω 阻抗匹配。</p> <div style="font-family:'system-ui', sans-serif;padding:16px;color:#1e293b;"> <div style="text-align:center;font-size:16px;font-weight:700;margin-bottom:16px;">USB 功率监测仪 · 系统架构图</div> <div style="margin:10px 0;"> <div style="border:2px solid #8b5cf6;background:#faf5ff;padding:10px 14px;text-align:center;min-width:120px;"> <div style="font-size:10px;color:#64748b;">Host / Power</div> <div style="font-size:13px;font-weight:700;margin:3px 0;">USB Type-A 公头</div> <div style="font-size:11px;color:#475569;">主机 / 电源输入</div> </div> <div style="font-size:11px;color:#7c3aed;font-weight:600;"> VBUS<span style="width:30px;height:2px;background:#8b5cf6;"></span>10mΩ<span style="width:30px;height:2px;background:#8b5cf6;"></span>VBUS </div> <div style="border:2px solid #8b5cf6;background:#faf5ff;padding:10px 14px;text-align:center;min-width:120px;"> <div style="font-size:10px;color:#64748b;">Load / Device</div> <div style="font-size:13px;font-weight:700;margin:3px 0;">USB Type-A 母座</div> <div style="font-size:11px;color:#475569;">负载设备连接</div> </div> </div> <div style="text-align:center;color:#94a3b8;font-size:10px;margin:4px 0;">DP / DN / SSTX / SSRX 全部直通</div> <div style="margin:8px 0;"> <div style="color:#d97706;font-size:11px;font-weight:600;min-width:80px;text-align:center;">▼ 5V</div> <div style="width:120px;"></div> <div style="color:#059669;font-size:11px;font-weight:600;min-width:80px;text-align:center;">▼ ADC</div> </div> <div style="margin:10px 0;"> <div style="border:2px solid #f59e0b;background:#fffbeb;padding:10px 14px;text-align:center;min-width:120px;"> <div style="font-size:10px;color:#64748b;">Buck Converter</div> <div style="font-size:13px;font-weight:700;margin:3px 0;">LMR16006Y</div> <div style="font-size:11px;color:#475569;">5V → 3.3V 降压</div> </div> <div style="width:60px;"></div> <div style="border:2px solid #10b981;background:#ecfdf5;padding:10px 14px;text-align:center;min-width:120px;"> <div style="font-size:10px;color:#64748b;">Current/Voltage Sense</div> <div style="font-size:13px;font-weight:700;margin:3px 0;">INA226 (TI)</div> <div style="font-size:11px;color:#475569;">16-bit ΔΣ ADC</div> </div> </div> <div style="margin:8px 0;"> <div style="color:#d97706;font-size:11px;font-weight:600;min-width:80px;text-align:center;">▼ 3.3V 供电</div> <div style="width:120px;"></div> <div style="color:#0284c7;font-size:11px;font-weight:600;min-width:80px;text-align:center;">▼ I²C1</div> </div> <div style="margin:10px 0;"> <div style="border:2px solid #0ea5e9;background:#f0f9ff;padding:14px;text-align:center;min-width:560px;"> <div style="font-size:10px;color:#64748b;">Main Controller</div> <div style="font-size:13px;font-weight:700;margin:3px 0;">STM32F103CBT6</div> <div style="font-size:11px;color:#475569;margin-bottom:10px;">ARM Cortex-M3 · 72MHz · 128KB Flash · 20KB RAM</div> <div> <div style="background:#fff;border:1px solid #e2e8f0;padding:6px;font-size:10px;"> <b style="color:#0284c7;font-size:11px;margin-bottom:2px;">SPI1</b> → TFT 显示屏<br>实时波形 </div> <div style="background:#fff;border:1px solid #e2e8f0;padding:6px;font-size:10px;"> <b style="color:#0284c7;font-size:11px;margin-bottom:2px;">I²C1</b> ← INA226<br>← EEPROM<br>← TMP1xx </div> <div style="background:#fff;border:1px solid #e2e8f0;padding:6px;font-size:10px;"> <b style="color:#0284c7;font-size:11px;margin-bottom:2px;">USART3</b> ← CH340X<br>← 上位机 </div> <div style="background:#fff;border:1px solid #e2e8f0;padding:6px;font-size:10px;"> <b style="color:#0284c7;font-size:11px;margin-bottom:2px;">USB CDC</b> ← Type-C<br>备用通道 </div> <div style="background:#fff;border:1px solid #e2e8f0;padding:6px;font-size:10px;"> <b style="color:#0284c7;font-size:11px;margin-bottom:2px;">ADC1</b> → USB 检测<br>→ 辅助监测 </div> </div> </div> </div> </div> <h3>4.2 核心模块</h3> <h4>电源模块</h4> <p><strong>LMR16006Y</strong>(TI):同步降压转换器,开关频率 2.1MHz,输入范围 4~60V,从 USB VBUS(5V)降压至 3.3V,为全板数字电路供电。采用 4.7μH 功率电感和紧凑的 SOT-23-6 封装。</p> <h4>电流测量模块</h4> <p><strong>INA226</strong>(TI):16 位 ΔΣ ADC 数字电流/电压/功率传感器,最高 36V 共模电压,I²C 接口。通过开尔文连接(Kelvin Connection)从 10mΩ 采样电阻(2512 封装,1% 精度)的两端直接引出差分信号,确保高精度测量。</p> <p><strong>TMP112</strong>:板载温度传感器,12-bit 分辨率(0.0625°C),通过 I²C1 与 INA226 共享总线。</p> <h4>显示模块</h4> <ul> <li><strong>1.47 英寸 TFT LCD</strong>,驱动 IC 为 <strong>ST7789V3</strong>,分辨率 172×320,支持 <strong>RGB666</strong>(18-bit/像素)色彩格式。</li> <li>通过 <strong>SPI1</strong>(PA5 SCK / PA7 MOSI)以单线模式通信,SPI 时钟 18MHz。</li> <li>采用 <strong>DMA 双缓冲 Ping-Pong 机制</strong>传输像素数据,CPU 填充缓冲区的同时 DMA 传输上一帧数据,大幅提升屏幕刷新效率。</li> <li>支持 <strong>FXAA 抗锯齿</strong>颜色混合,实现平滑的圆角矩形和高质量文字渲染。</li> <li>屏幕驱动采用自定义的 <strong>深色科技风 UI 设计系统</strong>,参考 Composio 设计理念。</li> </ul> <h4>通信模块(双通道)</h4> <ul> <li><strong>主通道 — CH340X 串口</strong>:USB Type-C 正插时,CH340X(WCH)将 USB 信号转换为 UART 信号,连接 STM32 USART3(PB10 RX / PB11 TX),呈现为标准 COM 端口,兼容几乎所有串口调试工具和 Web Serial API。</li> <li><strong>备用通道 — STM32 USB CDC</strong>:USB Type-C 反插时,STM32 内置 USB 全速接口(PA11 DM / PA12 DP)直接以 CDC(虚拟串口)模式通信,无需额外芯片。</li> </ul> <h4>存储模块</h4> <p><strong>AT24C02C</strong>(256 字节 EEPROM,SOT23-5),I²C 接口,挂载在 I²C1 总线上(与 INA226/TMP1xx 共用),用于存储校准系数、屏幕亮度、刷新率、显示页面等用户配置。</p> <h4>USB 线缆检测</h4> <p>通过 STM32 <strong>ADC1</strong>(PB0 → ADC1_IN8 检测 D-,PB1 → ADC1_IN9 检测 D+)采样 USB 差分线上的电压,任一引脚电压 > 0.8V 即判定 USB 线缆已插入。</p> <h3>4.3 关键引脚分配</h3> <table> <tr> <th>功能</th> <th>引脚</th> <th>说明</th> </tr> <tr> <td>LCD DC</td> <td>PA3</td> <td>数据/命令选择</td> </tr> <tr> <td>LCD CS</td> <td>PA4</td> <td>片选</td> </tr> <tr> <td>LCD RES</td> <td>PA6</td> <td>复位</td> </tr> <tr> <td>LCD BLK</td> <td>PA1</td> <td>背光控制</td> </tr> <tr> <td>SPI1_SCK</td> <td>PA5</td> <td>SPI 时钟</td> </tr> <tr> <td>SPI1_MOSI</td> <td>PA7</td> <td>SPI 数据输出</td> </tr> <tr> <td>I2C1_SCL</td> <td>PB6</td> <td>I²C 时钟</td> </tr> <tr> <td>I2C1_SDA</td> <td>PB7</td> <td>I²C 数据</td> </tr> <tr> <td>USART3_RX</td> <td>PB10</td> <td>串口接收 (CH340X)</td> </tr> <tr> <td>USART3_TX</td> <td>PB11</td> <td>串口发送 (CH340X)</td> </tr> <tr> <td>USB_DP</td> <td>PA12</td> <td>USB 差分对+</td> </tr> <tr> <td>USB_DM</td> <td>PA11</td> <td>USB 差分对-</td> </tr> <tr> <td>ADC1_IN8</td> <td>PB0</td> <td>USB D- 检测</td> </tr> <tr> <td>ADC1_IN9</td> <td>PB1</td> <td>USB D+ 检测</td> </tr> <tr> <td>OSC_IN/OUT</td> <td>PD0/PD1</td> <td>8MHz 晶振</td> </tr> <tr> <td>SWD_IO/CLK</td> <td>PA13/PA14</td> <td>调试接口</td> </tr> </table> <hr> <h2>5. 软件部分</h2> <h3>5.1 整体架构</h3> <p>软件采用 <strong>五层分层架构</strong>,从下至上依次为硬件层 → HAL 层 → 驱动层 → 任务层 → 应用层,各层职责清晰、松耦合,便于维护和扩展。</p> <div style="font-family:'system-ui', sans-serif;padding:16px;color:#1e293b;"> <div style="border:2px solid #8b5cf6;background:#faf5ff;padding:16px;margin:8px 0;"> <div style="text-align:center;font-size:14px;font-weight:700;color:#5b21b6;margin-bottom:12px;">APP 层(应用逻辑)</div> <div> <div style="border:1.5px solid #a78bfa;background:#fff;padding:10px;min-width:140px;"> <div style="font-size:12px;font-weight:700;color:#6d28d9;margin-bottom:6px;">测量任务层</div> <div style="font-size:11px;color:#475569;line-height:1.6;"> - INA226 读取<br> - 温度读取<br> - USB 检测<br> - 电量累计 </div> </div> <div style="border:1.5px solid #a78bfa;background:#fff;padding:10px;min-width:140px;"> <div style="font-size:12px;font-weight:700;color:#6d28d9;margin-bottom:6px;">显示任务层</div> <div style="font-size:11px;color:#475569;line-height:1.6;"> - UI 页面渲染<br> - DMA 屏幕刷新<br> - FXAA 抗锯齿<br> - 数值格式化 </div> </div> <div style="border:1.5px solid #a78bfa;background:#fff;padding:10px;min-width:140px;"> <div style="font-size:12px;font-weight:700;color:#6d28d9;margin-bottom:6px;">通信任务层</div> <div style="font-size:11px;color:#475569;line-height:1.6;"> - 串口命令解析/执行<br> - USB CDC 数据处理<br> - 校准协议处理<br> - 响应生成 </div> </div> </div> </div> <div style="border:2px solid #f59e0b;background:#fffbeb;padding:14px;margin:8px 0;text-align:center;"> <div style="font-size:14px;font-weight:700;color:#92400e;margin-bottom:6px;">TASK 层(任务调度)</div> <div style="font-size:12px;color:#78350f;">main_task_init() / main_task()</div> <div style="font-size:11px;color:#a16207;margin-top:4px;">时间片轮询:10ms 采集 / 50ms 显示 / 10ms 通信</div> </div> <div style="border:2px solid #10b981;background:#ecfdf5;padding:14px;margin:8px 0;text-align:center;"> <div style="font-size:14px;font-weight:700;color:#065f46;margin-bottom:6px;">DRV 层(硬件驱动)</div> <div style="font-size:12px;color:#047857;">INA226 | NextLCD (ST7789) | AT24C02C | TMP1xx | Protocol</div> </div> <div style="border:2px solid #0ea5e9;background:#f0f9ff;padding:14px;margin:8px 0;text-align:center;"> <div style="font-size:14px;font-weight:700;color:#075985;margin-bottom:6px;">HAL 层(硬件抽象层)</div> <div style="font-size:12px;color:#0369a1;">STM32CubeF1 HAL + LL: I2C1, SPI1, USART3, USB, ADC1, DMA1</div> </div> <div style="border:2px solid #64748b;background:#f1f5f9;padding:14px;margin:8px 0;text-align:center;"> <div style="font-size:14px;font-weight:700;color:#334155;margin-bottom:6px;">硬件层</div> <div style="font-size:12px;color:#475569;">STM32F103CBT6 (72MHz, 128KB Flash, 20KB SRAM)</div> </div> </div> <h3>5.2 主循环流程图(时间片轮询)</h3> <p>本项目不使用 RTOS,而是采用基于 SysTick(<code>HAL_GetTick()</code>)的 <strong>时间片轮询调度</strong> 机制,在 <code>while(1)</code> 主循环中按不同时间间隔执行各任务:</p> <div style="font-family:'system-ui', sans-serif;padding:16px;color:#1e293b;"> <div style="border:2px solid #6366f1;background:#eef2ff;padding:16px;margin:8px 0;"> <div style="text-align:center;font-size:14px;font-weight:700;color:#3730a3;margin-bottom:14px;">while(1) 主循环</div> <div style="border:1.5px solid #818cf8;background:#fff;padding:12px;margin:10px 0;"> <div style="font-size:12px;font-weight:700;color:#4338ca;margin-bottom:8px;">每 10ms: 传感器采集任务</div> <div style="font-size:11px;color:#475569;line-height:1.7;padding-left:8px;"> ├── INA226: 读取电压 → 应用校准系数<br> ├── INA226: 读取电流 → 应用校准系数<br> ├── INA226: 读取功率<br> ├── 电量累计 (mAh/mWh, 充电时累加)<br> ├── TMP1xx: 读取温度 (每500ms一次)<br> └── ADC1: 采样 DP/DN 电压 → USB 插入检测 </div> </div> <div style="border:1.5px solid #818cf8;background:#fff;padding:12px;margin:10px 0;"> <div style="font-size:12px;font-weight:700;color:#4338ca;margin-bottom:8px;">每 50ms: 显示刷新任务</div> <div style="font-size:11px;color:#475569;line-height:1.7;padding-left:8px;"> └── UI_RefreshValues() 局部刷新显示数值 </div> </div> <div style="border:1.5px solid #818cf8;background:#fff;padding:12px;margin:10px 0;"> <div style="font-size:12px;font-weight:700;color:#4338ca;margin-bottom:8px;">每 10ms: 串口通信处理任务</div> <div style="font-size:11px;color:#475569;line-height:1.7;padding-left:8px;"> └── Protocol_Process() 处理 USART3 + USB CDC </div> </div> <div style="border:1.5px solid #818cf8;background:#fff;padding:12px;margin:10px 0;"> <div style="font-size:12px;font-weight:700;color:#4338ca;margin-bottom:8px;">每 1s: 精确秒计时</div> <div style="font-size:11px;color:#475569;line-height:1.7;padding-left:8px;"> ├── g_run_seconds++ (总运行时间)<br> └── g_charge_seconds++ (充电时间) </div> </div> </div> </div> <h3>5.3 功能模块说明</h3> <h4>5.3.1 INA226 电流传感器驱动</h4> <ul> <li><strong>初始化</strong>:发送复位命令 → 计算并写入 CALIBRATION 寄存器 → 配置 CONFIG 寄存器(PGA 量程、ADC 转换时间、平均次数、运行模式)</li> <li><strong>关键参数</strong>:10mΩ 采样电阻,最大预期电流 8.192A,PGA=00 (±40mV),256 次平均</li> <li><strong>计算公式</strong>: <ul> <li>电流分辨率 = iMaxExcepted / 32768 = 8.192 / 32768 ≈ 0.25mA/bit</li> <li>功率分辨率 = 25 × 电流分辨率</li> <li>Calibration = 0.00512 / (Current_LSB × R_shunt)</li> </ul></li> <li><strong>错误处理</strong>:每次读取均检查 HAL 返回值,失败时保持上次有效值并递增 I²C 故障计数器</li> </ul> <h4>5.3.2 显示驱动</h4> <ul> <li><strong>色彩格式</strong>:RGB666(18-bit/像素),提供 262144 色,远高于普通 RGB565 的 65536 色</li> <li><strong>DMA 双缓冲 Ping-Pong</strong>:4KB 缓冲区分为两个半区,CPU 与 DMA 交替填充/传输,有效隐藏缓冲区填充开销</li> <li><strong>FXAA 抗锯齿</strong>:通过 Alpha 混合前景色与背景色,实现平滑的圆角矩形边框和高质量文字渲染</li> <li><strong>字体</strong>:等距更纱黑体 SCsarasa-mono-sc-regular / GrayBits4</li> <li><strong>UI 设计</strong>:深色科技风,电压/电流/功率三参数框分别使用柔亮橙/绿/蓝色调,右侧面板显示累计电量和运行时间</li> </ul> <h4>5.3.3 EEPROM 配置管理(AT24C02C)</h4> <p><strong>存储布局</strong>(256 字节):</p> <table> <tr> <th style="text-align:center;">地址</th> <th>字段</th> <th style="text-align:center;">类型</th> <th>说明</th> </tr> <tr> <td style="text-align:center;">0x00~0x01</td> <td>魔数</td> <td style="text-align:center;">uint16</td> <td>0x454D("EM"),数据有效性校验</td> </tr> <tr> <td style="text-align:center;">0x02</td> <td>版本号</td> <td style="text-align:center;">uint8</td> <td>当前为 v3</td> </tr> <tr> <td style="text-align:center;">0x03~0x04</td> <td>电压增益</td> <td style="text-align:center;">int16</td> <td>Q15 定点数</td> </tr> <tr> <td style="text-align:center;">0x05~0x06</td> <td>电压偏移</td> <td style="text-align:center;">int16</td> <td>mV 单位</td> </tr> <tr> <td style="text-align:center;">0x07~0x08</td> <td>电流增益</td> <td style="text-align:center;">int16</td> <td>Q15 定点数</td> </tr> <tr> <td style="text-align:center;">0x09~0x0A</td> <td>电流偏移</td> <td style="text-align:center;">int16</td> <td>mA 单位</td> </tr> <tr> <td style="text-align:center;">0x0B</td> <td>屏幕亮度</td> <td style="text-align:center;">uint8</td> <td>0~100</td> </tr> <tr> <td style="text-align:center;">0x0C</td> <td>刷新率档位</td> <td style="text-align:center;">uint8</td> <td>0~5</td> </tr> <tr> <td style="text-align:center;">0x0D</td> <td>显示页面</td> <td style="text-align:center;">uint8</td> <td>当前选中页</td> </tr> <tr> <td style="text-align:center;">0x0E</td> <td>过流阈值</td> <td style="text-align:center;">uint8</td> <td>A×10</td> </tr> <tr> <td style="text-align:center;">0x0F</td> <td>过压阈值</td> <td style="text-align:center;">uint8</td> <td>V×10</td> </tr> <tr> <td style="text-align:center;">0x10</td> <td>屏幕方向</td> <td style="text-align:center;">uint8</td> <td>0=正向, 1=反向</td> </tr> <tr> <td style="text-align:center;">0x11~0x14</td> <td>INA226 参数</td> <td style="text-align:center;">uint8×4</td> <td>BADC / SADC / AVG / PGA</td> </tr> <tr> <td style="text-align:center;">0x15~0x16</td> <td>充电参数</td> <td style="text-align:center;">uint8×2</td> <td>充电电压阈值 / 迟滞时间</td> </tr> </table> <p>上电时读取魔数进行校验,无效则写入默认配置。</p> <h4>5.3.4 通信协议</h4> <p><img src="https://image.lceda.cn/oshwhub/pullImage/497c8d9186db4dd58a47e03de218a142.png" alt="屏幕截图 2026-08-16 222253.png"></p> <p>协议帧格式:<code>$COMMAND PARAM *CS\r\n</code></p> <table> <tr> <th>字段</th> <th>说明</th> </tr> <tr> <td><code>$</code></td> <td>帧起始符(PROTOCOL_HEADER)</td> </tr> <tr> <td><code>COMMAND PARAM</code></td> <td>命令码 + 参数字符串</td> </tr> <tr> <td><code>*</code></td> <td>校验和分隔符(PROTOCOL_DELIMITER)</td> </tr> <tr> <td><code>CS</code></td> <td>2 字节十六进制 XOR 校验和</td> </tr> <tr> <td><code>\r\n</code></td> <td>帧结束符</td> </tr> </table> <p><strong>支持命令</strong>:</p> <table> <tr> <th>命令</th> <th>参数</th> <th>说明</th> </tr> <tr> <td><code>READ VER</code></td> <td>—</td> <td>读取固件版本号</td> </tr> <tr> <td><code>READ V</code></td> <td>—</td> <td>读取当前电压</td> </tr> <tr> <td><code>READ A</code></td> <td>—</td> <td>读取当前电流</td> </tr> <tr> <td><code>READ W</code></td> <td>—</td> <td>读取当前功率</td> </tr> <tr> <td><code>READ CONF</code></td> <td>—</td> <td>读取配置参数</td> </tr> <tr> <td><code>READ CALI</code></td> <td>—</td> <td>读取校准系数</td> </tr> <tr> <td><code>READ TMP</code></td> <td>—</td> <td>读取温度</td> </tr> <tr> <td><code>WRIT BRIGHT</code></td> <td><code>0~100</code></td> <td>设置屏幕亮度</td> </tr> <tr> <td><code>WRIT REFRESH</code></td> <td><code>0~5</code></td> <td>设置刷新率档位</td> </tr> <tr> <td><code>CALI VG</code></td> <td><code>浮点数</code></td> <td>设置电压增益</td> </tr> <tr> <td><code>CALI VO</code></td> <td><code>浮点数</code></td> <td>设置电压偏移</td> </tr> <tr> <td><code>CALI CG</code></td> <td><code>浮点数</code></td> <td>设置电流增益</td> </tr> <tr> <td><code>CALI CO</code></td> <td><code>浮点数</code></td> <td>设置电流偏移</td> </tr> <tr> <td><code>CALI SAVE</code></td> <td>—</td> <td>保存校准系数到 EEPROM</td> </tr> </table> <p><strong>双重通信通道</strong>:USART3(CH340X)和 USB CDC 均使用相同的协议栈,通过独立的状态机并行处理。</p> <h4>5.3.5 多点校准机制</h4> <ol> <li>连接 Web 上位机,读取当前 INA226 原始值</li> <li>将设备接入已知基准源(精密万用表),在上位机中填入参考值</li> <li>至少采集 2 个校准点,上位机使用 <strong>最小二乘法</strong> 计算线性拟合参数(增益和偏移)</li> <li>将校准系数通过 <code>$CALI</code> 命令下发至 MCU</li> <li><code>$CALI SAVE</code> 将系数写入 EEPROM,下次上电自动生效</li> </ol> <h3>5.4 源码结构</h3> <pre><code>EMME_A3.0_Rev1.0/ ├── Core/ │ ├── Inc/ ← CubeMX 生成的头文件(main.h, i2c.h, spi.h 等) │ └── Src/ │ ├── main.c ← 主入口:外设初始化 → main_task_init() → 主循环 │ ├── main_task.c ← 任务核心:初始化编排 + 时间片轮询 │ ├── main_task.h ← 任务头文件:全局变量声明 + 函数接口 │ └── stm32f1xx_it.c ← 中断服务函数 ├── Software/ │ ├── protocol.c ← 通信协议实现:状态机解析 + 命令执行 │ └── protocol.h ← 协议定义:帧格式 + 命令枚举 ├── Hardware/ │ ├── ina226/ │ │ ├── ina226.c ← INA226 驱动:寄存器读写 + 初始化/重配置 + 数据读取 │ │ └── ina226.h ← 寄存器地址 + 配置宏定义 │ ├── at24c02/ │ │ ├── at24c02.c ← EEPROM 驱动:字节/页读写 + 配置管理 │ │ └── at24c02.h ← 存储布局地址 + 配置结构体 │ ├── tmp1xx/ │ │ ├── tmp1xx.c ← 温度传感器驱动 │ │ └── tmp1xx.h │ └── nextlcd/ │ ├── nextlcd_init.c/.h ← ST7789 屏幕初始化(RGB666 模式配置) │ ├── nextlcd.c/.h ← 绘图 API(填充、DMA 传输、FXAA、文字显示) │ └── lcdfont.c/.h ← 字体字库 ├── USB_DEVICE/ │ ├── App/ │ │ ├── usb_device.c/.h ← USB 设备初始化 │ │ ├── usbd_desc.c/.h ← USB 设备描述符 │ │ └── usbd_cdc_if.c/.h ← CDC 接口实现(USB 串口收发) │ └── Target/ │ ├── usbd_conf.c/.h ← USB 底层配置 ├── web-serial-tool/ ← Web 上位机(纯前端) │ ├── index.html ← 页面结构 │ ├── script.js ← 核心逻辑(通信、校准、数据记录) │ ├── style.css ← 样式(深色科技风) │ └── README.md ← 使用说明 ├── drivers/ ← HAL 库、CMSIS(STM32CubeMX 自动生成) ├── datasheet/ ← 器件数据手册 ├── cmake/ ← CMake 构建配置 ├── build/ ← 构建输出目录 ├── EMME_A3.0_Rev1.0.ioc ← STM32CubeMX 工程配置 ├── EMME_A3.0_Rev1.0_HardwareDesign.md ← 硬件设计文档 ├── EMME_A3.0_Rev1.0_SoftwareDesign.md ← 软件设计文档 └── design_zh.md ← UI 设计系统规范</code></pre> <h3>5.5 开发环境与依赖工具</h3> <table> <tr> <th>工具</th> <th>版本</th> <th>用途</th> </tr> <tr> <td><strong>STM32CubeMX</strong></td> <td>6.12.0</td> <td>外设配置、时钟树生成、初始化代码生成</td> </tr> <tr> <td><strong>STM32CubeF1</strong></td> <td>V1.8.7</td> <td>HAL/LL 固件库</td> </tr> <tr> <td><strong>VS Code</strong></td> <td>—</td> <td>代码编辑与开发</td> </tr> <tr> <td><strong>CMake</strong></td> <td>—</td> <td>构建系统</td> </tr> <tr> <td><strong>ARM GCC</strong></td> <td>arm-none-eabi-gcc</td> <td>编译工具链</td> </tr> <tr> <td><strong>Chrome/Edge</strong></td> <td>89+</td> <td>运行 Web 上位机(需支持 Web Serial API)</td> </tr> </table> <h3>5.6 程序烧录方法</h3> <p><strong>SWD 烧录</strong>:</p> <ul> <li>使用 ST-Link V2/V3 调试器通过USB Type-C SBU1、SBU2 连接到 MCU 的 SWD 接口(PA13 SWDIO / PA14 SWCLK / 3.3V / GND)</li> <li>使用STM32CubeProgrammer 烧录 <code>.bin</code>/<code>.hex</code> 文件</li> </ul> <h3>5.7 关键算法说明</h3> <h4>时间片轮询调度</h4> <pre><code class="language-c">#define TASK_IS_DUE(last, interval) (HAL_GetTick() - (last) &gt;= (interval))</code></pre> <p>该机制避免了 RTOS 的上下文切换开销,在 STM32F103(20KB SRAM)的资源限制下实现了多任务并发执行。</p> <h4>INA226 校准计算</h4> <pre><code>Current_LSB = iMaxExcepted / 32768 = 8.192 / 32768 ≈ 0.25mA/bit Calibration = 0.00512 / (Current_LSB × R_shunt) = 0.00512 / (0.00025 × 0.01) = 2048 I_measured = Raw_Current_Register × Current_LSB V_measured = Raw_BusVoltage_Register × 1.25mV</code></pre> <h4>多点校准(最小二乘法线性拟合)</h4> <p>设原始测量值为 x,基准参考值为 y,收集 n 组数据点 (xᵢ, yᵢ),则:</p> <ul> <li><strong>增益(斜率)</strong>:G = (n·Σ(xᵢyᵢ) − Σxᵢ·Σyᵢ) / (n·Σ(xᵢ²) − (Σxᵢ)²)</li> <li><strong>偏移(截距)</strong>:O = (Σyᵢ − G·Σxᵢ) / n</li> </ul> <p>校准后实际值 = x × G + O,此系数存入 EEPROM,上电自动生效。</p> <hr> <h2>6. BOM 清单</h2> <p>根据硬件设计文档中的网表纲要,核心物料清单如下:</p> <table> <tr> <th style="text-align:center;">序号</th> <th>器件类别</th> <th>型号/规格</th> <th>封装</th> <th style="text-align:center;">数量</th> <th>说明</th> </tr> <tr> <td style="text-align:center;">1</td> <td>主控 MCU</td> <td><strong>STM32F103CBT6</strong></td> <td>LQFP48</td> <td style="text-align:center;">1</td> <td>Cortex-M3, 128KB Flash, 20KB SRAM</td> </tr> <tr> <td style="text-align:center;">2</td> <td>电流传感器</td> <td><strong>INA226AIDGSR</strong></td> <td>MSOP-10</td> <td style="text-align:center;">1</td> <td>16-bit ΔΣ ADC, I²C, 36V 共模</td> </tr> <tr> <td style="text-align:center;">3</td> <td>温度传感器</td> <td><strong>TMP112</strong></td> <td>SOIC-8</td> <td style="text-align:center;">1</td> <td>12-bit I²C 数字温度传感器</td> </tr> <tr> <td style="text-align:center;">4</td> <td>降压转换器</td> <td><strong>LMR16006YDDCR</strong></td> <td>SOT-23-6</td> <td style="text-align:center;">1</td> <td>2.1MHz, 4~60V 输入, 3.3V/600mA 输出</td> </tr> <tr> <td style="text-align:center;">5</td> <td>USB 转串口</td> <td><strong>CH340X</strong> (WCH)</td> <td>MSOP-10</td> <td style="text-align:center;">1</td> <td>USB↔UART 桥接芯片</td> </tr> <tr> <td style="text-align:center;">6</td> <td>EEPROM</td> <td><strong>AT24C02C-SSHM-T</strong></td> <td>SOT23-5</td> <td style="text-align:center;">1</td> <td>2Kbit (256B) I²C EEPROM</td> </tr> <tr> <td style="text-align:center;">7</td> <td>采样电阻</td> <td><strong>10mΩ, 1%, 3W</strong></td> <td>2512</td> <td style="text-align:center;">1</td> <td>金属合金, 低温漂</td> </tr> <tr> <td style="text-align:center;">8</td> <td>晶振</td> <td>8MHz, ±20ppm</td> <td>5032/3225</td> <td style="text-align:center;">1</td> <td>外部高速晶振</td> </tr> <tr> <td style="text-align:center;">9</td> <td>TFT 屏幕</td> <td><strong>1.47" ST7789V3</strong></td> <td>FPC 8P</td> <td style="text-align:center;">1</td> <td>RGB666 彩色 TFT LCD</td> </tr> <tr> <td style="text-align:center;">10</td> <td>USB Type-A 公头</td> <td>3.0 夹板公头</td> <td>夹板</td> <td style="text-align:center;">1</td> <td>0.8mm 板厚</td> </tr> <tr> <td style="text-align:center;">11</td> <td>USB Type-A 母座</td> <td>3.0 夹板母座</td> <td>夹板</td> <td style="text-align:center;">1</td> <td>0.8mm 板厚</td> </tr> <tr> <td style="text-align:center;">12</td> <td>USB Type-C 插座</td> <td>16P 夹板</td> <td>沉板0.8mm</td> <td style="text-align:center;">1</td> <td>上位机通信</td> </tr> <tr> <td style="text-align:center;">13</td> <td>电感</td> <td><strong>4.7μH, 饱和 ≥800mA</strong></td> <td>1210/2520</td> <td style="text-align:center;">1</td> <td>降压转换器功率电感</td> </tr> <tr> <td style="text-align:center;">14</td> <td>三极管</td> <td>S8050</td> <td>SOT-23</td> <td style="text-align:center;">1</td> <td>屏幕背光控制</td> </tr> <tr> <td style="text-align:center;">15</td> <td>电容/电阻</td> <td>0402/0603 封装</td> <td>0402</td> <td style="text-align:center;">若干</td> <td>去耦、滤波、上拉等</td> </tr> </table> <p>> <strong>注</strong>:以上为 BOM 纲要,完整物料清单以原理图和设计文件为准。</p> <hr> <h2>7. 大赛logo验证</h2> <p><img src="https://image.lceda.cn/oshwhub/pullImage/72d9e83976bd47febf68b23be6edecf8.jpg" alt="MVIMG_20260902_001228.jpg"></p> <hr> <h2>8. 更新日志</h2> <ul> <li>20260814 项目首次发布,编写文档</li> <li>20260816 bin固件、Web上位机发布,文档有误处修正</li> <li>20260818 文档流程图修整</li> <li>20260826 感谢@an2921指出PCB文件存在问题,已修复</li> <li> <h2>20260902 上传大赛logo验证图片</h2> </li> </ul> <h2>9. 写在最后</h2> <p>感谢你能读到这里,如果你觉得本项目不错那么欢迎你动手制作;如果你觉得文档中有不清楚的地方欢迎在评论区指出;如果你觉得想要实现某些功能或者发现存在Bug也欢迎在评论区提出,我会尽快修复<span style="color:#C0C0C0;">(也许XD</span></p>

文档

BOM

附件

附件名 下载
EMME_A3.0_Rev1.0.bin
web-serial-tool.zip

成员

评论(29)

  • 表情
    emoji
    小嘉工作篇
    小嘉日常篇
  • 图片
成功
工程所有者当前已关闭评论
an2921 回复
<p>大佬好,没固件吗?</p>
em_16x 回复
<p>你好,今晚会上传固件然后重新完善文档,预计下周一审核好[emojis:玫瑰]</p>
an2921 回复
<p>谢谢大佬分享!</p>
em_16x 回复
<p>你好,明天(8.17)上午应该就能审核好,固件和Web上位机都上传了,你如果有兴趣制作请务必了解本项目存在的一些问题,包括不限于烧录方式、功能存在问题等[emojis:看]</p>
fnicer 回复
<p>这UI设计,这布线风格,简直是艺术品</p>
an2921 回复
<p>大佬好!这部分电路主要起什么作用呢?<img title="点击查看大图" src="https://image.lceda.cn/oshwhub/pullImage/b07fc2c61bd749e2bc3d51849033bbb3.png" alt="" /></p>
elinm 回复
<p>分立元件实现的理想二极管</p>
elinm 回复
<p>作用就是防止USBA上可能存在的高压倒灌进USBC口的电源引脚</p>
an2921 回复
<p>多谢大佬解惑!</p>
em_16x 回复
<p>感谢认可~[emojis:玫瑰]</p>
an2921 回复
<p>大佬好!打板选多厚?是0.8mm吗?</p>
em_16x 回复
<p>是的,0.8mm,目前硬件上有一点问题,CH340到STM32 TXRX没有交换还没有修复(不过可以用STM32虚拟串口);然后我对目前结构厚度不是很满意还想改改,不过功能上暂时没问题,不在意这些问题的话可以打板;有时间我会重新画板并发布1.2版本[emojis:我想静静]</p>
an2921 回复
<p>好的!谢谢大佬</p>
an2921 回复
<p>大佬好!CH340到STM32 TXRX没有交换还没有修复,是什么意思啊?是硬件线路布线错了,还是说软件上ch340到stm32之间通讯没调通?只要不影响烧录固件就可以了!</p>
an2921 回复
<p>麻烦再请假一下大佬!没看明白烧录,使用 ST-Link V2/V3 调试器通过USB Type-C SBU1、SBU2 连接到 MCU 的 SWD 接口(PA13 SWDIO / PA14 SWCLK / 3.3V / GND)这句话,不知道typec USB线怎么和 ST-Link V2/V3 调试器杜邦线插头连接呢?板子上没看到烧录固件的排针,是焊接到引脚烧录吗?</p>
em_16x 回复
<p>是这样,你的问题我逐个解答:<br/>1.“CH340到STM32 TXRX没有交换还没有修复”,指的是CH340 TX错误的连接了STM32 TX,同理RX连接了RX,正常接线应该交换线序的,所以目前接错了,不能通信;但是原来预留了STM32 CDC虚拟串口,所以可以通过typec翻个面插入,来进行该表到上位机的通信;<br/>2.我没有在板子上预留常见的烧录过孔,而是把SWDIO、SWCLK连接到SBU1、SBU2,然后在外面用一个“typec全引脚转xh2.54”的小板来把相应的引脚引出的;当然了,你直接把STLINK的SWDIO、SWCLK、GND焊接到板上烧录也可以</p>
em_16x 回复
<p>理论上你只需要自制一个这个:<a href="https://oshwhub.com/u3g7/st-link-v2_cc" target="_blank" rel="noreferrer noopener">https://oshwhub.com/u3g7/st-link-v2_cc</a><br/>就可以直接把这个插在本项目C口上进行烧录了</p>
an2921 回复
<p>多谢大佬细心解惑!都明白了!</p>
em_16x 回复
<p>乐意至极[emojis:奋斗]</p>
an2921 回复
<p>麻烦大佬给看一下,屏幕焊盘这里的GND把2,3,4都连在一起,给短路了呢?还是我搞错了!<img title="点击查看大图" src="https://image.lceda.cn/oshwhub/pullImage/ba850532b10746adbfc9e1ff178e0712.png" alt="" /></p>
em_16x 回复
<p>神了,不知道怎么搞的,确实有错,我修复了<img title="点击查看大图" src="https://image.lceda.cn/oshwhub/pullImage/d384111eac5f46b8b8386754eb350b36.png" alt="" /></p>
an2921 回复
<p>谢谢,大佬真是神速,我看ch340到stm32的RXD,TXD,的交叉问题还没修改吧?</p>
em_16x 回复
<p>对,上班摸鱼改了下,那个问题比较麻烦下次改[emojis:哭笑]不过其实功能不影响</p>
an2921 回复
<p>好的!谢谢大佬</p>
hdrss 回复
<p>能麻烦大佬做成TYPC的吗。加入Cc1 Cc2电压[emojis:色]检测</p>
em_16x 回复
<p>下次做,目前有DPDN电压检测,除了CC电压检测还想要啥功能[emojis:看]</p>
立创电赛 回复
<p>logo验证需要上传实物图哦</p>
em_16x 回复
<p>感谢指出,已上传</p>
linggiet 回复
<p>同求一个C-C的版本,这都写的很详细,很方便学习了</p>
goToTop
svg-battery svg-battery-wifi svg-books svg-more svg-paste svg-pencil svg-plant svg-ruler svg-share svg-user svg-logo-cn svg-double-arrow