135 lines
3.8 KiB
C
135 lines
3.8 KiB
C
//
|
|
// Created by Timothy Yin on 2025/3/29.
|
|
//
|
|
#include "IM1281B.h"
|
|
|
|
uint8_t IM1281B_ID = 0x01;
|
|
|
|
uint8_t IM_TxBuf[8] = {0};
|
|
uint8_t IM_RxBuf[40] = {0};
|
|
uint8_t IM_ReadFlag = 0;
|
|
uint8_t IM_RecvDone = 0;
|
|
uint8_t IM_RecvLen = 0;
|
|
|
|
uint32_t IM_Volt = 0;
|
|
uint32_t IM_Curr = 0;
|
|
uint32_t IM_Power = 0;
|
|
uint32_t IM_Energy = 0;
|
|
uint32_t IM_PF = 0;
|
|
uint32_t IM_CO2 = 0;
|
|
|
|
unsigned int Calc_CRC(const unsigned char crc_buf, unsigned int crc)
|
|
{
|
|
crc = crc ^ crc_buf;
|
|
for (unsigned char i = 0; i < 8; i++)
|
|
{
|
|
const unsigned char chk = crc & 1;
|
|
crc = crc >> 1;
|
|
crc = crc & 0x7fff;
|
|
if (chk == 1)
|
|
crc = crc ^ 0xa001;
|
|
crc = crc & 0xffff;
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
unsigned int Check_CRC(const unsigned char* buf, const unsigned char len)
|
|
{
|
|
unsigned int crc = 0xFFFF;
|
|
for (unsigned int i = 0; i < len; i++)
|
|
{
|
|
crc = Calc_CRC(*buf, crc);
|
|
buf++;
|
|
}
|
|
const unsigned char MSB = crc % 256;
|
|
const unsigned char LSB = crc / 256;
|
|
crc = (unsigned int)MSB << 8 | LSB;
|
|
return crc;
|
|
}
|
|
|
|
void IM_Read(void)
|
|
{
|
|
if (IM_ReadFlag == 1) // 到时间抄读模块,抄读间隔 1 秒钟(或其他)
|
|
{
|
|
union crc_data
|
|
{
|
|
unsigned int word16;
|
|
unsigned char byte[2];
|
|
} new_crc;
|
|
IM_ReadFlag = 0;
|
|
IM_TxBuf[0] = IM1281B_ID; //模块的 ID 号,默认 ID 为 0x01
|
|
IM_TxBuf[1] = 0x03;
|
|
IM_TxBuf[2] = 0x00;
|
|
IM_TxBuf[3] = 0x48;
|
|
IM_TxBuf[4] = 0x00;
|
|
IM_TxBuf[5] = 0x06;
|
|
new_crc.word16 = Check_CRC(IM_TxBuf, 6);
|
|
IM_TxBuf[6] = new_crc.byte[1]; //CRC 效验低字节在前
|
|
IM_TxBuf[7] = new_crc.byte[0];
|
|
|
|
for (unsigned int i = 0; i < 8; i++)
|
|
{
|
|
HAL_UART_Transmit(&huart1, &IM_TxBuf[i], 1, HAL_MAX_DELAY);
|
|
}
|
|
}
|
|
}
|
|
|
|
void IM_Analyze(void)
|
|
{
|
|
if (IM_RecvDone == 1) //接收完成
|
|
{
|
|
IM_RecvDone = 0;
|
|
if (IM_RxBuf[0] == IM1281B_ID) //确认 ID 正确
|
|
{
|
|
union crc_data
|
|
{
|
|
unsigned int word16;
|
|
unsigned char byte[2];
|
|
} new_crc;
|
|
new_crc.word16 = Check_CRC(IM_RxBuf, IM_RecvLen - 2); //IM_RecvLen 是接收数据总长度
|
|
if (new_crc.byte[0] == IM_RxBuf[IM_RecvLen - 1] && new_crc.byte[1] == IM_RxBuf[IM_RecvLen - 2])
|
|
{
|
|
// 01 03 18 00 23 81 d8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 e7 00 00 00 00 84 5c
|
|
IM_Volt =
|
|
(uint32_t)IM_RxBuf[3] << 24
|
|
| (uint32_t)IM_RxBuf[4] << 16
|
|
| (uint32_t)IM_RxBuf[5] << 8
|
|
| IM_RxBuf[6];
|
|
IM_Curr =
|
|
(uint32_t)IM_RxBuf[7] << 24
|
|
| (uint32_t)IM_RxBuf[8] << 16
|
|
| (uint32_t)IM_RxBuf[9] << 8
|
|
| IM_RxBuf[10];
|
|
IM_Power =
|
|
(uint32_t)IM_RxBuf[11] << 24
|
|
| (uint32_t)IM_RxBuf[12] << 16
|
|
| (uint32_t)IM_RxBuf[13] << 8
|
|
| IM_RxBuf[14];
|
|
IM_Energy =
|
|
(uint32_t)IM_RxBuf[15] << 24
|
|
| (uint32_t)IM_RxBuf[16] << 16
|
|
| (uint32_t)IM_RxBuf[17] << 8
|
|
| IM_RxBuf[18];
|
|
IM_PF =
|
|
(uint32_t)IM_RxBuf[19] << 24
|
|
| (uint32_t)IM_RxBuf[20] << 16
|
|
| (uint32_t)IM_RxBuf[21] << 8
|
|
| IM_RxBuf[22];
|
|
IM_CO2 =
|
|
(uint32_t)IM_RxBuf[23] << 24
|
|
| (uint32_t)IM_RxBuf[24] << 16
|
|
| (uint32_t)IM_RxBuf[25] << 8
|
|
| IM_RxBuf[26];
|
|
}
|
|
else
|
|
{
|
|
IM_Volt = 199;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
IM_Volt = 99;
|
|
}
|
|
}
|
|
}
|