ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

钜泉ATT7053B串口驱动实战:从寄存器映射到校准计算

钜泉ATT7053B串口驱动实战:从寄存器映射到校准计算 简介面向电力仪表与能源管理领域的嵌入式开发者这套 ATT7053B_Demo 驱动源码演示了钜泉科技 ATT7053B 计量芯片的串口读写与校正流程。芯片集成多通道高精度 ADC可同时测量交直流电压、电流并完成三相电能计量驱动则封装了底层通信、初始化配置、数据读取和误差校准等模块让开发者能直接获取电压、电流、功率等实时数据也为进一步开发智能电表、配电监测等设备提供切入点。包内共 2 个文件包括 elecMeas.h 头文件与 elecMeas.c 源文件压缩包约 2KB结构精简其中 .h 文件声明函数接口与寄存器映射.c 文件实现串口通信与数据处理逻辑。代码示例覆盖了串口命令封装、数据返回解析以及基于校准系数的修正计算可清晰反映芯片寄存器操作与驱动框架。对想快速集成 ATT7053B 或学习单芯片计量驱动逻辑的开发者而言这份示例既能用作移植底座也能作为二次开发参考。目前已有 756 人学习下载适合需要轻量级驱动参考的开发场景。1. 钜泉ATT7053B串口驱动从信号链到校正计算的一次完整拆解做三相电能计量的人对钜泉ATT7053B不会陌生。这颗芯片集成了多通道高精度ADC电压电流同时采样能输出有功功率、无功功率、视在功率以及各相有效值在智能电表、能源网关和电力监控终端里都很常见。但芯片再好驱动写不好数据一样没法用。拿到ATT7053B_Demo这个工程包里面其实就两个核心文件elecMeas.h和elecMeas.c。前者定义寄存器地址、数据结构后者实现串口通信、数据解析和校准逻辑。把这两个文件读透等于把ATT7053B的上层通信框架摸了一遍比翻数据手册逐页啃要高效得多。这篇博文不打算做成数据手册的翻译稿而是按“通信协议设计 - 寄存器操作实现 - 数据解析与校验 - 校正计算实操 - 调试排错技巧”这条实际开发路径来拆解工程。适合刚接触电力计量芯片的嵌入式工程师也适合已经有基础但想把计量数据准确度做到位的开发者。2. ATT7053B通信基础串口帧结构、寄存器映射与工程文件职责划分2.1 为什么这颗芯片适合用串口驱动ATT7053B支持UART和SPI两种通信方式。Demo工程采用的是UART串口原因很直接在配电柜、智能断路器这类场景中主控MCU和计量芯片之间距离往往在几厘米到几十厘米串口两线制通信足够可靠而且很多低成本的MCU串口资源比SPI外设更充裕。数据速率不需要太高计量数据的刷新率通常在几千赫兹以内9600bps到38400bps的波特率完全够用。另一个因素是CPU占用率。用SPI通信需要主控频繁切换片选、控制时钟配合DMA还要额外配置。相比之下UART可以做成中断接收加环形缓冲区主控只有在收到完整的帧后才开始解析不占用连续的时间片。对需要同时处理LCD显示、按键扫描、远程通信的电表主控来说串口方式是更稳妥的选择。2.2 串口帧结构与命令字设计驱动层把上位机发给芯片的命令统一封装成定长帧。常见做法是命令字加寄存器地址再加校验字节。ATT7053B芯片本身支持单字节命令和带参数的命令驱动里封装得比较规整。帧结构大致是这样字段长度说明命令字1字节读寄存器/写寄存器/校表命令等寄存器地址1字节目标寄存器偏移地址数据域N字节写入数据或读取缓冲区校验字节1字节累加和校验或CRC8// elecMeas.h中定义的基础命令字 #define ATT7053B_CMD_READ 0x00 // 读寄存器命令 #define ATT7053B_CMD_WRITE 0x80 // 写寄存器命令最高位置1表示写操作 #define ATT7053B_CMD_CALIBRATE 0xA0 // 校表命令触发芯片内部校准流程命令字设计里把最高位作为读写标志是常见做法。写命令时最高位置1这样一条指令通过掩码就能把命令类型和寄存器操作统一起来。驱动收到响应帧后先判断命令字的回显是否一致再检查校验和防止错误的帧污染后续解析逻辑。2.3 寄存器映射elecMeas.h里的地址表规划看elecMeas.h时首先关注的不是代码本身而是寄存器地址表。ATT7053B的寄存器空间按功能模块划分每个通道的电压、电流有效值寄存器连续排列功率寄存器紧跟其后。数据手册里寄存器数量不少但Demo工程只挑关键寄存器做映射这也反映了实际项目中的做法用不到的寄存器没必要全部暴露给应用层。// 关键寄存器地址定义节选 #define ATT7053B_REG_AVOLTAGE 0x01 // A相电压有效值 #define ATT7053B_REG_ACURRENT 0x02 // A相电流有效值 #define ATT7053B_REG_APOWER 0x04 // A相有功功率 #define ATT7053B_REG_APOWER_Q 0x05 // A相无功功率 #define ATT7053B_REG_TEMPERATURE 0x2F // 芯片温度寄存器寄存器地址定义不能只看偏移量要结合数据手册确认每个寄存器的数据位宽和数据格式。ATT7053B的ADC数据是24位还是32位直接决定了驱动里解析数据时右移几位、要不要符号扩展、系数如何归一化。地址表本身不复杂但选错位宽会导致数值偏好几倍甚至出现符号错误。2.4 elecMeas.c的模块划分初始化、校验和数据处理源文件elecMeas.c的内部结构跟芯片的模块划分是强对应的。// elecMeas.c 内部函数结构示意 static void att7053b_send_cmd(uint8_t cmd, uint8_t reg, uint8_t *data, uint8_t len); static int att7053b_receive_frame(att7053b_frame_t *frame); static int att7053b_checksum(uint8_t *buf, uint8_t len); static void att7053b_parse_data(att7053b_regs_t *regs);通信层的三要素是构造帧、发送帧、接收帧。接收这一层最容易出问题因为串口中断被打断时数据可能丢失或者半包数据被当成完整帧处理。常见的解决思路是维护一个状态机接收FIFO根据帧头和帧尾界定边界收到完整一帧再做解析。Demo工程里虽然没有写操作系统但这个思路对裸机编程同样适用。2.5 驱动文件与MCU主控的边界划分好的驱动设计是自带边界的。elecMeas.c对外暴露的接口应该只做一件事——给上层一个获取测量结果的入口至于底层是串口还是SPI上层不应该关心。Demo工程在这一点上做得不错接口函数大多是这种风格// 本文件实现芯片数据读取主控只调用三个接口即可完成一次数据刷新 int battery_meter_open(void); int battery_meter_read_all(att7053b_regs_t *regs); int battery_meter_set_calibration(uint8_t ch, float gain);battery_meter_open负责打开串口外设、复位芯片、执行初始化序列battery_meter_read_all一次性读取所有需要关注的寄存器set_calibration用来写入校准系数。用户不需要关心寄存器地址怎么分发不必关心校验算法这层抽象对产品换主控时非常重要——只要接口不变上层业务代码一行不用改。3. 串口通信驱动的核心实现帧解析状态机与实时数据读取3.1 收发缓冲区与环形FIFO设计MCU与ATT7053B之间收发数据最忌讳的就是每收到一个字节就同步去解析。因为串口字节可能前后两个有间隔也可能连续到达如果同步阻塞接收很容易丢失字节。常见做法是开一个环形缓冲区串口中断只负责往缓冲区里丢字节主循环或定时器轮询时再取出来解析。// 环形FIFO实现中断服务函数和生产消费两端共用 #define RX_FIFO_SIZE 64 static volatile uint8_t rx_fifo[RX_FIFO_SIZE]; static volatile uint8_t rx_head 0, rx_tail 0; void uart_isr(void) { uint8_t byte UART_GetByte(); uint8_t next_head (rx_head 1) % RX_FIFO_SIZE; if (next_head ! rx_tail) { // 环形缓冲区未满 rx_fifo[rx_head] byte; rx_head next_head; } // 如果缓冲区满了丢弃该字节等待上层处理后再接收 }缓冲区大小的选择要结合一帧数据的长度和主控处理速度来考虑。ATT7053B一次性读多个寄存器时返回的数据帧可能长达10到20字节64字节的环形缓冲区对典型应用场景已经足够。如果主控主频低或者同时负担多个外设缓冲区要相应加大避免高频采样时溢出。3.2 状态机方式实现帧接收解析用状态机接收串口数据的好处是逻辑清晰、无阻塞。ATT7053B的响应帧结构是固定的帧头、长度、数据、校验呈线性顺序。状态机根据当前状态决定下一个字节做什么处理。// 帧接收状态机核心代码 typedef enum { FRAME_STATE_IDLE, // 等待帧头 FRAME_STATE_LENGTH, // 接收数据长度 FRAME_STATE_DATA, // 收数据负载 FRAME_STATE_CHECK // 校验字节 } frame_state_t; static frame_state_t frame_state FRAME_STATE_IDLE; static uint8_t frame_buf[32]; static uint8_t frame_len, frame_cnt; // 从FIFO取一个字节喂给状态机 void process_rx_byte(uint8_t byte) { switch (frame_state) { case FRAME_STATE_IDLE: if (byte 0xAA) { // 帧头 frame_buf[0] byte; frame_cnt 1; frame_state FRAME_STATE_LENGTH; } break; case FRAME_STATE_LENGTH: frame_buf[frame_cnt] byte; frame_len byte; if (frame_len sizeof(frame_buf) - 2) { // 长度超限复位 frame_state FRAME_STATE_IDLE; } else { frame_state FRAME_STATE_DATA; } break; case FRAME_STATE_DATA: frame_buf[frame_cnt] byte; if (frame_cnt frame_len) { frame_state FRAME_STATE_CHECK; } break; case FRAME_STATE_CHECK: frame_buf[frame_cnt] byte; if (att7053b_checksum(frame_buf, frame_cnt) 0) { parse_frame(frame_buf, frame_cnt); // 校验通过解析 } frame_state FRAME_STATE_IDLE; // 无论对错都回到空闲态 break; default: frame_state FRAME_STATE_IDLE; break; } }状态机的实现思路和TCP/IP协议栈里的帧解析异曲同工只是复杂度低很多。在实际项目中帧头可以选择0xAA这个Pattern但要注意如果数据负载里也出现0xAA就会导致帧同步错位。解决办法是增加帧头连续两个字节或者用长度字段加超时兜底。Demo工程里用的是单字节帧头加校验的方式对可靠通信已经足够。3.3 读取全部计量参数的命令序列一次完整的数据读取应该把电压、电流、功率一次拉回来而不是逐个寄存器读。ATT7053B支持连续读寄存器区域驱动里利用这个特性一次命令把多个连续寄存器全部读回。这样可以显著降低通信次数减少对主控时间的占用。// 批量读寄存器从起始寄存器连续读len个寄存器 int att7053b_read_regs(uint8_t start_reg, uint8_t len, uint32_t *out_buf) { uint8_t cmd[4]; cmd[0] ATT7053B_CMD_READ; cmd[1] start_reg; cmd[2] len; cmd[3] (cmd[0] cmd[1] cmd[2]) 0xFF; // 累加和校验 UART_Send(cmd, 4); // 接收响应帧 att7053b_frame_t frame; att7053b_receive_frame(frame); if (frame.has_error) return -1; // 数据以连续字节返回每4字节组成一个32位寄存器值 for (int i 0; i len; i) { out_buf[i] (uint32_t)frame.data[i * 4] 24 | (uint32_t)frame.data[i * 4 1] 16 | (uint32_t)frame.data[i * 4 2] 8 | (uint32_t)frame.data[i * 4 3]; } return 0; }这里有几个值得注意的点。寄存器连续读时数据是大端还是小端取决于芯片输出定义ATT7053B是高位在前所以代码里用左移拼接。如果主控是Cortex-M系列编译器直接使用__REV指令也可以实现相同的效果但可读性不如显式移位。命令帧里的校验字节用的是累加和而非CRC因为计量芯片的通信速率不高累加和检测误码的错误率已经可以接受CRC用于低速短帧反而增加计算成本。3.4 驱动里与主控的任务配合实时性方面Demo工程采用定时器触发读取的方式。典型周期是每100ms读一次这个频率足够捕捉电网电压的波动也兼顾了主控负载。如果要做谐波分析读取频率需要提到10kHz以上但这时串口通信方式就要重新考量了SPI或者直接采集ADC原始数据是更合适的技术路线。// 100ms定时器中断里触发一次采样 void timer_isr(void) { battery_meter_read_all(regs); data_ready 1; // 置位标志主循环解析数据 }定时器中断里直接做串口收发的好处是抖动小采样间隔均匀。主循环只需要在标志位被置位时去解析数据、更新显示、换算物理量。这种简单的轮转结构在裸机环境下非常实用既没有操作系统调度延迟也不存在信号量、邮箱这类复杂机制。3.5 通信错误处理超时重传与连续错误计数串口通信不会永远可靠驱动必须处理异常情况。接收超时是常见问题芯片可能在主控发出读命令后无响应。Demo工程里在发送命令后启动一个软件定时器作为超时保护典型超时值设为50ms。// 发送命令后启动超时定时器 void att7053b_send_cmd_with_timeout(uint8_t *cmd, uint8_t len) { start_timeout(50); UART_Send(cmd, len); // 等待响应或超时 while (!timeout_occurred) { if (response_available) { handle_response(); return; } } // 超时处理累计错误次数 comm_error_count; if (comm_error_count 3) { // 连续多次超时认为通信链路故障执行芯片复位 chip_reset(); comm_error_count 0; } }连续错误计数超过阈值时驱动芯片复位引脚重新初始化这种自愈机制在无人值守的电力设备里是必要的。而且复位后寄存器配置会丢失驱动里要记住当前校准状态复位完成后重新下发校准系数。4. 数据解析与校验把原始寄存器值换算成真实的电压、电流和功率4.1 寄存器原始值的数据格式ATT7053B的ADC原始数据经过芯片内部数字信号处理后由寄存器输出。寄存器位宽是32位但有效数据可能只有24位高8位是符号扩展位。读取时先拿到的是一串0x00到0xFFFFFF之间的数值直接把这个值当作实际电压除以1000乘出来的结果毫无意义。// 原始寄存器值到物理量的转换核心参数是电压/电流通道的比例系数 float att7053b_voltage_raw_to_real(uint32_t raw) { int32_t signed_raw (int32_t)raw; // 32位寄存器值带符号这里做符号扩展 float voltage (float)signed_raw * VOLTAGE_LSB_VALUE; return voltage; }VOLTAGE_LSB_VALUE这个参数是每一个LSB对应的实际电压值由芯片增益设置和外部传感器的分压比决定。比如电压通道采用1:1000的分压电阻芯片内部PGA设置为1ADC参考电压为2.4V那么每1个LSB对应的电压值大约是0.000488V。这个系数必须在硬件设计阶段确定下来并写进驱动程序配置中。4.2 三相系统的寄存器分布与通道映射在三相系统中ATT7053B具有三个独立的电压采样通道和三个电流采样通道。寄存器地址表按通道连续排列A相电压电流在前面B相居中C相靠后。读取时必须按顺序批量读取才能保证三相数据的时间一致性。物理通道寄存器地址数据内容格式A相电压0x01有效值带符号32位有符号整数A相电流0x02有效值带符号32位有符号整数A相有功功率0x04有功功率符号数值32位有符号整数A相无功功率0x05无功功率符号数值32位有符号整数B相电压0x09有效值32位有符号整数B相电流0x0A有效值32位有符号整数C相电压0x11有效值32位有符号整数C相电流0x12有效值32位有符号整数读取时要特别注意电流通道的寄存器区分。ATT7053B支持电流互感器直接接入和罗氏线圈两种模式两种模式下的电流增益差异很大。直接接入模式下信号幅值高寄存器原始数值偏大罗氏线圈模式下信号弱原始值可能只有几百个LSB。这种情况下要是用一个固定系数换算误差会大到不可接受。4.3 有效功率数据解析与符号处理有功功率寄存器里最高位是符号位0表示正向用电1表示反向用电。解析时不能用简单的无符号乘法直接算需要先统一转成有符号数再做绝对值计算最后带上方向标志。// 有功功率类型定义 typedef struct { float value; // 功率数值单位W uint8_t direction; // 0 正向1 反向 } power_result_t; void parse_power_register(uint32_t raw, power_result_t *result) { int32_t signed_raw (int32_t)raw; if (signed_raw 0x80000000) { // 检查符号位 result-direction 1; signed_raw -signed_raw; // 取绝对值 } else { result-direction 0; } result-value (float)signed_raw * POWER_LSB_VALUE; }处理功率符号的意义不仅在于显示用电方向更重要的是要参与电能量累计的加减运算。如果只存绝对值当用户光伏发电反送电网时电表产生的累计电量数值就会错误地增加而不是减少。很多新手在实现复费率电表时在这个细节上栽了跟头。4.4 校验计算和CRC实现驱动里的校验函数一方面用于验证芯片返回数据的完整性另一方面也在写寄存器操作时用来生成校验字节。Demo工程里做的是累加和校验实现简单但对付误码率不高的串口通信已经够用。// 累加和校验计算把帧内所有字节相加取低8位作为校验值 uint8_t checksum_calc(uint8_t *buf, uint8_t len) { uint8_t sum 0; for (uint8_t i 0; i len; i) { sum buf[i]; } return sum; } // 校验验证返回0表示校验通过 int checksum_verify(uint8_t *buf, uint8_t len) { uint8_t sum checksum_calc(buf, len - 1); // 最后一个字节是接收到的校验值 return (sum buf[len - 1]) ? 0 : -1; }如果应用环境电磁干扰严重比如电表靠近继电器或大功率开关串口数据传输中可能出现连续多位翻转。累加和校验此时已经不够用建议换成CRC8或CRC16。CRC检查对突发错误和多位错误的检测能力远比累加和强。替换时只需要把空闲态的校验函数换掉其余代码完全不用动。4.5 数据平滑滤波的必要性与实现单个寄存器读出来的值带有毛刺。ATT7053B虽然有ADC前端的硬件滤波但读取时机不同瞬时值还是会有轻微波动。驱动层可以做一阶低通滤波把突变噪声压制掉。// 一阶低通滤波系数alpha越大输出越平滑响应越慢 static float voltage_filtered 0.0f; float low_pass_filter(float current_value, float alpha) { voltage_filtered voltage_filtered alpha * (current_value - voltage_filtered); return voltage_filtered; }alpha取0.1到0.3之间比较合适。alpha太大滤波效果不明显alpha太小数据变化响应迟钝电网电压骤降时功率计算跟不上。在Demo工程里电压电流和功率都经过滤波后再用于显示但用于校表时不能开滤波直接使用原始值才能准确反映芯片的瞬时计量性能。5. 校正计算实操增益校准、相位校准与温度补偿5.1 为什么需要校正计算计量芯片的原始数据经过了内部ADC转换和数字信号处理但每个芯片的制造工艺偏差、外部信号链路上分压电阻和互感器的精度差异都会让最终换算出的电压电流值和实际标准源之间存在偏差。芯片能保证内部ADC线性度但绝对值精度达不到计量要求。必须通过校表的方式为每个通道引入补偿系数把测量结果拉回标准值。5.2 增益校准流程与代码实现增益校准的原理是接入一个已知的标准源比如标准表给出的100V、5A读取芯片计算出的原始换算值把这个值与标准值对比算出偏差比例然后写回芯片校准寄存器。// 增益校准函数standard_value为标准源数值measured_value为当前测量值 void gain_calibrate(float standard_value, float measured_value) { float gain_error standard_value / measured_value; // 误差比例 uint32_t cali_raw read_calibration_register(); // 读取当前校准值 uint32_t new_cali_raw (uint32_t)((float)cali_raw * gain_error); write_calibration_register(new_cali_raw); // 校准系数写回后重新读取数据验证 float new_measured read_voltage(); if (fabs(new_measured - standard_value) 0.002 * standard_value) { // 校准前后偏差未收敛到0.2%以内需要重新校准 } }执行校准时有一个容易忽略的问题增益校准系数在多次校准之间是乘法叠加的不是直接覆盖。写校准寄存器时要先读出当前值再乘以误差比例。如果直接写新值会把芯片出厂时默认的校正常量覆盖掉导致校准结果更差。5.3 相位校准在感性负载下的作用电压电流相位误差主要来源于电流互感器的角差。一个精度等级0.2级的电流互感器相位误差可能达到5到10角分折算成功率误差在功率因数较低时影响很大。相位校准的思路是给芯片一个已知功率因数的负载通常为0.5L感性负载读取有功功率和无功功率的比值计算出相位误差然后写入相位补偿寄存器。// 相位校准通过功率因数间接补偿互感器角差 void phase_calibrate(void) { // 假设当前负载的功率因数为0.5L即相位角为60度 float active_power read_active_power(); float reactive_power read_reactive_power(); float tan_phi reactive_power / active_power; float actual_phi atanf(tan_phi) * 180.0f / 3.14159f; float phase_error 60.0f - actual_phi; // 与标准角度的偏差 // 把相位误差换算成芯片要求的补偿寄存器的值 uint32_t phase_comp (uint32_t)(phase_error * PHASE_COEFFICIENT); write_phase_register(phase_comp); }相位校准的坑在于校准前必须确认当前负载的真实功率因数。如果不知道标准功率因数误差计算就没有参考基准。实际工程中通常是配合标准功率源来做的标准源给定准确的功率因数角度芯片计算出的角度与标准源之间的偏差才是补偿量。5.4 温度漂移补偿策略计量设备在户外使用时环境温度跨度可能从零下40度到零上70度。ATT7053B内部有温度传感器寄存器地址为0x2F读取出来是芯片结温。校准系数随温度会漂移严格做计量认证时需要在不同温度点做多点校准。// 温度补偿根据芯片温度传感器值对增益进行线性修正 float get_temperature(void) { uint32_t raw read_temperature_register(); // 芯片手册给出温度转换公式原始值减去偏移再乘以斜率 float temp (float)raw * TEMP_SLOPE - TEMP_OFFSET; return temp; } // 进行温度修正后读取电压 float read_voltage_with_compensation(void) { float v read_voltage_raw(); float t get_temperature(); float comp_factor 1.0f (t - 25.0f) * TEMP_DRIFT_PPM / 1e6f; return v * comp_factor; }TEMP_DRIFT_PPM这个参数需要根据实际设备的全温测试数据来确定是典型值每摄氏度多少PPM。对于普通的电能表应用TEMP_DRIFT_PPM通常取50到100之间。如果产品要求不高也可以不做温度补偿仅在常温下校准一次即可满足2.0级电表的精度要求。5.5 校准参数的保存与恢复校准完成后校准参数不能只存在芯片寄存器里因为芯片掉电后寄存器数据丢失。正确做法是校准时把参数备份到MCU的Flash或外部EEPROM中在上电初始化时重新下发给芯片。下发时机要在芯片完成内部自检之后否则芯片还没准备好接收数据。// 上电恢复校准参数 void calibration_restore(void) { calib_param_t saved; eeprom_read(EEPROM_ADDR_CALIB, saved, sizeof(saved)); write_gain_register(ATT7053B_REG_GAIN_VOL_A, saved.gain_vol_a); write_gain_register(ATT7053B_REG_GAIN_CUR_A, saved.gain_cur_a); write_phase_register(saved.phase_comp); // 恢复完成后读取一次数据验证参数是否生效 uint32_t test_raw read_register(ATT7053B_REG_AVOLTAGE); if (test_raw 0xFFFFFFFF) { // 芯片未响应可能需要重新初始化通信 } }实测中遇到过一种情况寄存器恢复后电压数据显示正常功率数据异常偏大。原因是芯片在上电后有自己的一套内部复位流程如果在芯片完全退出复位状态之前就写寄存器写入操作被忽略而寄存器读取操作能正常返回默认值。解决办法是在写寄存器之前执行至少100毫秒的延时或者等芯片状态寄存器的就绪位被置位后再操作。6. 调试ATT7053B驱动时最值得记住的三个检查点调试串口驱动和调程序还不一样出问题时往往不是语法错误而是信号链路上的细节。用逻辑分析仪抓UART总线波形看时序是否正确是第一步该做的事。确认帧头、数据、校验字节的顺序与期望相符确认波特率没有偏差导致字节错位。常见错误是把AT7053B从SDO脚输出的数据误当成有帧头包裹的协议帧来解析实际上芯片的响应帧格式由驱动决定主机发什么格式芯片就回什么格式。驱动认为的帧头如果不被芯片支持那就要回数据手册查通信时序图。看数据时使用假数据法验证换算逻辑。把寄存器原始值设成已知的固定值比如ADC满量程一半时对应多少伏特通过计算出来的物理量判断换算系数是否正确。这个方法能快速定位是寄存器读错了还是换算系数配错了。上电顺序也很关键先让芯片完成复位再发送配置命令不要在芯片还没就绪前就连续发写寄存器指令。整个驱动框架跑起来之后再对照一个可信标准表验证误差电压误差在0.1%以内、功率误差在0.2%以内算合格。如果达不到先从互感器相位误差查起再检查滤波系数是否影响了数据的实时性最后才是代码层面的问题。本文还有配套的精品资源点击获取
返回列表