100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > arduino Wemos D 1HT7038调试笔记

arduino Wemos D 1HT7038调试笔记

时间:2022-10-05 09:35:51

相关推荐

arduino Wemos D 1HT7038调试笔记

HT7038核心板原理图

电压互感器接口板原理图

按上述原理图,我分别制作了HT7038模块板和互感器接口板。

原有51的程序可以正常读出HT7038电压数据,此次我把KEIL C51的程序移植到arduino WEMOS D1平台,

开始wemos D1可以读取 rDeviceID和rChipID数据,我就以为大功告成。可是当我读电压数据时没有任何返回数据。几经周折发现是往HT7038写命令时没有给命令最高位置1.

实际SPI写寄存器命令

现在回想调试HT7038大概步骤应该是:

1实现读取rDeviceID和rChipID数据,如果能读取到,则表明SPI通讯正常。

2向w_ModeCfg写入数据,然后再读取该寄存器的数据,看是否和写入的数据一致,如果返回的是默认值0x89AA,则表明写入不成功。

写入前应开启校表寄存器写入,

ht7038.Write7038(0xC9,0x00005A); //设置可以写入校表寄存器的参数

然后写入数据

ht7038.Write7038(w_ModeCfg,0xF954);//开启电压通道ADC ,更新速率为慢速0xF9FE

禁止校表寄存器写入

ht7038.Write7038(0xC9,0x0000FF); //关闭写校表寄存器

开启读取校表寄存器

ht7038.Write7038(0xC6,0x00005A); //设置可以读校表寄存器的参数

读取校表寄存器

Serial.println(ht7038.Read7038(w_ModeCfg),HEX);//读取校表w_ModeCfg寄存器,并返回给串口输出

具体解释见官方表格

如果写入校表寄存器成功,则读取电压电流功率等数据不成问题。

下面是arduino代码:

//2ma/2ma互感器按220V 2ma设置#include <SPI.h>#include "HT7038.h"#include <BlynkSimpleEsp8266.h>HT7038 ht7038;BlynkTimer timer;//#define _DEBUG;typedef union{unsigned long Long_Data;byte da[4];}DWord;DWord rData;union UN_RMS{// unsigned char volChar[4]; //电压字节数组unsigned long volFloat; //电压浮点数};union UN_RMS U_rms; float Uab;float Ubc;float Uac;void SPIsendData(){#ifdef _DEBUGSerial.print("rDeviceID=0x");Serial.println(ht7038.Read7038(rDeviceID),HEX); Serial.print(" rChipID=0x");Serial.println(ht7038.Read7038(rChipID),HEX);#endifrData.Long_Data = ht7038.Read7038(rUaRms); //读取Uab电压 U_rms.volFloat=rData.Long_Data ;Uab=(float)U_rms.volFloat/8192;rData.Long_Data = ht7038.Read7038(rUbRms); //读取Uac电压 内部计算得出U_rms.volFloat=rData.Long_Data ;Uac=(float)U_rms.volFloat/8192; //长整型强制转换成浮点型,否者液晶显示数据为0rData.Long_Data = ht7038.Read7038(rUcRms); //读取Ubc电压U_rms.volFloat=rData.Long_Data ;Ubc=(float)U_rms.volFloat/8192;Serial.print("Uab=");Serial.print(Uab);Serial.println("V");Serial.print("Ubc=");Serial.print(Ubc);Serial.println("V");Serial.print("Uac=");Serial.print(Uac);Serial.println("V");Serial.println("-------------------");}void setup() {Serial.begin(230400);ht7038.HT7038_begin();ht7038.HT7038_init();delay(20);ht7038.Write7038(0xC9,0x00005A); //设置可以写入校表寄存器的参数ht7038.Write7038(w_ModeCfg,0xF954);//开启电压通道ADC ,更新速率为慢速0xF9FEht7038.Write7038(w_EMCfg,0x0003);//设置三相三线模式0x0111ht7038.Write7038(w_EMUIE,0xFFFF);ht7038.Write7038(w_ModuleCFG,0x3404);//0x3404ht7038.Write7038(w_PGACtrl,0x0000); //ADC增益配置为三相电压通道ADC增益放大2倍 bit09和bit08为设置电压通道增益位ht7038.Write7038(w_EMUCfg,0x0201); //EMU模块配置寄存器0x0201ht7038.Write7038(w_UgainA,0x022E);//Uab电压增益ht7038.Write7038(w_UgainC,0x022E);//Ubc电压增益ht7038.Write7038(w_UgainB,0x022E);//Uac相电压增益需单独计算,不与A相C相相同ht7038.Write7038(0xC9,0x0000FF); //关闭写校表寄存器ht7038.Write7038(0xC6,0x000000); //设置可以读计量寄存器的参数timer.setInterval(1000L, SPIsendData);}void loop() {timer.run();}

头文件代码:

#ifndef __HT7038_H__#define __HT7038_H__//导入Arduino核心头文件#include"Arduino.h" #include <SPI.h>#define HT7038_CS D8 //针对自制的HT7038接口板//===================================================//定义HT7038的数据寄存器 //===================================================#define rDeviceID 0x00 //7038 Device ID#define rPa0x01 //A相有功功率#define rPb0x02 //B相有功功率#define rPc0x03 //C相有功功率#define rPt0x04 //合相有功功率#define rQa0x05 //A相无功功率#define rQb0x06 //B相无功功率#define rQc0x07 //C相无功功率#define rQt0x08 //合相无功功率#define rSa0x09 //A相视在功率#define rSb0x0A //B相视在功率#define rSc0x0B //C相视在功率#define rSt0x0C //合相视在功率#define rUaRms0x0D //A相电压有效值#define rUbRms0x0E //B相电压有效值#define rUcRms0x0F //C相电压有效值#define rIaRms0x10 //A相电流有效值#define rIbRms0x11 //B相电流有效值#define rIcRms0x12 //C相电流有效值#define rItRms0x13 //ABC相电流矢量和的有效值#define rPfa 0x14 //A相功率因数#define rPfb 0x15 //B相功率因数#define rPfc 0x16 //C相功率因数#define rPft 0x17 //合相功率因数#define rPga 0x18 //A相电流与电压相角#define rPgb 0x19 //B相电流与电压相角功率因数#define rPgc 0x1a //C相电流与电压相角#define rINTFlag 0x1b //中断标志,读后清零 ☆#define rFreq 0x1C //线频率#define rEFlag 0x1d //电能寄存器的工作状态,读后清零☆#define rEpa 0x1e //A相有功电能#define rEpb 0x1f //B相有功电能#define rEpc 0x20 //C相有功电能#define rEpt 0x21 //合相有功电能#define rEqa 0x22 //A相无功电能#define rEqb 0x23 //B相无功电能#define rEqc 0x24 //C相无功电能#define rEqt 0x25 //合相无功电能#define rYUaUb 0x26 //Ua与Ub的电压夹角 ☆#define rYUaUc 0x27 //Ua与Uc的电压夹角 ☆#define rYUbUc 0x28 //Ub与Uc的电压夹角 ☆#define rTPSD 0x2a //温度传感器的输出#define rURmst 0x2b //ABC电压矢量和的有效值#define rS_Flag 0x2c //存放断相、相序、SIG信号的有效值#define rBackReg 0x2d //通讯数据备份寄存器☆#define rComChksum 0x2e //通讯校验和寄存器☆#define rSampleIA 0x2f //A相电流通道ADC采样数据☆#define rSampleIB 0x30 //B相电流通道ADC采样数据☆#define rSampleIC 0x31 //C相电流通道ADC采样数据☆#define rSampleUA 0x32 //A相电压通道ADC采样数据☆#define rSampleUB 0x33 //B相电压通道ADC采样数据☆#define rSampleUC 0x34 //C相电压通道ADC采样数据☆#define rEsa 0x35 //A相视在电能☆#define rEsb 0x36 //B相视在电能☆#define rEsc 0x37 //C相视在电能☆#define rEst 0x38 //合相视在电能☆#define rFstCntA 0x39 //A相快速脉冲计数☆#define rFstCntB 0x40 //B相快速脉冲计数☆#define rFstCntC 0x40 //C相快速脉冲计数☆#define rFstCntT 0x41 //合相快速脉冲计数☆#define rPFlag 0x3d //有功和无功功率方向,正向为0,负向为1#define rChkSum 0x3e //校表数据校验寄存器(三相四线模式下是0x01D4CD;三相三线模式下是0x01E0CD;)#define rVrefgain 0x5c //Vref自动补偿系数#define rChipID0x5d //芯片版本指示器0X7026E0#define rChkSum1 0x5e //新增校表寄存器校验和//==================================================================//HT7038校表寄存器定义//==================================================================#define w_ModeCfg 0X01 //模式相关控制 #define w_PGACtrl 0X02 //ADC增益选择 #define w_EMUCfg 0X03 //EMU模块配置寄存器 #define w_PgainA 0X04 //A相有功功率增益 #define w_PgainB 0X05 //B相有功功率增益 #define w_PgainC 0X06 //C相有功功率增益 #define w_QgainA 0X07 //A相无功功率增益 #define w_QgainB 0X08 //B相无功功率增益 #define w_QgainC 0X09 //C相无功功率增益 #define w_SgainA 0X0A //A相视在功率增益 #define w_SgainB 0X0B //B相视在功率增益 #define w_SgainC 0X0C //C相视在功率增益 #define w_PhSregApq0 0X0D //A相相位校正0 #define w_PhSregBpq0 0X0E //B相相位校正0 #define w_PhSregCpq0 0X0F //C相相位校正0 #define w_PhSregApq1 0X10 //A相相位校正1 #define w_PhSregBpq1 0X11 //B相相位校正1 #define w_PhSregCpq1 0X12 //C相相位校正1 #define w_PoffsetA0X13 //A相有功功率offset校正 #define w_PoffsetB0X14 //B相有功功率offset校正 #define w_PoffsetC0X15 //C相有功功率offset校正 #define w_QPhscal 0X16 //无功相位校正 #define w_UgainA 0X17 //A相电压增益 #define w_UgainB 0X18 //B相电压增益 #define w_UgainC 0X19 //C相电压增益 #define w_IgainA 0X1A //A相电流增益 #define w_IgainB 0X1B //B相电流增益 #define w_IgainC 0X1C //C相电流增益 #define w_Istarup 0X1D //起动电流阈值设置 #define w_Hfconst 0X1E //高频脉冲输出设置 #define w_FailVoltage 0X1F //失压阈值设置#define w_QoffsetA0X21 //A相无功功率offset校正 #define w_QoffsetB0X22 //B相无功功率offset校正 #define w_QoffsetC0X23 //C相无功功率offset校正 #define w_UaRmsoffse 0X24 //A相电压有效值offset校正 #define w_UbRmsoffse 0X25 //B相电压有效值offset校正 #define w_UcRmsoffse 0X26 //C相电压有效值offset校正 #define w_IaRmsoffse 0X27 //A相电流有效值offset校正 #define w_IbRmsoffse 0X28 //B相电流有效值offset校正 #define w_IcRmsoffse 0X29 //C相电流有效值offset校正 #define w_UoffsetA0X2A //A相电压通道ADC offset校正 #define w_UoffsetB0X2B //B相电压通道ADC offset校正 #define w_UoffsetC0X2C //C相电压通道ADC offset校正 #define w_IoffsetA0X2D //A相电流通道ADC offset校正 #define w_IoffsetB0X2E //B相电流通道ADC offset校正 #define w_IoffsetC0X2F //C相电流通道ADC offset校正 #define w_EMUIE 0X30 //中断使能 #define w_ModuleCFG0X31 //电路模块配置寄存器 #define w_AllGain 0X32 //全通道增益,用于校正ref自校正#define w_HFDouble0X33 //脉冲常数加倍选择 #define w_LineGain0X34 //基波增益校正 #define w_PinCtrl 0X35 //数字pin上下拉电阻选择控制 #define w_Pstartup0X36 //起动功率阈值设置 #define w_Iregion00X37 //相位补偿区域设置寄存器 #define w_Iregion10X60 //相位补偿区域设置寄存器1 #define w_PhSregApq2 0X61 //A相相位校正2 #define w_PhSregBpq2 0X62 //B相相位校正2 #define w_PhSregCpq2 0X63 //C相相位校正2 #define w_PoffsetAL0X64 //A相有功功率offset校正低字节 #define w_PoffsetBL0X65 //B相有功功率offset校正低字节 #define w_PoffsetCL0X66 //C相有功功率offset校正低字节 #define w_QoffsetAL0X67 //A相无功功率offset校正低字节 #define w_QoffsetBL0X68 //B相无功功率offset校正低字节 #define w_QoffsetCL0X69 //C相无功功率offset校正低字节 #define w_ItRmsoffset 0X6A //电流矢量和offset校正寄存器 #define w_TPSoffset0X6B //TPS初值校正寄存器 #define w_TPSgain 0X6C //TPS斜率校正寄存器 #define w_TCcoffA 0X6D //Vrefgain的二次系数#define w_TCcoffB 0X6E //Vrefgain的一次系数#define w_TCcoffC 0X6F //Vrefgain的常数项 #define w_EMCfg 0X70 //新增算法控制寄存器//===================================================================================class HT7038{private:byte pin; //CS引脚public:HT7038(byte p=HT7038_CS,bool state=HIGH );~HT7038();void HT7038_begin();void HT7038_init();void disattach();unsigned long Read7038(unsigned char rCmd);void Write7038(unsigned char wCmd,unsigned long Dat);};//====================================================================================#endif

CPP实现文件:

#include "HT7038.h" HT7038::HT7038(byte p,bool state):pin(p){pinMode(pin,OUTPUT);digitalWrite(pin, HIGH);}HT7038::~HT7038(){disattach();}void HT7038::HT7038_begin(){SPI.begin();digitalWrite(pin, HIGH);SPI.setDataMode(SPI_MODE1);SPI.setClockDivider(SPI_CLOCK_DIV32);SPI.setBitOrder(MSBFIRST);}void HT7038::HT7038_init(){Write7038(0xD3,0X000000);//软件复位}unsigned long HT7038:: Read7038(unsigned char rCmd){unsigned long buffer=0;unsigned char dataLength=3;unsigned char byteIndex=0 ;unsigned char receiveBuffer = 0;digitalWrite(pin, LOW);SPI.transfer(rCmd); //发送命令//接收从站返回数据,SPI.transfer(0)一次带回1个byte数据while(byteIndex < dataLength){receiveBuffer = SPI.transfer(0);buffer = (buffer << 8) + receiveBuffer;byteIndex++;}digitalWrite(pin, HIGH);return buffer;}void HT7038::Write7038(unsigned char wCmd,unsigned long Dat){long send;unsigned char data[3];typedef union{unsigned long Long_Data;unsigned char da[4];}DWord;DWord rData;wCmd = wCmd | 0x80; //最高位置位,表示为写操作 这句很重要//32大端转小端原理send = ((Dat>>24)&0xff) | // move byte 3 to byte 0((Dat<<8)&0xff0000) | // move byte 1 to byte 2((Dat>>8)&0xff00) | // move byte 2 to byte 1((Dat<<24)&0xff000000); // byte 0 to byte 3rData.Long_Data=send;data[0]=rData.da[1];data[1]=rData.da[2];data[2]=rData.da[3];digitalWrite(pin, LOW); SPI.transfer(wCmd); SPI.transfer(&data,3);digitalWrite(pin, HIGH);}void HT7038::disattach() //引脚回收,恢复到上电状态{digitalWrite(pin,LOW);pinMode(pin,INPUT);}

C51工程文件,比较乱,但功能正常基于STC15的,其它STC单片机注意延时。

链接:/s/1csUBAD3v5Go8YPSeVRpK3w

提取码:vb3h

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。