/* * @Author: chenjie * @Date: 2022-06-06 * @LastEditTime: 2022-10-27 * @LastEditors: chenjie * @Description: * @FilePath: \S32K146_4G\code\app\AppTaskUart0.c * Copyright (c) 2022 by chenjie, All Rights Reserved. */ #include "AppTaskUart0.h" #ifdef APP_UART0_ENABLE static process_Uart0 gProcess_Uart0_Task = PROCESS_UART_STATE_IDLE; #define PROC_UART0_STATE_SWITCH(a) (gProcess_Uart0_Task = a) bool bmsCellInfoDecode1(uint8 *dataPtr); bool bmsCellInfoDecode2(uint8 *dataPtr); bool bmsTempInfoDecode(uint8 *dataPtr); bool bmsOtherInfoDecode(uint8 *dataPtr); void UartBusReadDataFunc(uint16 RegAddrBegin, uint16 Reg_Num, bool (*decodeFunc)(uint8 *dataPtr)); // void battDataCalFunc(void); static uint16 UartNoDataReadCounter = 0; void Uart0Task(void *pvParameters) { (void)pvParameters; UartAnsType UartAnsData; uint16 pReadLen = 0; static uint8 writecounter = 0; while (1) { switch (gProcess_Uart0_Task) { case PROCESS_UART_STATE_IDLE: { vTaskDelay(pdMS_TO_TICKS(10)); if ((TimerCounter % 1000) == 0) { PROC_UART0_STATE_SWITCH(PROCESS_UART_STATE_READ); } else if (TimerCounter % 100 == 0) { PROC_UART0_STATE_SWITCH(PROCESS_UART_STATE_WRITE); } break; } case PROCESS_UART_STATE_READ: { /*01 04 00 01 00 38 A0 18 01 04 00 64 00 3C B1 C4 01 04 01 90 00 28 F1 C5 */ Dio_FlipChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2); //其他参数读取 UartBusReadDataFunc(0x01, 0x38, bmsOtherInfoDecode); //电压读取 UartBusReadDataFunc(0x64, 60, bmsCellInfoDecode1); UartBusReadDataFunc(0x64 + 60, 60, bmsCellInfoDecode2); //温度读取 UartBusReadDataFunc(0x190, 40, bmsTempInfoDecode); //没有读到数据时的默认值 if (UartNoDataReadCounter > 10) { memset((uint8 *)&UartAnsData, 0x00, sizeof(UartAnsData)); bmsCellInfoDecode1(UartAnsData.Data); bmsCellInfoDecode2(UartAnsData.Data); bmsTempInfoDecode(UartAnsData.Data); bmsOtherInfoDecode(UartAnsData.Data); PutErrorNum(ErrorArray, sizeof(ErrorArray) / 2, 1); vTaskDelay(pdMS_TO_TICKS(2000)); } PROC_UART0_STATE_SWITCH(PROCESS_UART_STATE_IDLE); break; } case PROCESS_UART_STATE_WRITE: { if (battSeparateEnable) //最多重新写5次 { uint16 RegAddress = 0; uint16 CRC_chk_buffer = 0; uint8 WriteData[2] = {0x00, 0x00}; uint8 UartRecvBuffer[10]; if (!battSeparateCtlState) { WriteData[1] = 0x55; } else { WriteData[1] = 0xAA; } RegAddress = 100; UartWriteMsgType Uart_Write_Msg; Uart_Write_Msg.Bms_Address = BMS_ADDRESS_CODE; Uart_Write_Msg.Bms_Funcode = UART_WRITE_CODE; Uart_Write_Msg.Reg_Begin_H = RegAddress >> 8; Uart_Write_Msg.Reg_Begin_L = RegAddress; Uart_Write_Msg.Reg_Num_H = 0x00; Uart_Write_Msg.Reg_Num_L = 0x01; Uart_Write_Msg.Data_Count = 0x02; //要写入的字节数 memcpy(Uart_Write_Msg.Data, WriteData, 2); CRC_chk_buffer = crc_chk((uint8 *)&Uart_Write_Msg, sizeof(Uart_Write_Msg) - 2); Uart_Write_Msg.CRC_L = CRC_chk_buffer; Uart_Write_Msg.CRC_H = CRC_chk_buffer >> 8; UART_Query_Data(UART_LPUART0, UART_LPUART0, (uint8 *)&Uart_Write_Msg, sizeof(Uart_Write_Msg), UartRecvBuffer, &pReadLen, 500); if (pReadLen > 3 && *(UartRecvBuffer + 1) == 0x10) { writecounter = 0; battSeparateEnable = 0; } else { writecounter++; } } if (writecounter >= 5) { battSeparateEnable = 0; writecounter = 0; } PROC_UART0_STATE_SWITCH(PROCESS_UART_STATE_IDLE); break; } case PROCESS_UART_STATE_SLEEP: { break; } default: break; } } } bool bmsCellInfoDecode1(uint8 *dataPtr) //电压数据解码1 { for (uint8 i = 0; i < 60; i++) { battCellU[i] = ((dataPtr[(0x00 + i) * 2] << 8) | dataPtr[(0x00 + i) * 2 + 1]); } return true; } bool bmsCellInfoDecode2(uint8 *dataPtr) //电压数据解码2 { for (uint8 i = 0; i < 60; i++) { battCellU[i+60] = ((dataPtr[(0x00 + i) * 2] << 8) | dataPtr[(0x00 + i) * 2 + 1]); } return true; } bool bmsTempInfoDecode(uint8 *dataPtr) //温度数据解码 { for (uint8 i = 0; i < BMS_TEMPNUM; i++) { battCellTemp[i] = dataPtr[(0x00 + i) * 2 + 1]; } return true; } bool bmsOtherInfoDecode(uint8 *dataPtr) //其他数据解析 { uint16 Batt_current; battPackVol = (dataPtr[(0x00) * 2]) << 8 | (dataPtr[(0x00) * 2 + 1]); Batt_current = (dataPtr[(0x01) * 2] << 8) | (dataPtr[(0x01) * 2 + 1]); if(battPackVol==0) { Batt_current=16000; } battI = Batt_current - 6000; //电流偏移量不同 battSOC = dataPtr[(0x02) * 2 + 1]; battSOH = dataPtr[(0x03) * 2 + 1]; battWorkState = (dataPtr[(0x06) * 2 + 1]) & 0x03; //电池状态(原始数据),3表示开路,2表示放电,1表示充电 switch (battWorkState) //电池状态(上传数据),0表示开路,1表示放电,2表示充电 { case 0: battWorkState = 0; break; case 1: battWorkState = 2; break; case 2: battWorkState = 1; break; case 3: battWorkState = 0; break; default: break; } maxCellVol = (dataPtr[(0x13) * 2] << 8) | dataPtr[(0x13) * 2 + 1]; minCellVol = (dataPtr[(0x16) * 2] << 8) | dataPtr[(0x16) * 2 + 1]; if(battPackVol==0) { return false; } else { uint32 temp = 0; temp = ((dataPtr[(0x34) * 2] << 24) | (dataPtr[(0x34) * 2 + 1]<<16)| (dataPtr[(0x35) * 2]<<8)| (dataPtr[(0x35) * 2 + 1]))*100; if ((temp- AppConfigInfo.AppDataInfo.battDischrgAccEnrg)>10) { AppConfigInfo.appSaveFlg = true; } AppConfigInfo.AppDataInfo.battDischrgAccEnrg = temp; temp = ((dataPtr[(0x32) * 2] << 24) | (dataPtr[(0x32) * 2 + 1]<<16)| (dataPtr[(0x33) * 2]<<8)| (dataPtr[(0x33) * 2 + 1]))*100; AppConfigInfo.AppDataInfo.battChrgAccEnrg = temp; AppConfigInfo.AppDataInfo.battCycleTimes = AppConfigInfo.AppDataInfo.battDischrgAccEnrg / 49000; } return true; } void UartBusReadDataFunc(uint16 RegAddrBegin, uint16 Reg_Num, bool (*decodeFunc)(uint8 *dataPtr)) { // argv In UartQueryType Uart0AskMsg; uint16 ReadLen1 = 0; uint16 ReadLenTar = 0; uint8 ReadDelayCounter = 0; uint16 CRC_chk_buffer = 0; uint16 pReadLen = 0; UartAnsType UartAnsData; uint8 UartDataRecv[256]; Uart0AskMsg.Bms_Address = BMS_ADDRESS_CODE; Uart0AskMsg.Bms_Funcode = UART_READ_CODE; Uart0AskMsg.Reg_Begin_H = RegAddrBegin >> 8; Uart0AskMsg.Reg_Begin_L = RegAddrBegin; Uart0AskMsg.Reg_Num_H = Reg_Num >> 8; Uart0AskMsg.Reg_Num_L = Reg_Num; CRC_chk_buffer = crc_chk((uint8 *)&Uart0AskMsg, 6); Uart0AskMsg.CRC_L = CRC_chk_buffer; Uart0AskMsg.CRC_H = CRC_chk_buffer >> 8; UART_Send_Data(UART_LPUART0, (uint8 *)&Uart0AskMsg, sizeof(Uart0AskMsg), 100); ReadLenTar = (Reg_Num)*2 + 5; memset((uint8 *)&UartAnsData, 0x00, sizeof(UartAnsData)); while (1) { UART_Receive_Data(UART_LPUART0, UartDataRecv, &pReadLen, 100); if (pReadLen > 2) { memcpy((uint8 *)&UartAnsData + ReadLen1, UartDataRecv, pReadLen); ReadLen1 = ReadLen1 + pReadLen; } else { ReadDelayCounter++; } if (ReadLen1 >= ReadLenTar) { ReadDelayCounter = 0; pReadLen = ReadLen1; ReadLen1 = 0; break; } if (ReadDelayCounter >= 20) { ReadDelayCounter = 0; pReadLen = 0; ReadLen1 = 0; break; } } if (pReadLen > 0) { uint16 CrcChkGet = 0xffff; uint16 CrcChkCal = 0x0000; CrcChkCal = crc_chk((uint8 *)&UartAnsData, pReadLen - 2); CrcChkGet = ((uint16)(UartAnsData.Data[pReadLen - 1 - 3]) << 8) | ((uint16)(UartAnsData.Data[pReadLen - 2 - 3])); if (CrcChkCal == CrcChkGet) { decodeFunc(UartAnsData.Data); UartNoDataReadCounter = 0; } else { UartNoDataReadCounter++; } } else { UartNoDataReadCounter++; } } #endif