#include "main.h" 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 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]; // 发送数据 uart_write_blocking(UART0, Tx_Buffer, 8); sleep_ms(10); // 接收数据 uint8_t _DATA[37] = { 0 }; uart_read_blocking(UART0, _DATA, 37); for (i = 0; i <= 37 - 1; i++) { //printf("0x%X ", _DATA[i]); Rx_Buffer[i] = _DATA[i]; } sleep_ms(10); } } void Analysis_data(void) { unsigned char i; 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]; } } } } 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("电能: %.2f 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); return; } // 电能清零 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"); uart_write_blocking(UART0, ELE_ZRRO, 13); sleep_ms(10); uart_read_blocking(UART0, RETURN_DATA, 8); for (int i = 0; i <= 8 - 1; i++) { printf("0x%X ", RETURN_DATA[i]); } printf("\n"); } return; } static uint16_t IM1253B(void) { static int i = 0; // 初始化UART uart_init(UART0, BAUD_RATE); gpio_set_function(UART0_TX_PIN, GPIO_FUNC_UART); gpio_set_function(UART0_RX_PIN, GPIO_FUNC_UART); uart_set_hw_flow(UART0, false, false); uart_set_format(UART0, DATA_BITS, STOP_BITS, PARITY); sleep_ms(10); /* // 官方软件内部按钮发送的数据 // 电能清零 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(); // 打印原始十六进制数据 for (i = 0; i <= 37 - 1; i++) { printf("0x%X ", Rx_Buffer[i]); } printf("\n"); // 打印处理后的数据 Print_data(); return 0; } int main(void) { stdio_init_all(); sleep_ms(1000); set_sys_clock_khz(250000, true); // 启动看门狗, 程序如果有阻塞或者程序逻辑错误重启 if (watchdog_caused_reboot()) { // 判断是否从看门狗启动或者正常启动 printf("Rebooted by Watchdog!\n"); } else { printf("Clean boot\n"); } watchdog_enable(8300, 1); // 8秒检测是否重新加载看门狗计数器. (不更新计数器则重启硬件, 最高8秒(8秒后不喂狗硬件重启)) watchdog_start_tick(12); sec = 0; printf("IM1253B Module\n"); while (1) { watchdog_update(); // 喂狗 IM1253B(); printf("\n"); // 电能清零 sec++; Electric_energy_(sec); sleep_ms(2000); } return 0; }