HLW8110电耗采集芯片的硬件设计和软件驱动方法

news/2025/2/5 5:06:37/

目录

1、硬件设计

2、软件设计


1、硬件设计

HLW8110是一款高精度的电能计量 IC,它采用 CMOS 制造工艺,主要用于单相计量应用。它能够测量线电压和电流,并能计算有功功率,视在功率和功率因素。该器件内部集成了二个∑-Δ型 ADC 和一个高精度的电能计量内核。输入通道支持灵活的 PGA 设置,因此 HLW8110 适合与不同类型的传感器使用,如电流互感器(CT)和低阻值分流器。

项目资源下载请参见:https://download.csdn.net/download/m0_38106923/87775438

HLW8110 电能计量 IC 采用 3.3V 或 5.0V 电源供电,内置 3.579M 振荡器,可以通过 UART 口进行数据通讯,波特率为 9600bps。

HLW8110的典型电路,外围电路简单,外围器件非常少,单路通道可用于检测负载设备的功率、电压、电流和用电量,通过 UART 或接口传输数据至 MCU,HLW8110 内部可以设置功率过载、电压过载和电流过载阀值,通过内部寄存器可以查询,并可以检测电压过零点。

官方测试,使用采样电阻或者互感器的理论数据误差如下所示:

在使用之前先简单设计一块Demo板进行调测,实物模块如下所示:

原理图、PCB如下所示:

2、软件设计

由于代码量较多,部分配置代码不再赘述,仅仅展示核心算法代码。

读取通道电流,实现代码如下所示:

void Read_HLW8110_IA(void)
{	float a;Uart_Read_HLW8110_Reg(REG_RMSIA_ADDR,3);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U32_RMSIA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]); printf("A通道电流寄存器:%lx\n " ,U32_RMSIA_RegData);}else{printf("A通道电流寄存器读取出错\r\n");B_Read_Error = 1;}//A通道电流PGA = 16,电压通道PGA = 1;电流采样电阻1mR,电压采样电阻1M//计算公式,U16_AC_I = (U32_RMSIA_RegData * U16_RMSIAC_RegData)/(电流系数* 2^23)if ((U32_RMSIA_RegData & 0x800000) == 0x800000){F_AC_I = 0;}else{a = (float)U32_RMSIA_RegData;a = a * U16_RMSIAC_RegData;a  = a/0x800000;                     //电流计算出来的浮点数单位是mA,比如5003.12 a = a/1;  								// 1 = 电流系数a = a/1000;              //a= 5003ma,a/1000 = 5.003A,单位转换成Aa = a * D_CAL_A_I;				//D_CAL_A_I是校正系数,默认是1F_AC_I = a;}
}

读取通道电压,实现代码如下所示:

void Read_HLW8110_U(void)
{float a;Uart_Read_HLW8110_Reg(REG_RMSU_ADDR,3);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U32_RMSU_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);printf("电压通道寄存器:%lx\n " ,U32_RMSU_RegData);}else{printf("电压通道寄存器读取出错\r\n");B_Read_Error = 1;}//电压//计算:U16_AC_V = (U32_RMSU_RegData * U16_RMSUC_RegData)/2^23if ((U32_RMSU_RegData &0x800000) == 0x800000){F_AC_V = 0;}else{a =  (float)U32_RMSU_RegData;a = a*U16_RMSUC_RegData;  a = a/0x400000;       a = a/1;  						// 1 = 电压系数a = a/100;    				//计算出a = 22083.12mV,a/100表示220.8312V,电压转换成Va = a*D_CAL_U;				//D_CAL_U是校正系数,默认是1,		F_AC_V = a;}
}

读取通道功率,实现代码如下所示:

void Read_HLW8110_PA(void)
{float a;float b;Uart_Read_HLW8110_Reg(REG_POWER_PA_ADDR,4);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U32_POWERPA_RegData = (unsigned long)(u8_RxBuf[0]<<24) + (unsigned long)(u8_RxBuf[1]<<16) + (unsigned long)(u8_RxBuf[2]<<8) + (unsigned long)(u8_RxBuf[3]);printf("A通道功率寄存器:%lx\n " ,U32_POWERPA_RegData);}else{printf("A通道功率寄存器读取出错\r\n");B_Read_Error = 1;}if (U32_POWERPA_RegData > 0x80000000){b = ~U32_POWERPA_RegData;a = (float)b;}elsea =  (float)U32_POWERPA_RegData;//功率需要分正功和负功//计算,U16_AC_P = (U32_POWERPA_RegData * U16_PowerPAC_RegData)/(2^31*电压系数*电流系数)//单位为W,比如算出来5000.123,表示5000.123Wa = a*U16_PowerPAC_RegData;a = a/0x80000000;             a = a/1;  										// 1 = 电流系数a = a/1;  										// 1 = 电压系数a = a * D_CAL_A_P;						//D_CAL_A_P是校正系数,默认是1F_AC_P = a;									//单位为W,比如算出来5000.123,表示5000.123W
}

读取通道有功电量,实现代码如下所示:

void Read_HLW8110_EA(void)
{float a;Uart_Read_HLW8110_Reg(REG_ENERGY_PA_ADDR,3); delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U32_ENERGY_PA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);printf("A通道有功电量寄存器:%lx\n " ,U32_ENERGY_PA_RegData);}else{printf("A通道有功电量寄存器读取出错\r\n");B_Read_Error = 1;}Uart_Read_HLW8110_Reg(REG_HFCONST_ADDR,2); delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U16_HFConst_RegData = (unsigned int)(u8_RxBuf[0]<<8) + (unsigned int)(u8_RxBuf[1]);printf("HFCONST常数 = :%d\n " ,U16_HFConst_RegData);}else{printf("HFCONST常数寄存器读取出错\r\n");B_Read_Error = 1;}//电量计算,电量 = (U32_ENERGY_PA_RegData * U16_EnergyAC_RegData * HFCONST) /(K1*K2 * 2^29 * 4096)//HFCONST:默认值是0x1000, HFCONST/(2^29 * 4096) = 0x20000000a =  (float)U32_ENERGY_PA_RegData;	a = a*U16_EnergyAC_RegData;a = a/0x20000000;             //电量单位是0.001KWH,比如算出来是2.002,表示2.002KWH    a = a/1;  										// 1 = 电流系数a = a/1;  										// 1 = 电压系数a = a * D_CAL_A_E;     			//D_CAL_A_E是校正系数,默认是1F_AC_E = a;F_AC_BACKUP_E = F_AC_E;	
}

读取通道的线性频率,实现代码如下所示:

void Read_HLW8110_LineFreq(void)
{float a;unsigned long b;Uart_Read_HLW8110_Reg(REG_UFREQ_ADDR,2);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){b = (unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);printf("A通道线性频率寄存器:%ld\n " ,b);}else{printf("A通道线性频率寄存器读取出错\r\n");B_Read_Error = 1;}a = (float)b;a = 3579545/(8*a);    F_AC_LINE_Freq = a;
}

读取通道功率因素,实现代码如下所示:

void Read_HLW8110_PF(void)
{float a;unsigned long b;//测量A通道的功率因素,需要发送EA+5A命令
//测量B通道的功率因素,需要发送EA+A5命令	Uart_Read_HLW8110_Reg(REG_PF_ADDR,3);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){b = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);printf("A通道功率因素寄存器:%ld\n " ,b);}else{printf("读取A通道功率因素寄存器出错\r\n");B_Read_Error = 1;}if (b>0x800000)       //为负,容性负载{a = (float)(0xffffff-b + 1)/0x7fffff;}else{a = (float)b/0x7fffff;}if (F_AC_P < 0.3) // 小于0.3W,空载或小功率,PF不准a = 0; //功率因素*100,最大为100,最小负100F_AC_PF = a;
}

读取通道相位角,实现代码如下所示:

void Read_HLW8110_Angle(void)
{float a;	unsigned long b;Uart_Read_HLW8110_Reg(REG_ANGLE_ADDR,2);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);printf("A通道线相角寄存器:%ld\n " ,b);}else{printf("A通道线相角寄存器出错\r\n");B_Read_Error = 1;}if ( F_AC_PF < 55)	//线性频率50HZ{a = b;a = a * 0.0805;F_Angle = a;}else{//线性频率60HZa = b;a = a * 0.0965;F_Angle = a;}if (F_AC_P < 0.5)		//功率小于0.5时,说明没有负载,相角为0{F_Angle = 0;}if (F_Angle < 90){a = F_Angle;printf("电流超前电压:%f\n " ,a);}else if (F_Angle < 180){a = 180-F_Angle;printf("电流滞后电压:%f\n " ,a);	}else if (F_Angle < 360){a = 360 - F_Angle;printf("电流滞后电压:%f\n " ,a);	}else{a = F_Angle -360;printf("电流超前电压:%f\n " ,a);	}
}

项目资源下载请参见:https://download.csdn.net/download/m0_38106923/87775438 


http://www.ppmy.cn/news/307403.html

相关文章

4.词频

#导入之前的语料库 import pandas as pd chapterpd.read_csv(chapter.xlsx)#自定义词典 import jieba dict 金庸小说词库.txt jieba.load_userdict(dict) # dict为自定义词典的路径#停用词 tmpdf pd.read_csv(停用词.txt,names [w], sep aaa, encoding utf-8) import jieb…

圈小猫游戏

前言 我之前写过一篇关于圈小猫游戏的文章&#xff0c;写了一半没有写完&#xff0c;但已经大致把我的容错值理论表达出来了。感觉由于个人学术能力不足&#xff0c;还是没有把这个游戏讲清楚&#xff0c;或者说文章太过于理论化了&#xff0c;难以真正应用在游戏里面。这篇文…

刘强东和他的四个梦想

Python实战社群 Java实战社群 长按识别下方二维码&#xff0c;按需求添加 扫码关注添加客服 进Python社群▲ 扫码关注添加客服 进Java社群▲ 作者 | 赵云合 来源 | 电商之家&#xff08;ID&#xff1a;iechome&#xff09; 转载请联系授权&#xff08;微信ID&#xff1a;laodia…

闲谈“自我认知“

注: 纯记录个人此刻想法,无主题,瞎写,不保证有人看通我写的啥 0 对于一个人的大脑活动,应该主要有四个重要部分情绪,动机,逻辑,固执 其中情绪是最高决策,动机和人的欲望有关,逻辑是理性思考,固执拒绝某信息输入,各自互相双向连接. 当你听一个励志演讲的时候是不是十分激动,情绪…

“抓住神经猫”的2D游戏创作

经过一阵子的学习&#xff0c;再次上传一份小游戏&#xff0c;叫“抓住神经猫”的游戏&#xff0c;通过二维数组&#xff0c;实例化出场景并进行游戏&#xff0c;直到围住神经猫或者让它逃脱为止。 首先呢&#xff0c;我把用到的图片上传&#xff0c;然后感兴趣的朋友可以保存…

文本挖掘学习笔记(二):文档信息向量化与主题关键词提取

注&#xff1a;学习笔记基于文彤老师文本挖掘的系列课程 全文基于《射雕英雄传》语料库&#xff0c;下面是读入数据的一个基于Pandas的通用操作框架。 读入为数据框 import pandas as pd from matplotlib import pyplot as plt %matplotlib inline # 有的环境配置下read_tab…

转换接头PL8000V-B 0-70MPa

校验台PL8000-TH 0-70MPa 量程PL8000V-B 转换接头PL8000V-B 0-70MPa 数字压力表PL8000T 0-10MPa 友谊森林奇遇记 小故事网 森林的故事   在一片森林中&#xff0c;有一群小动物快乐地生活着&#xff0c;过得无忧无虑。 有一天&#xff0c;来了一个巨人&#xff0c;他把整…

七夕节赚取徽章啦

*七夕来袭&#xff01;是时候展现专属于程序员的浪漫了&#xff01;你打算怎么给心爱的人表达爱意&#xff1f;鲜花礼物&#xff1f;代码表白&#xff1f;还是创意DIY&#xff1f;或者…无论那种形式&#xff0c;快来秀我们一脸吧&#xff01; 记录一起走过的那些日子 今天是…