ソースを参照

电池下线控制完成部分,Tcp任务还没添加控制指令

CHENJIE-PC\QiXiang_CHENJIE 4 年 前
コミット
94fa4d2f81
4 ファイル変更171 行追加10 行削除
  1. 10 2
      inc/UartTask.h
  2. 2 2
      inc/app.h
  3. 158 3
      src/UartTask.c
  4. 1 3
      src/app.c

+ 10 - 2
inc/UartTask.h

@@ -13,10 +13,18 @@ typedef struct _UartRedMsg
     UINT8 data[120];
     UINT16 len;
 }UartReadMsgType;
+typedef struct Uart_Write_Data_Type
+{
+    volatile uint8_t WriteCmd; 
+    uint8_t Data[2];
+}Uart_Write_Data_Type;
 //全局变量输出区
 extern UartReadMsgType UartReadMsg;
 extern osMutexId_t UartMutex;
+extern Uart_Write_Data_Type UartWriteData;
 //
+#define UART_WRITE_FLAG 0x01
+#define UART_READ_FLAG 0x00
 
 #define PROC_UART_TASK_STACK_SIZE           (1024)
 #define BMS_ADDRESS_CODE 0x01
@@ -31,8 +39,8 @@ typedef struct Uart_Read_Msg_Type
     uint8_t Reg_Begin_L; 
     uint8_t Reg_Num_H; 
     uint8_t Reg_Num_L; 
-    uint8_t CRC_H;
     uint8_t CRC_L;
+    uint8_t CRC_H;
 }Uart_Read_Msg_Type;
 
 typedef struct Uart_Write_Msg_Type
@@ -45,8 +53,8 @@ typedef struct Uart_Write_Msg_Type
     uint8_t Reg_Num_L; 
     uint8_t Data_Count;
     uint8_t Data[2];
-    uint8_t CRC_H;
     uint8_t CRC_L;
+    uint8_t CRC_H;
 }Uart_Write_Msg_Type;
 
 typedef struct Uart_Write_Answer_Msg_Type

+ 2 - 2
inc/app.h

@@ -33,8 +33,8 @@ extern "C" {
 #define HWVERSION		    0x0102    //硬件主版本,现为V1.2板
 #define	BLSWVERSION		0x01020000    //BootLoader版本号V1.2.0.0
 #define	DRVSWVERSION		0x01030000     //驱动层版本号V1.3.0.0
-#define	APPSWVERSION		0x01020102       
-#define APP_CONFIG_FILE_LATEST_VERSION 2
+#define	APPSWVERSION		0x01020104       
+#define APP_CONFIG_FILE_LATEST_VERSION 4
 #define APP_CONFIG_FILE_NAME  "qxappconfig.nvm"
 //--------------------------------------------------------------------------------
 typedef struct AppNVMDataType

+ 158 - 3
src/UartTask.c

@@ -28,14 +28,18 @@
 #include "UartTask.h"
 #include "MainTask.h"
 #include "app.h"
+#include "numeric.h"
 //全局变量输入区
 extern UINT32 Timer_count;
 extern volatile bool Sleep_flag; 
+extern AppNVMDataType AppNVMData;
 //全局变量输出区
+UINT8 Uart_Write_Flag=0;
 UartReadMsgType UartReadMsg;
 osMutexId_t UartMutex = NULL;//Uart数据锁
+Uart_Write_Data_Type UartWriteData; //Uart控制命令
 //
-UINT8 Uart_Write_Flag=0;
+
 extern ARM_DRIVER_USART Driver_USART1;
 static ARM_DRIVER_USART *USARTdrv = &Driver_USART1;
 volatile bool isRecvTimeout = false;
@@ -51,7 +55,9 @@ static process_Uart             gProcess_Uart_Task = PROCESS_UART_STATE_IDLE;
 //函数声明区
 void USART_callback(uint32_t event);
 UINT8 Uart_Transmit_func(UINT8* Uart_Read_Msg,UINT8* Uart_Recv_Buffer);
+UINT8 Uart_WriteCmd_func(Uart_Write_Data_Type UartWriteData);
 UINT16 crc_chk(UINT8* data, UINT8 length);
+BOOL BattHeaterSwitch(UINT8* heaterSwitch);
 //Uart线程任务区
 static void UartTask(void* arg)
 {
@@ -71,6 +77,19 @@ static void UartTask(void* arg)
     {
         UartMutex = osMutexNew(NULL);
     }
+    //上电起始控制区域
+    Uart_Write_Flag=UART_WRITE_FLAG;
+    UartWriteData.WriteCmd = 0x01;
+    if(AppNVMData.isBattLocked)
+    {
+        UartWriteData.Data[0] = 0x00;
+        UartWriteData.Data[1] = 0x00;
+    }
+    else
+    {
+        UartWriteData.Data[0] = 0x00;
+        UartWriteData.Data[1] = 0x03;
+    }
     while (1)
     {
         switch (gProcess_Uart_Task)
@@ -87,7 +106,7 @@ static void UartTask(void* arg)
                     #ifdef USING_PRINTF
                         printf("[%d]Uart Timer 5s:%d\n",__LINE__,Timer_count);
                     #endif
-                    if(Uart_Write_Flag==0)
+                    if(Uart_Write_Flag==UART_READ_FLAG)
                         PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ);
                     else
                         PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_WRITE);
@@ -97,7 +116,7 @@ static void UartTask(void* arg)
             case PROCESS_UART_STATE_READ:
             {
                 osStatus_t result = osMutexAcquire(UartMutex, osWaitForever);
-                Reg_Num = 0x21+BATT_CELL_VOL_NUM+BATT_TEMP_NUM;//按照协议里面的0x21+X+N的结束地址
+                Reg_Num = 0x21+BATT_CELL_VOL_NUM+BATT_TEMP_NUM + 2;//按照协议里面的0x21+X+N的结束地址
                 Uart_Read_Msg.Bms_Address = BMS_ADDRESS_CODE;
                 Uart_Read_Msg.Bms_Funcode = UART_READ_CODE;
                 Uart_Read_Msg.Reg_Begin_H = 0x00;
@@ -114,6 +133,9 @@ static void UartTask(void* arg)
             }
             case PROCESS_UART_STATE_WRITE:
             {
+                Uart_WriteCmd_func(UartWriteData);
+                Uart_Write_Flag=UART_READ_FLAG;
+                PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
                 break;
             }
             case PROCESS_UART_STATE_SLEEP:
@@ -183,6 +205,86 @@ UINT16 crc_chk(UINT8* data, UINT8 length)
     }
     return reg_crc;
 }
+//Uart写命令函数
+UINT8 Uart_WriteCmd_func(Uart_Write_Data_Type UartWriteData)
+{
+    Uart_Write_Msg_Type Uart_Write_Msg;
+    UINT16 RegAddress = 0x0000;
+    UINT16 CRC_chk_buffer;
+    UINT8 timeout = 0x00;
+    UINT8 Uart_Recv_Buffer[8];
+    switch (UartWriteData.WriteCmd)
+    {
+        case 0x01:
+        {   
+            RegAddress = 0x1B + BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM;
+            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,UartWriteData.Data,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;
+            break;
+        }
+        default:
+        {
+            UartWriteData.WriteCmd = 0x00;
+            return 0;
+            break;
+        }
+    }
+    USARTdrv->Send((UINT8 *)&Uart_Write_Msg,sizeof(Uart_Write_Msg));
+    #ifdef USING_PRINTF
+        printf("Uart_Send_buffer:  ");
+        for(int i=0;i<sizeof(Uart_Write_Msg);i++)
+        {
+            printf("%x ",*((UINT8 *)&Uart_Write_Msg+i));
+        }
+        printf("\n");
+    #endif
+    USARTdrv->Receive(Uart_Recv_Buffer,8);
+    while((isRecvTimeout == false) && (isRecvComplete == false))
+    {
+        timeout++;
+        osDelay(100);
+        if (timeout>=50)
+        {
+            timeout =0;
+            isRecvTimeout = true;
+            break;
+        }
+    }
+    if (isRecvComplete == true)
+    {
+        #ifdef USING_PRINTF
+            printf("Uart_Rece_buffer: ");
+            for(int i=0;i<8;i++)
+            {
+            printf("%x ",Uart_Recv_Buffer[i]);
+            }
+            printf("n");
+        #endif
+        isRecvComplete = false;
+        if(Uart_Recv_Buffer[1]==0x10)
+        {
+            return UartWriteData.WriteCmd;
+        }
+        else
+        {
+            return 0x00;
+        }
+    }
+    else
+    {
+        isRecvTimeout = false;
+        return 0x00;
+    }
+}
 //Uart发送接收函数
 UINT8 Uart_Transmit_func(UINT8* Uart_Read_Msg,UINT8* Uart_Recv_Buffer)
 {
@@ -260,4 +362,57 @@ UINT8 Uart_Transmit_func(UINT8* Uart_Read_Msg,UINT8* Uart_Recv_Buffer)
         isRecvTimeout = false;
         return 0;
     }
+}
+//
+/**
+  \fn   BOOL BattHeaterSwitch(UINT8* heaterSwitch)
+  \param[in]  (UINT8*) heaterSwitch: the heater switch state
+  \brief    according to the current switch state and all the cell temp, it will turn on/off the switch
+  \return   (BOOL) isNeedtoSwitch: true: need to send cmd to turn on/off the switch
+                                                                   false: do not need to do anything
+*/
+BOOL BattHeaterSwitch(UINT8* heaterSwitch)
+{
+        BOOL isNeedtoSwitch = FALSE;
+        
+        UINT8 battCellTemp[BATT_TEMP_NUM];
+        UINT8 maxCellTemp,minCellTemp;
+        
+        UINT8 i =0;        
+        UINT8 currentSwitchState = 0;
+
+        //get the current switch state and the cell temp
+        currentSwitchState = UartReadMsg.data[(0x1C+BATT_CELL_VOL_NUM+(BATT_TEMP_NUM+2))*2+1]&0x01;
+        for(int i=0; i<BATT_TEMP_NUM; i++)
+    {
+            battCellTemp[i] = UartReadMsg.data[(0x06+BATT_CELL_VOL_NUM+i)*2+1];            
+    }
+
+        //cal the maxtemp and mintemp
+        maxCellTemp = battCellTemp[0];
+        minCellTemp = battCellTemp[0];
+    for(i=1;i<BATT_TEMP_NUM;i++)
+    {
+                maxCellTemp = max(maxCellTemp,battCellTemp[i]);
+                minCellTemp = min(minCellTemp,battCellTemp[i]);
+    }
+
+    
+        if(currentSwitchState==0)         //当前状态为关闭,判断是否应该开启
+        {
+                if(minCellTemp<=5+40 && maxCellTemp<25+40)//温度偏移为40 
+                {
+                        *heaterSwitch = 1;
+                        isNeedtoSwitch = true;
+                }
+        }
+        else                                                  //当前状态为开启,判断是否应该关闭
+        {
+                if(minCellTemp>10+40||maxCellTemp>30+40)
+                {
+                        *heaterSwitch = 0;
+                        isNeedtoSwitch= true;
+                }
+        }
+        return isNeedtoSwitch;
 }

+ 1 - 3
src/app.c

@@ -30,10 +30,8 @@
 #include "TcpTask.h"
 void appInit(void *arg)
 {
-    #ifdef USING_PRINTF	
-    	printf("%s[%d]\r\n",__FUNCTION__, __LINE__);
-    #endif
     MainTaskInit(arg);
+    osDelay(1000);
     UartTaskInit(arg);
     TcpTaskInit(arg);
     GpsTaskInit();