使用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