257 lines
7.7 KiB
C
257 lines
7.7 KiB
C
#include "IM1253B.h"
|
|
#include "common.h"
|
|
|
|
int Read_ID = 0x01;
|
|
unsigned char Tx_Buffer[8];
|
|
unsigned char Rx_Buffer[40];
|
|
unsigned char read_enable, receive_finished, receive_number;
|
|
unsigned long Voltage_data, Current_data, Power_data, Energy_data, Pf_data, CO2_data, Temperature_data, Hz_data;
|
|
int sec;
|
|
|
|
int IM1253B_INIT(void)
|
|
{
|
|
uint tx_offset = pio_add_program(IM1253B_PIO, &uart_tx_program);
|
|
uart_tx_program_init(IM1253B_PIO, IM1253B_PIO_SM_TX, tx_offset, IM1253B_PIO_TX_PIN, IM1253B_PIO_SERIAL_BAUD);
|
|
|
|
uint rx_offset = pio_add_program(IM1253B_PIO, &uart_rx_program);
|
|
uart_rx_program_init(IM1253B_PIO, IM1253B_PIO_SM_RX, rx_offset, IM1253B_PIO_RX_PIN, IM1253B_PIO_SERIAL_BAUD);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int IM1253B_PIO_UART_TX_DATA(PIO pio, uint sm, uint8_t * DATA, int DATA_LEN)
|
|
{
|
|
|
|
for (int i = 0; i < DATA_LEN; i++) {
|
|
uart_tx_program_putc(pio, sm, DATA[i]);
|
|
sleep_ms(1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int IM1253B_PIO_UART_RX_DATA(PIO pio, uint sm, uint8_t * DATA, int DATA_LEN)
|
|
{
|
|
char c = '\0';
|
|
int received_count = 0;
|
|
int timeout_ms = 1000; // 设置较长的超时时间
|
|
|
|
while (received_count < DATA_LEN && timeout_ms > 0) {
|
|
if (uart_rx_program_available(pio, sm)) {
|
|
c = uart_rx_program_getc(pio, sm);
|
|
DATA[received_count++] = c;
|
|
//printf("0x%X ", c);
|
|
/*
|
|
// 此处不能要对于 IM1253B
|
|
if (c == '\n') {
|
|
// 接收到换行符,停止接收数据
|
|
break;
|
|
}
|
|
*/
|
|
} else {
|
|
// 没有接收到数据,继续等待
|
|
sleep_ms(2);
|
|
timeout_ms--;
|
|
}
|
|
}
|
|
|
|
if (received_count == 0) {
|
|
// 没有接收到有效数据
|
|
return -1;
|
|
}
|
|
|
|
return received_count;
|
|
}
|
|
|
|
unsigned int calccrc(unsigned char crcbuf, unsigned int crc)
|
|
{
|
|
unsigned char i;
|
|
unsigned char chk;
|
|
crc = crc ^ crcbuf;
|
|
for (i = 0; i < 8; i++) {
|
|
chk = (unsigned char)(crc & 1);
|
|
crc = crc >> 1;
|
|
crc = crc & 0x7fff;
|
|
if (chk == 1)
|
|
crc = crc ^ 0xa001;
|
|
crc = crc & 0xffff;
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
unsigned int chkcrc(unsigned char *buf, unsigned char len)
|
|
{
|
|
unsigned char hi, lo;
|
|
unsigned int i;
|
|
unsigned int crc;
|
|
crc = 0xFFFF;
|
|
for (i = 0; i < len; i++) {
|
|
crc = calccrc(*buf, crc);
|
|
buf++;
|
|
}
|
|
hi = (unsigned char)(crc % 256);
|
|
lo = (unsigned char)(crc / 256);
|
|
crc = (((unsigned int)(hi)) << 8) | lo;
|
|
return crc;
|
|
}
|
|
|
|
void Print_data(void)
|
|
{
|
|
|
|
float voltage_value = (float)Voltage_data * 0.0001;
|
|
printf("电压: %.2f V\n", voltage_value);
|
|
|
|
float current_data = (float)Current_data * 0.0001;
|
|
printf("电流: %.2f A\n", current_data);
|
|
|
|
float power_data = (float)Power_data * 0.0001;
|
|
printf("功率: %.2f W\n", power_data);
|
|
|
|
float energy_data = (float)Energy_data * 0.0001;
|
|
printf("电能: %.4f KWH\n", energy_data);
|
|
|
|
float pf_data = (float)Pf_data * 0.001;
|
|
printf("功率因数: %.2f \n", pf_data);
|
|
|
|
float cO2_data = (float)CO2_data * 0.0001;
|
|
printf("二氧化碳: %.2f KG\n", cO2_data);
|
|
|
|
printf("温度: %.2f ℃\n", (float)Temperature_data * 0.01);
|
|
printf("频率: %.2f HZ\n", (float)Hz_data * 0.01);
|
|
|
|
printf("\n");
|
|
|
|
return;
|
|
}
|
|
|
|
void Analysis_data(void)
|
|
{
|
|
union crcdata {
|
|
unsigned int word16;
|
|
unsigned char byte[2];
|
|
} crcnow;
|
|
|
|
if (receive_finished == 1) // 接收完成
|
|
{
|
|
receive_finished = 0;
|
|
|
|
if (Rx_Buffer[0] == Read_ID) // 确认 ID 正确
|
|
{
|
|
crcnow.word16 = chkcrc(Rx_Buffer, receive_number - 2); // receive_number 是接收数据总长度
|
|
if ((crcnow.byte[0] == Rx_Buffer[receive_number - 1]) && (crcnow.byte[1] == Rx_Buffer[receive_number - 2])) // 确认 CRC 校验正确
|
|
{
|
|
Voltage_data = (((unsigned long)(Rx_Buffer[3])) << 24) | (((unsigned long)(Rx_Buffer[4])) << 16) | (((unsigned long)(Rx_Buffer[5])) << 8) | Rx_Buffer[6];
|
|
Current_data = (((unsigned long)(Rx_Buffer[7])) << 24) | (((unsigned long)(Rx_Buffer[8])) << 16) | (((unsigned long)(Rx_Buffer[9])) << 8) | Rx_Buffer[10];
|
|
Power_data = (((unsigned long)(Rx_Buffer[11])) << 24) | (((unsigned long)(Rx_Buffer[12])) << 16) | (((unsigned long)(Rx_Buffer[13])) << 8) | Rx_Buffer[14];
|
|
Energy_data = (((unsigned long)(Rx_Buffer[15])) << 24) | (((unsigned long)(Rx_Buffer[16])) << 16) | (((unsigned long)(Rx_Buffer[17])) << 8) | Rx_Buffer[18];
|
|
Pf_data = (((unsigned long)(Rx_Buffer[19])) << 24) | (((unsigned long)(Rx_Buffer[20])) << 16) | (((unsigned long)(Rx_Buffer[21])) << 8) | Rx_Buffer[22];
|
|
CO2_data = (((unsigned long)(Rx_Buffer[23])) << 24) | (((unsigned long)(Rx_Buffer[24])) << 16) | (((unsigned long)(Rx_Buffer[25])) << 8) | Rx_Buffer[26];
|
|
Temperature_data = (((unsigned long)(Rx_Buffer[27])) << 24) | (((unsigned long)(Rx_Buffer[28])) << 16) | (((unsigned long)(Rx_Buffer[29])) << 8) | Rx_Buffer[30];
|
|
Hz_data = (((unsigned long)(Rx_Buffer[31])) << 24) | (((unsigned long)(Rx_Buffer[32])) << 16) | (((unsigned long)(Rx_Buffer[33])) << 8) | Rx_Buffer[34];
|
|
|
|
Print_data();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 电能清零
|
|
void Electric_energy_(int *sec)
|
|
{
|
|
|
|
uint8_t RETURN_DATA[8] = { 0 };
|
|
uint8_t ELE_ZRRO[13] = { 0x01, 0x10, 0x00, 0x4B, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0xB6, 0x2C };
|
|
|
|
// 假如从开机算起60秒后
|
|
if (*sec >= 3) {
|
|
printf("电能清零\n");
|
|
IM1253B_PIO_UART_TX_DATA(IM1253B_PIO, IM1253B_PIO_SM_TX, ELE_ZRRO, 13);
|
|
sleep_ms(100);
|
|
|
|
IM1253B_PIO_UART_RX_DATA(IM1253B_PIO, IM1253B_PIO_SM_RX, RETURN_DATA, 8);
|
|
for (int i = 0; i < 8; i++) {
|
|
printf("0x%X ", RETURN_DATA[i]);
|
|
}
|
|
sleep_ms(100);
|
|
|
|
*sec = 0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void read_data(void)
|
|
{
|
|
static int i = 0;
|
|
union crcdata {
|
|
unsigned int word16;
|
|
unsigned char byte[2];
|
|
} crcnow;
|
|
|
|
if (read_enable == 1) // 到时间抄读模块,抄读间隔 1 秒钟(或其他)
|
|
{
|
|
read_enable = 0;
|
|
Tx_Buffer[0] = Read_ID; //模块的 ID 号,默认 ID 为 0x01
|
|
Tx_Buffer[1] = 0x03;
|
|
Tx_Buffer[2] = 0x00;
|
|
Tx_Buffer[3] = 0x48;
|
|
Tx_Buffer[4] = 0x00;
|
|
Tx_Buffer[5] = 0x08;
|
|
crcnow.word16 = chkcrc(Tx_Buffer, 6);
|
|
Tx_Buffer[6] = crcnow.byte[1]; //CRC 效验低字节在前
|
|
Tx_Buffer[7] = crcnow.byte[0];
|
|
|
|
// 发送数据
|
|
IM1253B_PIO_UART_TX_DATA(IM1253B_PIO, IM1253B_PIO_SM_TX, Tx_Buffer, 8);
|
|
sleep_ms(10);
|
|
|
|
// 接收数据
|
|
uint8_t _DATA[37] = { 0 };
|
|
IM1253B_PIO_UART_RX_DATA(IM1253B_PIO, IM1253B_PIO_SM_RX, _DATA, 37);
|
|
for (i = 0; i <= 37 - 1; i++) {
|
|
//printf("0x%X ", _DATA[i]);
|
|
Rx_Buffer[i] = _DATA[i];
|
|
}
|
|
sleep_ms(10);
|
|
}
|
|
}
|
|
|
|
void IM1253B(void *p)
|
|
{
|
|
(void)p;
|
|
|
|
IM1253B_INIT();
|
|
while (1) {
|
|
printf("IM1253B\n");
|
|
|
|
/*
|
|
// 官方软件内部按钮发送的数据
|
|
// 电能清零 TX[13]:01 10 00 4B 00 02 04 00 00 00 00 B6 2C
|
|
// RX[8]:01 10 00 4B 00 02 31 DE
|
|
|
|
// 读取 TX[8]:00 03 00 01 00 04 14 18
|
|
// RX[13]:01 03 08 02 35 01 08 41 30 01 05 44 BD (直流模块)
|
|
|
|
// 设置 TX[11]:00 10 00 04 00 01 02 01 05 6B D7
|
|
// RX[8]:01 10 00 04 00 01 40 08
|
|
*/
|
|
|
|
// 发送
|
|
read_enable = 1;
|
|
read_data();
|
|
sleep_ms(10);
|
|
|
|
// 发送完成后接收数据并处理
|
|
receive_number = 37;
|
|
receive_finished = 1;
|
|
Analysis_data();
|
|
|
|
// 打印处理后的数据
|
|
//Print_data();
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
|
|
}
|
|
|
|
return;
|
|
}
|