使用STM32接收HLW8032芯片的数值

STM32收HLW8032测量数据并计算电流电压功率

1.HLW8032串口发送形式

 HLW8032的串口输出的波特率是4800bps,每隔50ms 发送一次数据,HLW8032 的UART 使用两个引脚,TX 引脚用于从HLW8032 发送数据,数据以低位(LSB)优先发送,RX 引脚用于来接收来自微控制器的数据。HLW8032每发送一次完整数据是24byte; 从寄存器1(State REG)开发发送,到寄存器11(CheckSum REG)结束一组数据,一共11个寄存器,24 byte数据。

以下是数据格式:

2.寄存器说明

数据包的包头(状态寄存器)一般为:0x55        (如果在测量电压时不接负载,一段时间后电流寄存器将会溢出,此时数据包的包头会变成:0xF2)

校验位(检测寄存器)为:0x5A

电压参数寄存器,电压寄存器,电流参数寄存器,电流寄存器,功率参数寄存器,功率寄存器,数据分别被拆成了24个位,分为高8位,中8位,低8位,每8个位合成一个字节,共3个字节以16进制的形式发送。发送顺序是:高8位->中8位 ->低8位。所以在接收每个寄存器的值时需要将数据进行左移储存。

3.电能数据的计算

(1)电压有效值计算

(2)电流有效值计算

(3)有功功率的计算

4.STM32程序大概

uint8_t Serial_RxFlag;
int RX_data[24];
uint32_t VpR  = 0;                            // 电压参数寄存器
uint32_t VR   = 0;                            // 电压寄存器
double CpR  = 0;                            // 电流参数寄存器
double CR   = 0;   
uint32_t PpR  = 0;                            // 电流参数寄存器
uint32_t PR   = 0;                            // 电流寄存器
uint8_t Serial_RxFlag;

float VoltValue = 0.0;         //电压值
double IcurrentValue = 0.0;    //电流值
float PowerValue = 0.0;        //功率值

void Serial_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 4800;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART1, &USART_InitStructure);
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStructure);
	
	USART_Cmd(USART1, ENABLE);
}

uint8_t Serial_GetRxFlag(void)
{
	if (Serial_RxFlag == 1)
	{
		Serial_RxFlag = 0;
		return 1;
	}
	return 0;
}

void USART1_IRQHandler(void)
{
    extern int i = 0;
	RX_data[i++] = USART_ReceiveData(USART1);
	if((RX_data[0] != 0x55)&&(RX_data[0] != 0xF2))i = 0;
	if((i == 2) && (RX_data[1] != 0x5A)) i = 0;
	if(i == 25)
	{
		VpR = (RX_data[2]<<16) + (RX_data[3]<<8) + RX_data[4];
		VR = (RX_data[5]<<16) + (RX_data[6]<<8) + RX_data[7];
		VoltValue = (VpR/VR)*3.0645;//电压系数
		CpR = (RX_data[8]<<16) + (RX_data[9]<<8) + RX_data[10];
		CR = (RX_data[11]<<16) + (RX_data[12]<<8) + RX_data[13];
		IcurrentValue = (CpR/CR)+0.03;//补偿值
		PpR = (RX_data[14]<<16) + (RX_data[15]<<8) + RX_data[16];
		PR = (RX_data[17]<<16) + (RX_data[18]<<8) + RX_data[19];
		PowerValue = (PpR/PR)*3.1222;//功率补偿系数
		i = 0;
	}
	
}

*上述程序中的系数和补偿值是靠多组数据计算得出,适用性并不强,仅作参考。

作者:萧技电创EIIA

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32接收HLW8032芯片的数值

发表回复