|
@@ -5,307 +5,4 @@
|
|
|
* Author: QiXiang_CHENJIE
|
|
|
*/
|
|
|
#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 bmsCellInfoDecode(uint8 *dataPtr);
|
|
|
-bool bmsOtherInfoDecode(uint8 *dataPtr);
|
|
|
-void Uart0Task(void *pvParameters)
|
|
|
-{
|
|
|
- (void)pvParameters;
|
|
|
- UartQueryType Uart0AskMsg;
|
|
|
- uint16 Reg_Num = 0;
|
|
|
- uint16 RegAddrBegin = 0;
|
|
|
- uint16 CRC_chk_buffer = 0;
|
|
|
- uint16 pReadLen = 0;
|
|
|
- UartAnsType UartAnsData;
|
|
|
- static uint8 writecounter = 0;
|
|
|
- uint16 UartNoDataReadCounter = 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
|
|
|
- {
|
|
|
- PROC_UART0_STATE_SWITCH(PROCESS_UART_STATE_WRITE);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case PROCESS_UART_STATE_READ:
|
|
|
- {
|
|
|
- /*电压电流数据读取(第一次读取)*/
|
|
|
- pReadLen = 0;
|
|
|
- Dio_FlipChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2);
|
|
|
- RegAddrBegin = 0x00;
|
|
|
- Reg_Num =AppDataInfo.BattCellCount + 3;
|
|
|
- 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;
|
|
|
- memset(RX_Buffer[UART_LPUART0],0x00,sizeof(RX_Buffer[UART_LPUART0]));
|
|
|
- UART_Query_Data(UART_LPUART0,UART_LPUART0,(uint8 *)&Uart0AskMsg,sizeof(Uart0AskMsg),RX_Buffer[UART_LPUART0], &pReadLen,500);
|
|
|
- if (pReadLen > 0)
|
|
|
- {
|
|
|
- uint16 CrcChkGet = 0xffff;
|
|
|
- uint16 CrcChkCal = 0x0000;
|
|
|
- memcpy((uint8 *)(&UartAnsData),RX_Buffer[UART_LPUART0],0x03);
|
|
|
- UartAnsData.DataPtr = (uint8 *)(&RX_Buffer[UART_LPUART0][3]);
|
|
|
- CrcChkCal = crc_chk(RX_Buffer[UART_LPUART0], pReadLen-2);
|
|
|
- CrcChkGet = (uint16)((RX_Buffer[UART_LPUART0][pReadLen-1]<<8)|(RX_Buffer[UART_LPUART0][pReadLen-2]));
|
|
|
- if(CrcChkCal==CrcChkGet)
|
|
|
- {
|
|
|
- bmsCellInfoDecode(UartAnsData.DataPtr);
|
|
|
- UartNoDataReadCounter = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- UartNoDataReadCounter++;
|
|
|
- }
|
|
|
- /*温度及其他状态信息读取(第二次读取)*/
|
|
|
- pReadLen = 0;
|
|
|
- RegAddrBegin = 0x03 + AppDataInfo.BattCellCount;
|
|
|
- Reg_Num = 0x1B + AppDataInfo.BattTempCount; //读取的寄存器数据,暂定,分开读取
|
|
|
- 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;
|
|
|
- /*RS485查询命令需要使能
|
|
|
- Dio_WriteChannel(DioConf_DioChannel_PTB4_GPIO_OUT_MCU_RS485_EN, STD_ON);
|
|
|
- UART_Send_Data(UART_LPUART0, (uint8 *)&Uart0AskMsg, sizeof(Uart0AskMsg), 1000);
|
|
|
- Dio_WriteChannel(DioConf_DioChannel_PTB4_GPIO_OUT_MCU_RS485_EN, STD_OFF);
|
|
|
- memset(RX_Buffer[UART_LPUART0], 0x00, sizeof(RX_Buffer[UART_LPUART0]));
|
|
|
- UART_Receive_Data(UART_LPUART0, RX_Buffer[UART_LPUART0], &pReadLen, 1000);
|
|
|
- Dio_WriteChannel(DioConf_DioChannel_PTB4_GPIO_OUT_MCU_RS485_EN, STD_ON);
|
|
|
- */
|
|
|
- /*TTL直连可以直接查询*/
|
|
|
- memset(RX_Buffer[UART_LPUART0],0x00,sizeof(RX_Buffer[UART_LPUART0]));
|
|
|
- UART_Query_Data(UART_LPUART0,UART_LPUART0,(uint8 *)&Uart0AskMsg,sizeof(Uart0AskMsg),RX_Buffer[UART_LPUART0], &pReadLen,500);
|
|
|
- if (pReadLen > 0)
|
|
|
- {
|
|
|
- uint16 CrcChkGet = 0xffff;
|
|
|
- uint16 CrcChkCal = 0x0000;
|
|
|
- memcpy((uint8 *)(&UartAnsData),RX_Buffer[UART_LPUART0],0x03);
|
|
|
- UartAnsData.DataPtr = (uint8 *)(&RX_Buffer[UART_LPUART0][3]);
|
|
|
- CrcChkCal = crc_chk(RX_Buffer[UART_LPUART0], pReadLen-2);
|
|
|
- CrcChkGet = (uint16)((RX_Buffer[UART_LPUART0][pReadLen-1]<<8)|(RX_Buffer[UART_LPUART0][pReadLen-2]));
|
|
|
- if(CrcChkCal==CrcChkGet)
|
|
|
- {
|
|
|
- bmsOtherInfoDecode(UartAnsData.DataPtr);
|
|
|
- UartNoDataReadCounter = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- UartNoDataReadCounter++;
|
|
|
- }
|
|
|
- //没有读到数据时的默认值
|
|
|
- if(UartNoDataReadCounter>20)
|
|
|
- {
|
|
|
- memset(RX_Buffer[UART_LPUART0],0x00,sizeof(RX_Buffer[UART_LPUART0]));
|
|
|
- memcpy((uint8 *)(&UartAnsData),RX_Buffer[UART_LPUART0],0x03);
|
|
|
- UartAnsData.DataPtr = (uint8 *)(&RX_Buffer[UART_LPUART0][3]);
|
|
|
- bmsCellInfoDecode(UartAnsData.DataPtr);
|
|
|
- bmsOtherInfoDecode(UartAnsData.DataPtr);
|
|
|
- PutErrorNum(ErrorArray, sizeof(ErrorArray)/2, 1);
|
|
|
- }
|
|
|
- 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};
|
|
|
- if(battSeparateEnableState)
|
|
|
- {
|
|
|
- setbit(WriteData[1],7);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- clrbit(WriteData[1],7);
|
|
|
- }
|
|
|
- RegAddress = 0x1B + AppDataInfo.BattCellCount + AppDataInfo.BattTempCount;
|
|
|
- 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),RX_Buffer[UART_LPUART0], &pReadLen,500);
|
|
|
- if (pReadLen>0&&RX_Buffer[UART_LPUART0][1] == 0x10)
|
|
|
- {
|
|
|
- writecounter = 0;
|
|
|
- battSeparateEnable = 0;
|
|
|
- }
|
|
|
- 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 bmsCellInfoDecode(uint8 *dataPtr) //根据串口协议确定的解码函数,电压电流解码
|
|
|
-{
|
|
|
- uint8 i = 0;
|
|
|
- sint8 BattCurrentNegFlag = 1;
|
|
|
- uint16 Batt_current;
|
|
|
- uint8 BATT_CELL_VOL_NUM = 0, BATT_TEMP_NUM = 0;
|
|
|
- uint32 Battsumvoltage = 0;
|
|
|
- BATT_CELL_VOL_NUM = (dataPtr[(0x00) * 2] << 8) | (dataPtr[(0x00) * 2 + 1]);
|
|
|
- BATT_TEMP_NUM = ((dataPtr[(0x01) * 2] << 8) | (dataPtr[(0x01) * 2 + 1])) - BmsOtherTemp;
|
|
|
- if (BATT_CELL_VOL_NUM != AppDataInfo.BattCellCount || BATT_TEMP_NUM != AppDataInfo.BattTempCount)
|
|
|
- {
|
|
|
- BATT_CELL_VOL_NUM = AppDataInfo.BattCellCount;
|
|
|
- BATT_TEMP_NUM = AppDataInfo.BattTempCount;
|
|
|
- }
|
|
|
- Batt_current = (dataPtr[(0x02 + BATT_CELL_VOL_NUM) * 2] << 8) | (dataPtr[(0x02 + BATT_CELL_VOL_NUM) * 2 + 1]);
|
|
|
- //原始数据:充电为负,放电为正
|
|
|
- if (Batt_current < 0x8000) //充电过程
|
|
|
- {
|
|
|
- if (Batt_current > 0x8000) // 数据为负
|
|
|
- {
|
|
|
- //求补码,结果为负
|
|
|
- Batt_current = (uint16)((uint16)(~(Batt_current)) + 1);
|
|
|
- Batt_current = Batt_current / 10;
|
|
|
- BattCurrentNegFlag = -1;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //源码,结果为负
|
|
|
- Batt_current = Batt_current / 10;
|
|
|
- BattCurrentNegFlag = -1;
|
|
|
- }
|
|
|
- }
|
|
|
- else //放电过程
|
|
|
- {
|
|
|
- if (Batt_current > 0x8000) // 数据为负
|
|
|
- {
|
|
|
- //求补码,结果为正
|
|
|
- Batt_current = (uint16)((uint16)(~(Batt_current)) + 1);
|
|
|
- Batt_current = Batt_current / 10;
|
|
|
- BattCurrentNegFlag = 1;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- //源码,结果为正
|
|
|
- Batt_current = Batt_current / 10;
|
|
|
- BattCurrentNegFlag = 1;
|
|
|
- }
|
|
|
- }
|
|
|
- battI = Batt_current * BattCurrentNegFlag + 0x2710;
|
|
|
- // sint16 BattI_Temp = 0;//做电压补偿需要的参数
|
|
|
- // BattI_Temp = Batt_current * BattCurrentNegFlag;
|
|
|
- for (i = 0; i < BATT_CELL_VOL_NUM; i++)
|
|
|
- {
|
|
|
- //battCellU[i] = ((dataPtr[(0x02 + i) * 2] << 8) | dataPtr[(0x02 + i) * 2 + 1]) + (INT16)(cmnm_R_voloffset[i] * BattI_Temp / 10000);//不使用电压补偿
|
|
|
- battCellU[i] = ((dataPtr[(0x02 + i) * 2] << 8) | dataPtr[(0x02 + i) * 2 + 1]);
|
|
|
- Battsumvoltage = Battsumvoltage + battCellU[i];
|
|
|
- }
|
|
|
- avrgCellVol = Battsumvoltage / BATT_CELL_VOL_NUM;
|
|
|
- return true;
|
|
|
-}
|
|
|
-bool bmsOtherInfoDecode(uint8 *dataPtr)//其他数据解析
|
|
|
-{
|
|
|
- uint8 TEMP_NUM = 0, temp = 0;
|
|
|
|
|
|
- sint8 OtherInfoAddrOffset = -3;//其他数据解析的起始位置改变,需要向前减3
|
|
|
- TEMP_NUM = AppDataInfo.BattTempCount + BmsOtherTemp;
|
|
|
- bmsHwVersion = dataPtr[(0x08 + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1];
|
|
|
- bmsSwVersion = dataPtr[(0x08 + OtherInfoAddrOffset + TEMP_NUM) * 2];
|
|
|
-
|
|
|
- temp = ((dataPtr[(0x09 + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1]) >> 1) & 0x03;
|
|
|
- battMOSSwitchState = ((temp & 0x01) << 1) | ((temp & 0x02) >> 1);
|
|
|
- if (battSeparateEnableState==1)
|
|
|
- {
|
|
|
- battMOSSwitchState = battMOSSwitchState | (0x01 << 2);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- battMOSSwitchState = battMOSSwitchState | (0x00 << 2);
|
|
|
- }
|
|
|
- battSOC = dataPtr[(0x0B + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1];
|
|
|
- battSOH = dataPtr[(0x0C + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1];
|
|
|
- Battdesigncap = (dataPtr[(0x0E + OtherInfoAddrOffset + TEMP_NUM) * 2]) << 24 | (dataPtr[(0x0E + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1]) << 16 | (dataPtr[(0x0F + OtherInfoAddrOffset + TEMP_NUM) * 2]) << 8 | (dataPtr[(0x0F + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1]);
|
|
|
- battPackVol = ((dataPtr[(0x18 + OtherInfoAddrOffset + TEMP_NUM) * 2]) << 8 | (dataPtr[(0x18 + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1])) / 10; // uint 100mV
|
|
|
- maxCellVol = (dataPtr[(0x19 + OtherInfoAddrOffset + TEMP_NUM) * 2] << 8) | dataPtr[(0x19 + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1];
|
|
|
- minCellVol = (dataPtr[(0x1A + OtherInfoAddrOffset + TEMP_NUM) * 2] << 8) | dataPtr[(0x1A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1];
|
|
|
- for (uint8 i = 0; i < AppDataInfo.BattTempCount; i++)
|
|
|
- {
|
|
|
- battCellTemp[i] = dataPtr[(0x06 + OtherInfoAddrOffset + i) * 2 + 1];
|
|
|
- }
|
|
|
- battWorkState = (dataPtr[(0x03 + OtherInfoAddrOffset) * 2 + 1]) & 0x03; //电池状态(原始数据),0表示静置,1表示放电,2表示充电
|
|
|
- //状态量上传
|
|
|
- battHeatState = getbit(dataPtr[(0x09 + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],5);
|
|
|
- battFanState = getbit(dataPtr[(0x09 + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],3);
|
|
|
- battRelayState = getbit(dataPtr[(0x09 + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],4);
|
|
|
- battConverState = getbit(dataPtr[(0x09 + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],6);
|
|
|
- battSeparateEnableState = getbit(dataPtr[(0x1B + OtherInfoAddrOffset + TEMP_NUM) * 2],7);
|
|
|
- //故障状态映关系(先完成告警状态简单上传)
|
|
|
- uint8 ErrorArrayTemp[32] ={0};
|
|
|
- uint8 ErrorArrayNumTemp[32]={81,87,83,89,97,99,132,131,134,84,90,82,88,135,136,98,100};
|
|
|
- ErrorArrayTemp[0] = getbit(dataPtr[(0x03 + OtherInfoAddrOffset) * 2],0);//电芯电压过高切断告警-0-81
|
|
|
- ErrorArrayTemp[1] = getbit(dataPtr[(0x03 + OtherInfoAddrOffset) * 2],1);//总压过高切断告警-1-87
|
|
|
- ErrorArrayTemp[2] = getbit(dataPtr[(0x04 + OtherInfoAddrOffset) * 2 + 1],0);//电芯电压过低切断告警2-83
|
|
|
- ErrorArrayTemp[3] = getbit(dataPtr[(0x04 + OtherInfoAddrOffset) * 2 + 1],1);//总压过低切断告警3-89
|
|
|
- ErrorArrayTemp[4] = getbit(dataPtr[(0x04 + OtherInfoAddrOffset) * 2],4);//单节温度过高切断4-97
|
|
|
- ErrorArrayTemp[5] = getbit(dataPtr[(0x04 + OtherInfoAddrOffset) * 2],5);//单节温度过低切断5-99
|
|
|
- ErrorArrayTemp[6] = getbit(dataPtr[(0x05 + OtherInfoAddrOffset) * 2 + 1],1);//放电电流切断6-132
|
|
|
- ErrorArrayTemp[7] = getbit(dataPtr[(0x05 + OtherInfoAddrOffset) * 2 + 1],2);//充电电流切断7-131
|
|
|
- ErrorArrayTemp[8] = getbit(dataPtr[(0x05 + OtherInfoAddrOffset) * 2 + 1],3);//BTU连接告警8-134
|
|
|
- ErrorArrayTemp[9] = getbit(dataPtr[(0x0A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],0);//单节电压下限告警9-84
|
|
|
- ErrorArrayTemp[10] = getbit(dataPtr[(0x0A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],1);//组电压下限告警10-90
|
|
|
- ErrorArrayTemp[11] = getbit(dataPtr[(0x0A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],2);//单节电压上限告警11-82
|
|
|
- ErrorArrayTemp[12] = getbit(dataPtr[(0x0A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],3);//组单节电压上限告警12-88
|
|
|
- ErrorArrayTemp[13] = getbit(dataPtr[(0x0A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],4);//放电电流告警13-135
|
|
|
- ErrorArrayTemp[14] = getbit(dataPtr[(0x0A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],5);//充电电流告警14-136
|
|
|
- ErrorArrayTemp[15] = getbit(dataPtr[(0x0A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],6);//单节温度上限告警15-98
|
|
|
- ErrorArrayTemp[16] = getbit(dataPtr[(0x0A + OtherInfoAddrOffset + TEMP_NUM) * 2 + 1],7);//单节温度下线告警16-100
|
|
|
- for(uint8 i=0,j=0;(i<32&&j<5);i++)
|
|
|
- {
|
|
|
- if(ErrorArrayTemp[i]==1)
|
|
|
- {
|
|
|
- PutErrorNum(ErrorArray, sizeof(ErrorArray)/2, ErrorArrayNumTemp[i]);
|
|
|
- j++;
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
-#endif
|