#include "includes.h" #include "device.h" #include "tax_ctrl.h" #include "net_proc.h" #include "oiltank.h" typedef union { u8 c[5]; u32 i; } uData_t; typedef union { u32 i; float f; } uData1_t; system_oiltank_info_t system_oiltank; //CRC校验(本质和校验) static u32 _check_sum(u8 buf[], u32 len) { u32 i, check_sum = 0; uData_t data; for(i=0; i< len; i++) { check_sum += buf[i]; } #if 0 check_sum = ~check_sum; check_sum &= 0xffff; check_sum += 1; #else check_sum &= 0xffff; check_sum = 0xffff-check_sum+1; #endif snprintf(data.c, sizeof(data.c), "%04X", check_sum); return data.i; } static u32 _str_to_hex(uint8_t *data) { u8 i, ch; u32 hex = 0; //data_dump("====", data, 8); for(i = 0;i < 8;i++) { if(isdigit(data[i])) { ch = data[i] - '0' + 0x0; } else if(isalpha(data[i])){ ch = data[i] - 'A' + 0xA; } hex = (hex<<4)|ch; } //printf("%08x, %0.2f\r\n", hex, (float)(hex)); return (hex); } int oiltank_data_update(I201_FUELTANK_DATA *p_data) { uData1_t data; oiltank_info_t *p_tank = NULL; u8 id = 0; id = p_data->TT[1] - '0'; if(id > OILTANK_VALID_COUNT) { return 0; } //data_dump("******", (uint8_t * )p_data, YB_SS160_RCV_DATASIZE); p_tank = &system_oiltank.oiltank[id]; printf("罐号: %c%c\r\n", p_data->TT[0], p_data->TT[1]); printf("油品: %c\r\n", p_data->P); printf("油罐状态: %c%c%c%c\r\n", p_data->SSSS[0], p_data->SSSS[1], p_data->SSSS[2], p_data->SSSS[3]); printf("%c%c 组数据\r\n", p_data->NN[0], p_data->NN[1]); p_tank->id = id; BIT_SET(system_oiltank.valid, p_tank->id); p_tank->quality = p_data->P; /* 首先来看单精度浮点型float。 float占用4字节空间,也就是32位。 从左向右数,第1位是符号位(0代表正数,1代表负数),接着是8位指数位,剩下的23位是数据位。如下所示 S EEEEEEEE DDDDDDDDDDDDDDDDDDDDDDD */ //1、容积;2、TC 容积;3、罐空;4 高度;5、水位;6、温度;7、水容积 p_tank->volume = _str_to_hex(p_data->TankVolume); printf("Tank Volume : 0x%08x\r\n", p_tank->volume); //printf("Tank Volume :%0.2f\r\n", data.f); p_tank->oil_volume = _str_to_hex(p_data->NetVolume); //printf("Net Volume :%0.2f\r\n", data.f); data.i = _str_to_hex(p_data->CrossVolume); //printf("Cross Volume :%0.2f\r\n", data.f); p_tank->height = _str_to_hex(p_data->Height); //printf("Height :%0.2f\r\n", data.f); data.i = _str_to_hex(p_data->Water); //printf("Water :%0.2f\r\n", data.f); p_tank->temperature = _str_to_hex(p_data->Temp); //printf("Temp :%0.2f\r\n", data.f); p_tank->water_volume = _str_to_hex(p_data->WaterVolume); //printf("Water Volume :%0.2f\r\n", data.f); p_tank->valid_num++; return 0; } int oiltank_YB_SS160_cmd_comm(uint8_t uart) { int ret = -1; uint8_t rcv_buf[1024], send_buf[128]; uint32_t i, rcv_size = 0, send_size = YB_SS160_SEND_SIZE, crc; RS232_YB_SS160_SEND *p_tank_tx = (RS232_YB_SS160_SEND *)send_buf; RS232_YB_SS160_RECEIVE_HEAD *p_tank_rx_head = (RS232_YB_SS160_RECEIVE_HEAD *)rcv_buf; RS232_YB_SS160_RECEIVE_TAIL *p_tank_rx_tail = NULL; I201_FUELTANK_DATA *p_data = NULL; int FuelTank_Num = 0; oiltank_info_t *p_tank = NULL; /* 查询所有油管数据 */ //i201TT, /* i201TT YYMMDDHHmm 日期和时间(年/月/日/时/分) TTpssssNNFFFFFFFF... TTpssssNNFFFFFFFF... &&CCCC */ p_tank_tx->SOH = 0x01; strcpy((char *)p_tank_tx->FCN_CODE, "i20100"); p_tank_tx->EXT = 0x03; data_dump("YB_SS160 oiltank send", send_buf, send_size); uart_msg_send(uart, (char *)p_tank_tx, send_size); rcv_size = uart_blocking_read((char *)rcv_buf, uart, 5000); if(rcv_size) { data_dump("YB_SS160 oiltank recv", rcv_buf, rcv_size); if(memcmp((char *)p_tank_rx_head->FCN_CODE, "i20100", sizeof(p_tank_rx_head->FCN_CODE)) == 0) { /* check sum */ p_tank_rx_tail = (RS232_YB_SS160_RECEIVE_TAIL *)(rcv_buf + rcv_size - YB_SS160_RCV_TAILSIZE); crc = _check_sum(rcv_buf, rcv_size - YB_SS160_RCV_TAILSIZE + 2); printf("headsize : %d, datasize : %d, tailsize : %d, rcv_size : %d, %x, %x, %x\r\n", YB_SS160_RCV_HEADSIZE, YB_SS160_RCV_DATASIZE, YB_SS160_RCV_TAILSIZE, rcv_size, p_tank_rx_tail->FCN_FLAG, p_tank_rx_tail->CheckCode , crc); if((p_tank_rx_tail->FCN_FLAG == YB_SS160_FCN_FLAG)&& (p_tank_rx_tail->CheckCode == crc)) { rcv_size -= (YB_SS160_RCV_HEADSIZE + YB_SS160_RCV_TAILSIZE); FuelTank_Num = rcv_size/YB_SS160_RCV_DATASIZE; for(i = 0;i < FuelTank_Num;i++) { p_data = (I201_FUELTANK_DATA *)(rcv_buf + YB_SS160_RCV_HEADSIZE + i*YB_SS160_RCV_DATASIZE); oiltank_data_update(p_data); } } } } for(i = 0;i < OILTANK_VALID_COUNT;i++) { if(BIT_IS_SET(system_oiltank.valid, 1<valid_num == 0) { BIT_CLC(system_oiltank.valid, i); memset(p_tank, 0, sizeof(oiltank_info_t)); } else { p_tank->valid_num = 0; } } } return ret; } void oiltank_polling(void) { uint8_t uart = OILTANK_UART; YTSF_GPIO_RS485_RESET(); YTSF_GPIO_YTSF_RESET(); YTSF_GPIO_AB_SET(); oiltank_YB_SS160_cmd_comm(uart); } void oiltank_msg_timer(void *p_tmr, void *p_arg) { inner_msg_format_t *p_msg = NULL; uint32_t *p_collect_time = NULL, i; gb_oiltank_header_t *p_oiltank_header = NULL; oiltank_info_t *p_oiltank_info = NULL; if(system_oiltank.valid == 0) {/* 没有有效数据 */ return ; } p_msg = (inner_msg_format_t *)net_queue_mem_calloc(); if(p_msg == NULL) { return ; } //HEADER p_oiltank_header = (gb_oiltank_header_t *)p_msg->info; device_type_and_id_get(&p_oiltank_header->device_type, &p_oiltank_header->device_id); p_oiltank_header->device_status = 0; p_oiltank_header->oiltank_count = 1; //OILTANK_INFO for(i = 0;i < OILTANK_VALID_COUNT;i++) { system_oiltank.current += i + 1; system_oiltank.current = system_oiltank.current%OILTANK_VALID_COUNT; if(BIT_IS_SET(system_oiltank.valid, 1<info + GB_OILTANK_HEADER_LEN); #if 0 p_oiltank_info->id = 1; p_oiltank_info->quality = QUALITY_95; p_oiltank_info->volume = 100; p_oiltank_info->oil_volume = 200; p_oiltank_info->water_volume = 300; p_oiltank_info->temperature = 50; p_oiltank_info->height = 400; #else memcpy(p_oiltank_info, &system_oiltank.oiltank[system_oiltank.current], GB_OILTANK_INFO_LEN); #endif //timestamp p_collect_time = (uint32_t *)(p_msg->info + GB_OILTANK_HEADER_LEN + GB_OILTANK_INFO_LEN); *p_collect_time = RTC_GetCounter(); net_msg_frame_fill(p_msg, net_msg_type_oiltank, GB_OILTANK_HEADER_LEN + GB_OILTANK_INFO_LEN + 4); net_queue_insert((char *)p_msg, sizeof(inner_msg_format_t)); data_dump(MQTT_UPLINK_TANK_TOPIC, (uint8_t *)p_msg, sizeof(inner_msg_format_t)); } OS_TMR oiltank_timer; int oiltank_init(void) { OS_ERR err; //GUN CHECK,PC0 - PC 3 GPIO_COMM_Init(RCC_APB2Periph_GPIOC, GPIOC, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 , GPIO_Mode_IN_FLOATING, GPIO_Speed_2MHz); //SW_PORT_RS485、SW_PORT_AB、SW_PORT_CD、SW_PORT_YTSF GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6, GPIO_Mode_Out_PP, GPIO_Speed_2MHz); //YTSF_REV2 GPIO_COMM_Init(RCC_APB2Periph_GPIOD, GPIOD, GPIO_Pin_7, GPIO_Mode_IPU, GPIO_Speed_2MHz); //YTSF_RST_N GPIO_COMM_Init(RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP, GPIO_Speed_2MHz); YTSF_GPIO_EN(); //YTSF_POSITION_N GPIO_COMM_Init(RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_6, GPIO_Mode_IPU, GPIO_Speed_2MHz); //YTSF_EN_N GPIO_COMM_Init(RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_7, GPIO_Mode_Out_PP, GPIO_Speed_2MHz); YTSF_GPIO_DN(); OSTmrCreate(&oiltank_timer, "oiltank_tmr", OILTANK_MSG_PERIOD, OILTANK_MSG_PERIOD, OS_OPT_TMR_PERIODIC, oiltank_msg_timer, NULL, &err); OSTmrStart(&oiltank_timer, &err); YTSF_GPIO_DN(); memset(&system_oiltank, 0 ,sizeof(system_oiltank_info_t)); system_oiltank.valid = 0; system_oiltank.current = 0; return 0; }