STM32F103驱动ATT7022E/HT7036电能计量芯片:硬件设计、SPI驱动与校准实战
2026/8/31 20:22:42 网站建设 项目流程

简介:本资源面向嵌入式电力仪表开发工程师与高校电能计量方向学习者,提供基于STM32F103C8T6主控、ATT7022E三相电能计量芯片及HT7036电力线通信芯片的完整硬件设计与软件实现参考方案,解决电能参数高精度采集、本地处理与PLC远程传输的一体化开发难题。压缩包共494个文件,含68个C源文件(核心驱动与计量算法)、73个汇编/S文件(启动与底层配置)、87个头文件(外设寄存器定义与接口声明)、87个目标文件及4份关键PDF文档(含原理图与芯片数据手册),整体21.82MB,结构清晰覆盖硬件连接、SPI/UART通信协议栈、ATT7022E校准例程及HT7036调制解调适配代码。已有120人学习下载,用户可直接复用原理图设计、移植计量校准逻辑、调试PLC通信链路,并参考多层目录组织方式构建同类电力终端项目工程框架。

1. 项目背景与核心价值

最近在做一个智能电表数据采集的项目,核心需求是要精确测量交流电的电压、电流、功率、电能等参数。选型阶段,市面上常见的电能计量芯片如ATT7022E和HT7036进入了我的视野,而主控芯片则毫无悬念地选择了经典的“国民MCU”——STM32F103C8T6。这个组合在工控、能源管理和智能家居领域非常经典,但当你真正动手从零开始设计硬件和编写驱动时,会发现资料虽然多,却散落在各处,很多关键细节,比如SPI通信的时序稳定性、芯片校准流程的实操、以及如何有效处理ATT7022E和HT7036在寄存器配置和数据处理上的差异,都需要自己一点点摸索和踩坑。

这篇文章,我就把自己从原理图设计、PCB layout到软件驱动调试的全过程梳理一遍。重点不是简单地贴原理图和代码,而是会深入解释为什么要这样设计硬件连接,为什么软件里某个寄存器的某一位必须那样设置,以及在调试过程中遇到的那些“诡异”问题及其根因。无论你是正在做课程设计的学生,还是需要快速搭建一个高精度电量采集原型的工程师,希望这份结合了实战经验的参考能让你少走弯路,快速得到一个稳定可靠的系统。

2. 芯片选型与核心特性对比

在动手画图之前,搞清楚你手头这两颗计量芯片的“脾气”至关重要。ATT7022E和HT7036虽然功能相似,但在接口、精度和易用性上各有侧重,直接决定了你的硬件设计和软件架构。

2.1 ATT7022E:高精度与灵活性的代表

ATT7022E是一颗三相电能计量芯片,但它完全支持单相应用。我选择它,主要是看中以下几个点:

高精度与丰富参数:在1000:1的动态范围内,它能达到0.5S级的计量精度,这对于需要做电能质量分析或者高精度计费的应用来说是硬性指标。除了基本的电压、电流有效值,有功/无功/视在功率,以及有功/无功电能,它还能输出功率因数、频率等参数,寄存器配置非常灵活。

灵活的SPI接口:ATT7022E通过一个标准的SPI接口与MCU通信。这里有个关键细节:它的SPI模式固定为CPOL=0, CPHA=0(即模式0)。这意味着在时钟空闲时为低电平,数据在时钟的上升沿被采样。如果你的STM32 SPI配置错了模式,通信会完全失败。此外,它的片选信号(CS)是低电平有效,且在一次完整的读写操作期间必须保持低电平。

校表寄存器复杂但强大:ATT7022E的精度依赖于一套完整的校表流程,包括增益校正、相位校正、偏移校正等。它的校表寄存器数量多,逻辑稍显复杂,但这也意味着你可以进行非常精细的校准,以适应不同的电流互感器(CT)和电压采样网络。初次接触可能会觉得头大,但一旦掌握,它能提供的精度和适应性是值得的。

2.2 HT7036:单相应用的简洁之选

HT7036是一颗专注于单相计量的芯片,它的设计理念更偏向于“开箱即用”和低成本。

简化的数据输出:与ATT7022E需要通过SPI读取多个寄存器来拼凑数据不同,HT7036提供了脉冲输出(CF)和直接数据输出两种方式。对于很多只需要获取电能脉冲进行计数的应用,直接使用CF引脚接到STM32的外部中断或计数器输入上,软件设计会变得极其简单。它也有SPI接口,用于读取电压、电流有效值等参数,但寄存器数量比ATT7022E少得多。

内置基准与低功耗:HT7036内部集成了电压基准,这在一定程度上简化了外围电路设计。它的功耗也相对较低,对于电池供电或低功耗要求的场景更有优势。

快速启动与校准:HT7036的启动和初始校准过程通常比ATT7022E更快,校表寄存器也更直观,对于快速原型开发或者对校准流程经验不足的开发者更友好。

2.3 STM32F103C8T6:可靠的控制核心

选择“蓝桥杯”神板的核心MCU,理由很充分:性价比极高、资源丰富、生态完善。72MHz的主频足够处理计量芯片的数据并进行初步运算;拥有多个SPI接口,可以轻松对接ATT7022E或HT7036;充足的GPIO和定时器资源,可以用来捕获HT7036的CF脉冲,或者控制继电器、液晶显示等外围设备;并且,基于HAL库或标准外设库的开发资料浩如烟海,遇到问题几乎都能找到解决方案。

选型决策逻辑: 如果你的项目需求是高精度、三相或未来可能扩展至三相、需要进行复杂的电能质量分析,那么ATT7022E是更专业的选择。你需要投入更多时间在复杂的SPI驱动和校表算法上。 如果你的项目是典型的单相用电计量、需求快速上线、对成本敏感、或者主要依赖电能脉冲计数,那么HT7036的简洁性会带来巨大的开发效率优势。STM32F103C8T6的强大性能足以驾驭这两种方案。

3. 硬件电路设计详解与避坑指南

原理图设计是项目稳定的基石。这里我分享基于STM32F103C8T6最小系统板,分别连接ATT7022E和HT7036的经典设计,并重点说明那些容易出错的地方。

3.1 电源与基准电路设计

稳定的电源是精密测量的前提。两颗计量芯片通常都采用5V或3.3V供电,需要与STM32的供电电压匹配。

ATT7022E供电方案: ATT7022E通常采用5V模拟供电(AVDD)和3.3V数字供电(DVDD)。这里一个常见的坑是:如果系统只有3.3V电源,虽然芯片数据手册标明DVDD可以接3.3V,但AVDD接3.3V可能会影响内部模拟电路的性能,尤其是动态范围和精度。推荐做法是使用一个低压差线性稳压器(LDO),如AMS1117-5.0,从系统电源(比如12V或USB 5V)单独为AVDD生成一个干净的5V。DVDD则可以直接连接到STM32的3.3V上。两个电源域之间,在AVDD引脚附近放置一个10uF的钽电容和一个100nF的陶瓷电容进行退耦,在DVDD引脚附近放置一个100nF的陶瓷电容。

HT7036供电方案: HT7036通常工作在3.3V或5V。由于其内部集成了基准,电源要求相对宽松。但同样需要在电源引脚附近放置足够的去耦电容:一个10uF的电解电容或钽电容并联一个100nF的陶瓷电容是标准配置。

基准电压: ATT7022E需要外部基准电压,通常选择2.5V。可以使用REF192或ADR425等精密基准源芯片。基准源的输出端必须用低ESR的陶瓷电容(如1uF)滤波,并且走线要尽量短且粗,远离数字信号线,以避免噪声干扰。这是影响计量精度的关键因素之一。HT7036因内置基准,这部分电路可以省略。

3.2 模拟前端(AFE)采样电路设计

这是硬件设计的核心,决定了输入信号的质量。

电压采样电路: 通常采用电阻分压网络将市电(如220V AC)按比例衰减到芯片允许的输入电压范围(例如±0.5V)。以ATT7022E为例,假设其电压通道输入峰值电压为±0.5V(对应有效值约0.353V)。对于220V市电,峰值约为311V。分压比需要达到311V / 0.5V ≈ 622:1。

  • 电阻选型:高压侧电阻(R1)要选用高压、高精度、低温漂的贴片电阻,如1206封装的1MΩ 1%精度电阻。低压侧电阻(R2)计算约为1MΩ / 622 ≈ 1.6kΩ。同样需要高精度。
  • 保护与滤波:在分压点与芯片输入引脚之间,必须串联一个小的限流电阻(如100Ω),并并联双向TVS管(如SMBJ5.0A)和钳位二极管,防止浪涌电压损坏芯片。同时,需要加入一个RC低通滤波器(如1kΩ + 100nF),用于抗混叠滤波,截止频率设置在远高于工频(50Hz)但低于采样频率一半的位置。一个易忽略的点:这个滤波电容的容差和温度特性也会影响相位,进而影响功率测量精度,建议使用C0G/NP0材质的陶瓷电容。

电流采样电路: 通常使用电流互感器(CT)或锰铜分流器。

  • CT方案:更常见,提供电气隔离。CT次级输出的电流信号通过一个“负载电阻”(Burden Resistor)转换为电压信号。这个电阻的精度和温度稳定性至关重要。同样需要在芯片输入端设计RC滤波和钳位保护电路。特别注意CT的相位误差,不同CT在额定频率下的相位误差不同,这需要在软件校表时进行相位补偿。
  • 分流器方案:成本低,无相位误差,但无隔离。需要在设计时仔细计算分流器的功耗和温漂,并注意共模电压问题。

布局布线要点

  1. 模拟与数字分区:在PCB上,将计量芯片、采样电阻、滤波电容、基准源等模拟部分集中在一个区域,并与STM32等数字部分明确分开。
  2. 地平面分割与单点连接:采用模拟地(AGND)和数字地(DGND)。在PCB底层或内层铺设完整的模拟地平面和数字地平面,两者仅在一点连接,通常选择在电源输入滤波电容的接地端。绝对禁止将模拟和数字地线随意交织。
  3. 敏感走线:基准电压走线、模拟输入走线要尽量短、粗,避免穿过数字区域或靠近时钟线、高速数据线。必要时使用“包地”处理,即用接地铜皮将其包围。
  4. 退耦电容就近放置:所有芯片的电源退耦电容(100nF)必须尽可能靠近芯片的电源引脚,回流路径最短。

3.3 数字接口连接设计

SPI接口的连接看似简单,但时序问题常常是调试的噩梦。

ATT7022E与STM32的SPI连接

  • ATT7022E.SCLK->STM32.SPIx_SCK
  • ATT7022E.DIN->STM32.SPIx_MOSI
  • ATT7022E.DOUT->STM32.SPIx_MISO
  • ATT7022E.CS->STM32.任意GPIO(配置为推挽输出)
  • ATT7022E.RESET->STM32.任意GPIO(配置为推挽输出,用于硬件复位)

关键配置

  1. SPI模式:必须设置为Mode 0 (CPOL=0, CPHA=0)。在STM32的HAL库中,对应SPI_MODE0
  2. 时钟极性与相位:在CubeMX或代码中明确配置。hspi.Init.CLKPolarity = SPI_POLARITY_LOW;hspi.Init.CLKPHA = SPI_PHASE_1EDGE;
  3. 片选(CS)软件管理:ATT7022E要求在一次通信期间CS保持低电平。因此,不能使用STM32硬件NSS管脚,必须用一个普通GPIO来模拟。在读写函数开始前拉低,完成后拉高。
  4. 时钟频率:初始调试时,建议将SPI时钟频率设低,如1MHz以下,确保通信稳定。确认无误后再逐步提高。ATT7022E的SPI最高时钟可达几MHz,但受PCB布局影响,过高频率可能导致数据错误。
  5. 上拉电阻:如果连接线较长,考虑在SCLK、MOSI、MISO线上增加4.7kΩ上拉电阻,增强抗干扰能力。

HT7036的连接: SPI连接方式与ATT7022E类似,同样需要注意模式(请查阅HT7036数据手册确认具体模式)。此外,HT7036的CF(电能脉冲)输出引脚可以连接到STM32的:

  • 外部中断(EXTI)引脚:用于精确捕获每个脉冲沿,在中断服务程序中进行电能累加。适用于高精度计量。
  • 定时器输入捕获通道:可以测量脉冲频率,从而计算瞬时功率。
  • 普通GPIO输入:通过轮询方式检测电平(不推荐,效率低且可能丢失脉冲)。

注意:无论是ATT7022E的SPI还是HT7036的CF引脚,与STM32连接的线上,如果距离超过5cm,建议串联一个22Ω-100Ω的小电阻,有助于抑制信号过冲和振铃,提升信号完整性。

4. 软件驱动架构与核心代码解析

硬件搭好后,软件是让系统“活”起来的关键。下面以ATT7022E为例,详解驱动层、数据读取与校准层的实现。HT7036的驱动会更简单,架构类似。

4.1 底层SPI通信驱动封装

一个健壮、可重用的SPI读写函数是基础。

// att7022e_spi.c #include “att7022e_spi.h” #include “main.h” // 包含你的SPI和GPIO定义 extern SPI_HandleTypeDef hspi1; // 假设使用SPI1 #define ATT7022E_CS_PIN GPIO_PIN_4 #define ATT7022E_CS_PORT GPIOA // 私有函数:SPI读写一字节 static uint8_t SPI_ReadWriteByte(uint8_t tx_data) { uint8_t rx_data = 0; HAL_SPI_TransmitReceive(&hspi1, &tx_data, &rx_data, 1, 1000); return rx_data; } // 公共函数:读取ATT7022E寄存器 uint32_t ATT7022E_ReadReg(uint8_t reg_addr) { uint32_t read_data = 0; uint8_t i; ATT7022E_CS_LOW(); // 拉低片选 // 发送读命令 (最高位为0) + 6位地址 SPI_ReadWriteByte(reg_addr & 0x3F); // 读取24位数据 (ATT7022E数据多为24位) for (i = 0; i < 3; i++) { read_data <<= 8; read_data |= SPI_ReadWriteByte(0xFF); // 发送哑元数据以产生时钟 } ATT7022E_CS_HIGH(); // 拉高片选 return read_data; } // 公共函数:写入ATT7022E寄存器 void ATT7022E_WriteReg(uint8_t reg_addr, uint32_t write_data) { uint8_t i; uint8_t data_buf[3]; ATT7022E_CS_LOW(); // 发送写命令 (最高位为1) + 6位地址 SPI_ReadWriteByte(reg_addr | 0x40); // 发送24位数据 data_buf[0] = (write_data >> 16) & 0xFF; data_buf[1] = (write_data >> 8) & 0xFF; data_buf[2] = write_data & 0xFF; for (i = 0; i < 3; i++) { SPI_ReadWriteByte(data_buf[i]); } ATT7022E_CS_HIGH(); }

关键点解析

  1. 时序严格性ATT7022E_CS_LOW()ATT7022E_CS_HIGH()之间的操作必须连续,不能插入不必要的延时或任务切换,否则可能导致芯片误解命令。
  2. 数据长度:ATT7022E多数有效数据寄存器是24位的,所以读写函数按24位处理。但有些控制寄存器可能是8位或16位,需要根据具体寄存器地址调整。
  3. 错误处理:上述示例省略了错误处理。在实际产品中,应检查HAL_SPI_TransmitReceive的返回值,并在通信失败时进行重试或错误上报。

4.2 ATT7022E初始化与基础配置

上电后,芯片需要正确的初始化序列才能进入工作状态。

void ATT7022E_Init(void) { // 1. 硬件复位 (可选,但推荐) ATT7022E_RST_LOW(); HAL_Delay(10); // 保持低电平至少1ms ATT7022E_RST_HIGH(); HAL_Delay(50); // 等待芯片稳定 // 2. 检查芯片通信是否正常 (读芯片ID寄存器) uint32_t chip_id = ATT7022E_ReadReg(REG_CHIP_ID); // REG_CHIP_ID需根据数据手册定义 if ((chip_id & 0xFF) != 0xE1) { // ATT7022E的ID固定为0xE1 // 通信失败处理,打印日志或进入错误状态 Error_Handler(); } // 3. 配置系统控制寄存器 // 例如:选择内部时钟、设置ADC增益、启动ADC等 uint32_t sys_ctrl_value = 0; sys_ctrl_value |= (0x01 << 0); // 启动ADC sys_ctrl_value |= (0x00 << 1); // 使用内部时钟 // ... 其他位配置 ATT7022E_WriteReg(REG_SYS_CTRL, sys_ctrl_value); // 4. 配置测量模式寄存器 // 例如:选择RMS测量模式、设置积分时间等 ATT7022E_WriteReg(REG_MODE_SEL, 0x000000); // 示例值,需根据需求设置 // 5. 初始化校表参数为默认值 (或从EEPROM加载历史校准值) Load_Calibration_Params(); HAL_Delay(100); // 等待配置生效 }

4.3 关键数据读取与处理流程

配置完成后,需要周期性地读取测量数据。

typedef struct { float voltage_rms; // 电压有效值 (V) float current_rms; // 电流有效值 (A) float active_power; // 有功功率 (W) float reactive_power; // 无功功率 (Var) float apparent_power; // 视在功率 (VA) float power_factor; // 功率因数 float frequency; // 频率 (Hz) uint32_t total_energy; // 累计电能 (Wh或kWh, 需换算) } EnergyData_t; void ATT7022E_ReadEnergyData(EnergyData_t *data) { uint32_t reg_val; // 读取电压有效值寄存器 (24位, 补码格式) reg_val = ATT7022E_ReadReg(REG_U_RMS); >// 使用TIM2的通道1捕获CF脉冲上升沿 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { // 每次进入此回调,表示检测到一个电能脉冲 g_energy_pulse_count++; // 可以根据脉冲常数(imp/kWh)计算累计电能 // g_total_energy_wh += (1000.0 / PULSE_CONSTANT); // 假设PULSE_CONSTANT是 imp/kWh } }

脉冲计数注意事项

  1. 防抖:机械继电器或负载切换可能引起CF脉冲抖动。需要在硬件(RC滤波)或软件(在中断回调中进行时间判断,短时间内多次触发则忽略)上做防抖处理。
  2. 脉冲常数:HT7036的CF脉冲输出频率与功率成正比。需要根据数据手册和你的前端设计,计算出准确的脉冲常数(如 3200 imp/kWh)。
  3. 中断优先级:如果系统中有其他中断,需要合理设置电能脉冲捕获中断的优先级,确保不会丢失脉冲。

5. 校准流程实战与精度提升技巧

未经校准的计量系统毫无意义。校准是消除系统误差(增益误差、相位误差、偏移误差)的过程。

5.1 ATT7022E校准全流程

ATT7022E的校准相对复杂,但逻辑清晰。通常需要专业的校准源(如可编程交流电源)和标准表。

校准前准备

  1. 硬件焊接无误,电源稳定。
  2. 软件基础驱动(读写寄存器)已调通。
  3. 准备校准点:通常在额定电压(如220V)、额定电流(如5A)、功率因数1.0(纯阻性负载)和0.5L(感性负载)条件下进行。

校准步骤

  1. 小信号校准(可选):在无输入或输入很小时,读取电压、电流通道的偏移值,并写入偏移校正寄存器,使读数为零。
  2. 增益校准
    • 施加额定电压和额定电流(功率因数1.0)。
    • 读取芯片测量的电压有效值U_meas和电流有效值I_meas
    • 读取标准表得到的真实值U_stdI_std
    • 计算增益校正系数:Gain_U = U_std / U_measGain_I = I_std / I_meas
    • 将计算出的增益系数写入对应的增益校正寄存器。ATT7022E的增益寄存器通常是带有符号和小数位的,需要按照数据手册的格式进行转换。
  3. 相位校准
    • 保持额定电压和电流,将负载切换为感性负载(功率因数约0.5L)。
    • 读取芯片测量的有功功率P_meas
    • 读取标准表的有功功率P_std
    • 由于增益已校准,此时的功率误差主要由电压和电流采样通道之间的相位差引起。
    • 通过调整相位校正寄存器(Phase Compensation Register)的值,使P_meas尽可能接近P_std。这个过程可能需要迭代几次。
  4. 电能脉冲常数校准
    • 在增益和相位校准后,进行电能累加测试。
    • 让标准表输出一定的电能(如0.01kWh),同时记录ATT7022E输出的电能脉冲数或读取的电能寄存器差值。
    • 计算脉冲常数误差,并调整电能累加系数或相关寄存器。

校准经验

  • 分步进行:先做电压增益,再做电流增益,最后做相位。每一步校准后,验证一下其他参数是否合理。
  • 多次平均:读取校准用的测量值时,取多次(如100次)的平均值,以消除随机噪声的影响。
  • 保存参数:校准得到的参数需要存储在非易失性存储器(如STM32内部的Flash或外置EEPROM)中。每次上电初始化时,将这些参数加载到ATT7022E的相应寄存器。
  • 温度补偿:对于高精度应用,需要考虑环境温度变化对采样电阻、基准源等的影响。可以测量板载温度,根据温漂曲线对校准参数进行补偿。

5.2 HT7036校准简述

HT7036的校准流程更简单,通常只涉及增益校正。

  1. 施加额定输入。
  2. 读取测量寄存器值。
  3. 与标准值比较,计算出一个校正系数。
  4. 将该系数写入指定的校准寄存器(如GAIN寄存器)。 HT7036的校表寄存器较少,很多芯片在出厂时已经进行了基础校准,用户校准主要是为了匹配前端传感器(CT、分压电阻)的个体差异。

5.3 常见校准问题与排查

  • 校准后读数跳动大:检查电源纹波、基准电压噪声、PCB布局。确保模拟地干净。增加软件滤波。
  • 增益校准写入后无变化:确认寄存器地址是否正确;确认写入的数据格式是否符合芯片要求(可能是带符号的定点数);用读回的方式验证是否写入成功。
  • 相位校准效果不明显:确认负载是否是真正的感性负载(功率因数0.5L左右)。检查电压和电流采样电路的RC滤波参数是否一致,不一致的滤波会导致附加相位差。可以尝试微调硬件上的滤波电容。
  • 小负载时误差大:这可能是偏移误差未校准或非线性误差。在非常小的输入下进行偏移校准。ATT7022E有专门的Poffset(功率偏移)寄存器来修正小信号下的功率误差。

6. 系统集成与调试经验分享

当硬件和基础驱动都准备好后,将整个系统跑起来,并与上位机或显示终端连接,才是真正的挑战开始。

6.1 与STM32主程序的整合

建议采用模块化设计:

  • att7022e.c/.hht7036.c/.h:封装所有芯片相关的操作。
  • energy_meter.c/.h:提供上层应用接口,如Get_Instant_Power()Get_Total_Energy(),内部调用底层驱动。
  • main.c中,初始化后,在一个定时器中断或低优先级任务中周期性地调用数据读取函数。
// 在1ms定时器中断中更新标志 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim == &htim6) { // TIM6用于1ms定时 static uint16_t cnt_10ms = 0; static uint16_t cnt_500ms = 0; cnt_10ms++; cnt_500ms++; if (cnt_10ms >= 10) { // 10ms任务 cnt_10ms = 0; g_sys_tick_10ms_flag = 1; } if (cnt_500ms >= 500) { // 500ms任务 cnt_500ms = 0; g_sys_tick_500ms_flag = 1; } } } // 在主循环中 while (1) { if (g_sys_tick_500ms_flag) { g_sys_tick_500ms_flag = 0; ATT7022E_ReadEnergyData(&g_energy_data); // 500ms读取一次数据 // 更新显示、通过串口发送数据等 Update_Display(&g_energy_data); Send_Data_To_UART(&g_energy_data); } // ... 其他任务 }

6.2 通信与数据上报

常用的数据上报方式有串口(UART)和液晶显示(LCD)。

串口通信: 定义一套简单的应用层协议,如[帧头][长度][命令字][数据域][校验和][帧尾]

// 示例:将电量数据打包发送 void Send_Energy_Packet(void) { uint8_t tx_buf[32]; uint8_t *p = tx_buf; uint16_t checksum = 0; *p++ = 0xAA; // 帧头 *p++ = 0x55; *p++ = 0x00; // 长度占位 *p++ = CMD_REPORT_ENERGY; // 命令字 // 填充数据域 (将float转换为网络字节序或字符串) memcpy(p, &g_energy_data.voltage_rms, 4); p+=4; memcpy(p, &g_energy_data.current_rms, 4); p+=4; // ... 填充其他数据 // 计算长度和校验和 tx_buf[2] = (p - tx_buf) - 3; // 长度 for(int i=0; i<(tx_buf[2]+3); i++) { checksum += tx_buf[i]; } *p++ = (checksum >> 8) & 0xFF; *p++ = checksum & 0xFF; *p++ = 0x0D; // 帧尾 *p++ = 0x0A; HAL_UART_Transmit(&huart1, tx_buf, p - tx_buf, 1000); }

LCD显示: 使用STM32的FSMC接口驱动TFT屏,或者使用I2C/SPI接口的OLED屏。将浮点数格式化为字符串显示。

void Update_Display(EnergyData_t *data) { char str_buf[20]; // 清屏或局部刷新 LCD_Clear(AREA_VOLTAGE); sprintf(str_buf, “U: %.1f V”, style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;" />

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询