Files
IM1253B/main.c

196 lines
5.8 KiB
C

#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, reveive_number - 2); //reveive_number 是接收数据总长度
if ((crcnow.byte[0] == Rx_Buffer[reveive_number - 1]) && (crcnow.byte[1] == Rx_Buffer[reveive_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];
}
}
}
}
void Print_data(void)
{
float voltage_value = (float)Voltage_data / 10000.0;
printf("电压: %.2f V\n", voltage_value);
float current_data = (float)Current_data / 10000.0;
printf("电流: %.2f A\n", current_data);
float power_data = (float)Power_data / 10000.0;
printf("功率: %.2f W\n", power_data);
float energy_data = (float)Energy_data / 10000.0;
printf("电能: %.2f KWH\n", energy_data);
float pf_data = (float)Pf_data / 10000.0;
printf("功率因数: %.2f \n", pf_data);
float cO2_data = (float)CO2_data / 10000.0;
printf("二氧化碳: %.2f KG\n", cO2_data);
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);
// 发送完成后接收数据并处理
reveive_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);
printf("IM1253B module\n");
while (1) {
watchdog_update(); // 喂狗
IM1253B();
printf("\n");
sleep_ms(2000);
}
return 0;
}