|
@@ -37,6 +37,24 @@ extern ARM_DRIVER_USART Driver_USART1;
|
|
|
static ARM_DRIVER_USART *USARTdrv = &Driver_USART1;
|
|
|
volatile bool isRecvTimeout = false;
|
|
|
volatile bool isRecvComplete = false;
|
|
|
+
|
|
|
+uint8_t Batt_Cell_Num = 14;//默认数值14、17
|
|
|
+uint8_t Batt_Cell_Num_2 ;//默认数值
|
|
|
+uint8_t Batt_Temp_Num = 5;//默认数值5、7
|
|
|
+int16_t Uart_Rece_BattI=0x0000;
|
|
|
+uint16_t data_index = 0x0000;
|
|
|
+uint8_t battbuffer[100];//电池数据都存在此数组中————电压14,温度5
|
|
|
+/**
|
|
|
+ * 存放规则如下:
|
|
|
+ * 位置: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
|
|
+ * 数据: 年 月 日 时 分 秒 信息体标志 年 月 日 时 分 秒 网络信号 故障等级 故障代码高 故障代码低
|
|
|
+ *
|
|
|
+ * 17 18 19 20 21 22 23 24 25 26 27 28 29 30 30+1 .... 30+X*2 31+X*2 31+1...31+X*2+N
|
|
|
+ * 电流H 电流L Link电压H Link电压L Pack电压H Pack电压L 开关状态 SOC SOH 均衡状态 单体个数X 单体v1...单体vX 温度个数N 温度1..温度N
|
|
|
+ * 32+X*2+N 33+X*2+N 34+x*2+N 35 +X*2+N 36+X*2 +N 37+X*2+N
|
|
|
+ * 电池状态 是否加热 最高单体H 最高单体L 最低单体H 最低单体L
|
|
|
+ * */
|
|
|
+
|
|
|
//状态机定义
|
|
|
typedef enum
|
|
|
{
|
|
@@ -46,9 +64,25 @@ typedef enum
|
|
|
}process_Main;
|
|
|
static process_Main gProcess_Main_Task = PROCESS_STATE_IDLE;
|
|
|
#define PROC_MAIN_STATE_SWITCH(a) (gProcess_Main_Task = a)
|
|
|
+
|
|
|
+typedef enum
|
|
|
+{
|
|
|
+ PROCESS_UART_STATE_IDLE = 0,
|
|
|
+ PROCESS_UART_STATE_CHECK,
|
|
|
+ PROCESS_UART_STATE_WORK,
|
|
|
+ PROCESS_UART_STATE_SLEEP
|
|
|
+}process_Uart;
|
|
|
+static process_Uart gProcess_Uart_Task = PROCESS_UART_STATE_IDLE;
|
|
|
+#define PROC_UART_STATE_SWITCH(a) (gProcess_Uart_Task = a)
|
|
|
+
|
|
|
+
|
|
|
//堆栈申请
|
|
|
static StaticTask_t gProcess_Main_Task_t;
|
|
|
-static UINT8 gProcess_Main_TaskStack[PROC_MAIN_TASK_STACK_SIZE];
|
|
|
+static UINT8 gProcess_Main_TaskStack[PROC_UART_TASK_STACK_SIZE];
|
|
|
+static StaticTask_t gProcess_Uart_Task_t;
|
|
|
+static UINT8 gProcess_Uart_TaskStack[PROC_UART_TASK_STACK_SIZE];
|
|
|
+
|
|
|
+
|
|
|
//睡眠进出函数
|
|
|
static void appBeforeHib(void *pdata, slpManLpState state)
|
|
|
{
|
|
@@ -210,6 +244,7 @@ static void Main_Task(void* arg)
|
|
|
}
|
|
|
case PROCESS_STATE_SLEEP:
|
|
|
{
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_SLEEP);
|
|
|
slpManSlpState_t State;
|
|
|
uint8_t cnt;
|
|
|
if(slpManCheckVoteState(MainSlpHandler, &State, &cnt)==RET_TRUE)
|
|
@@ -245,7 +280,209 @@ static void Main_Task(void* arg)
|
|
|
|
|
|
}
|
|
|
|
|
|
+//Uart校验程序
|
|
|
+unsigned int crc_chk(uint8_t* data, uint8_t length)
|
|
|
+{
|
|
|
+ int j;
|
|
|
+ uint16_t reg_crc=0xFFFF;
|
|
|
+ while(length--)
|
|
|
+ {
|
|
|
+ reg_crc ^= *data++;
|
|
|
+ for(j=0;j<8;j++)
|
|
|
+ {
|
|
|
+ if(reg_crc & 0x01)
|
|
|
+ {
|
|
|
+ reg_crc=(reg_crc>>1) ^ 0xA001;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ reg_crc=reg_crc >>1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return reg_crc;
|
|
|
+}
|
|
|
+//Uart回调程序
|
|
|
+void USART_callback(uint32_t event)
|
|
|
+{
|
|
|
+ if(event & ARM_USART_EVENT_RX_TIMEOUT)
|
|
|
+ {
|
|
|
+ isRecvTimeout = true;
|
|
|
+ }
|
|
|
+ if(event & ARM_USART_EVENT_RECEIVE_COMPLETE)
|
|
|
+ {
|
|
|
+ isRecvComplete = true;
|
|
|
+ }
|
|
|
+}
|
|
|
+//Uart发送接收函数
|
|
|
+uint8_t* Uart_Receive_func(Uart_Receive_Type Uart_Receive_Msg,uint8_t* Uart_Rece_buffer,uint8_t Data_Len)
|
|
|
+{
|
|
|
+ uint16_t CRC_Rece_buffer;
|
|
|
+ uint16_t CRC_chk_buffer;
|
|
|
+ uint8_t Uart_Send_buffer[8];
|
|
|
+ Uart_Send_buffer[0] = Uart_Receive_Msg.Bms_Address;
|
|
|
+ Uart_Send_buffer[1] = Uart_Receive_Msg.Bms_Read_Funcode;
|
|
|
+ Uart_Send_buffer[2] = Uart_Receive_Msg.Reg_Begin_H;
|
|
|
+ Uart_Send_buffer[3] = Uart_Receive_Msg.Reg_Begin_L;
|
|
|
+ Uart_Send_buffer[4] = Uart_Receive_Msg.Reg_Num_H;
|
|
|
+ Uart_Send_buffer[5] = Uart_Receive_Msg.Reg_Num_L;
|
|
|
+ CRC_chk_buffer = crc_chk(Uart_Send_buffer,6);
|
|
|
+ Uart_Send_buffer[6] = CRC_chk_buffer;
|
|
|
+ Uart_Send_buffer[7] = CRC_chk_buffer>>8;
|
|
|
+ uint8_t timeout = 0x00;
|
|
|
+ USARTdrv->Send(Uart_Send_buffer,8);
|
|
|
+ USARTdrv->Receive(Uart_Rece_buffer,Data_Len);
|
|
|
+ while((isRecvTimeout == false) && (isRecvComplete == false))
|
|
|
+ {
|
|
|
+ timeout++;
|
|
|
+ if (timeout>=500)
|
|
|
+ {
|
|
|
+ timeout =0;
|
|
|
+ isRecvTimeout = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ osDelay(10);
|
|
|
+ }
|
|
|
+ if (isRecvComplete == true)
|
|
|
+ {
|
|
|
+ isRecvComplete = false;
|
|
|
+ CRC_Rece_buffer =*(Uart_Rece_buffer+Data_Len-1)<<8|*(Uart_Rece_buffer+Data_Len-2);
|
|
|
+ CRC_chk_buffer = crc_chk(Uart_Rece_buffer,Data_Len-2);
|
|
|
+ #ifdef USING_PRINTF
|
|
|
+ printf("Uart_Send_buffer: ");
|
|
|
+ for(int i=0;i<8;i++)
|
|
|
+ {
|
|
|
+ printf("%x ",Uart_Send_buffer[i]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+ printf("Uart_Rece_buffer: ");
|
|
|
+ for(int i=0;i<Data_Len;i++)
|
|
|
+ {
|
|
|
+ printf("%x ",*(Uart_Rece_buffer+i));
|
|
|
+ }
|
|
|
+ printf("crcchk:%x,%x ",CRC_chk_buffer,CRC_Rece_buffer);
|
|
|
+ #endif
|
|
|
+ if (CRC_Rece_buffer == CRC_chk_buffer)//满足校验
|
|
|
+ {
|
|
|
+ return Uart_Rece_buffer+3;
|
|
|
+ }
|
|
|
+ else //接收数据的校验不过屏蔽
|
|
|
+ {
|
|
|
+ memset(Uart_Rece_buffer,0xff,Data_Len);
|
|
|
+ return Uart_Rece_buffer+3;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ memset(Uart_Rece_buffer,0x00,Data_Len);
|
|
|
+ isRecvTimeout = false;
|
|
|
+ osDelay(1000);
|
|
|
+ return Uart_Rece_buffer;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
+}
|
|
|
+//Uart线程
|
|
|
+static void Uart_Task(void* arg)
|
|
|
+{
|
|
|
+ USARTdrv->Initialize(USART_callback);
|
|
|
+ USARTdrv->PowerControl(ARM_POWER_FULL);
|
|
|
+ USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS |
|
|
|
+ ARM_USART_DATA_BITS_8 |
|
|
|
+ ARM_USART_PARITY_NONE |
|
|
|
+ ARM_USART_STOP_BITS_1 |
|
|
|
+ ARM_USART_FLOW_CONTROL_NONE, 9600);
|
|
|
+ int Rece_index = 0;
|
|
|
+ uint8_t Data_Len;
|
|
|
+ uint8_t *Uart_Reve_Point = NULL;
|
|
|
+ Uart_Receive_Type Uart_Receive_Msg;
|
|
|
+ memset(&battbuffer[0],0x00,100);
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
|
|
|
+ slpManApplyPlatVoteHandle("UARTSLP",&UartSlpHandler);
|
|
|
+ slpManPlatVoteDisableSleep(UartSlpHandler, SLP_SLP2_STATE);
|
|
|
+ Uart_Receive_Msg.Bms_Address = 0x01;
|
|
|
+ Uart_Receive_Msg.Bms_Read_Funcode = 0x03;
|
|
|
+ uint8_t *Uart_Rece_buffer = NULL;
|
|
|
+ Batt_Cell_Num_2 = Batt_Cell_Num<<1;
|
|
|
+ Uart_Rece_buffer = (uint8_t *)malloc(Uart_Rece_LEN);
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ switch (gProcess_Uart_Task)
|
|
|
+ {
|
|
|
+ case PROCESS_UART_STATE_IDLE:
|
|
|
+ {
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_OFF);
|
|
|
+ Rece_index = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PROCESS_UART_STATE_CHECK:
|
|
|
+ {
|
|
|
+ Uart_Receive_Msg.Reg_Begin_H = 0x00;
|
|
|
+ Uart_Receive_Msg.Reg_Begin_L= 0x02+Batt_Cell_Num;
|
|
|
+ Uart_Receive_Msg.Reg_Num_H = 0x00;
|
|
|
+ Uart_Receive_Msg.Reg_Num_L = 0x01;
|
|
|
+ Data_Len = Uart_Receive_Msg.Reg_Num_L*2+5;
|
|
|
+ memset(Uart_Rece_buffer,0x00,Data_Len);
|
|
|
+ Uart_Rece_buffer = Uart_Receive_func(Uart_Receive_Msg,Uart_Rece_buffer,Data_Len);
|
|
|
+ Uart_Rece_BattI = *(Uart_Reve_Point+0)<<8 |*(Uart_Reve_Point+1);
|
|
|
+ #ifdef USING_PRINTF
|
|
|
+ printf("Check_Current!\n");
|
|
|
+ #endif
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PROCESS_UART_STATE_WORK:
|
|
|
+ {
|
|
|
+ NetSocDisplay(LED_SOC_1,LED_TURN_ON);
|
|
|
+ switch (Rece_index)
|
|
|
+ {
|
|
|
+ case 0:
|
|
|
+ {
|
|
|
+ Uart_Receive_Msg.Reg_Begin_H = 0x00;
|
|
|
+ Uart_Receive_Msg.Reg_Begin_L= 0x02+Batt_Cell_Num;
|
|
|
+ Uart_Receive_Msg.Reg_Num_H = 0x00;
|
|
|
+ Uart_Receive_Msg.Reg_Num_L = 0x01;
|
|
|
+ Data_Len = Uart_Receive_Msg.Reg_Num_L*2+5;
|
|
|
+ memset(Uart_Rece_buffer,0xff,Data_Len);
|
|
|
+ Uart_Rece_buffer = Uart_Receive_func(Uart_Receive_Msg,Uart_Rece_buffer,Data_Len);
|
|
|
+ Uart_Rece_BattI = *(Uart_Rece_buffer+0)<<8 |*(Uart_Rece_buffer+1);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case 1:
|
|
|
+ {
|
|
|
+ Uart_Receive_Msg.Reg_Begin_H = 0x00;
|
|
|
+ Uart_Receive_Msg.Reg_Begin_L = 0x02;
|
|
|
+ Uart_Receive_Msg.Reg_Num_H = Batt_Cell_Num>>8;
|
|
|
+ Uart_Receive_Msg.Reg_Num_L = Batt_Cell_Num;
|
|
|
+ Data_Len = Uart_Receive_Msg.Reg_Num_L*2+5;
|
|
|
+ memset(Uart_Rece_buffer,0xff,Data_Len);
|
|
|
+ Uart_Rece_buffer = Uart_Receive_func(Uart_Receive_Msg,Uart_Rece_buffer,Data_Len);
|
|
|
+ battbuffer[30] = Batt_Cell_Num;
|
|
|
+ memcpy(&battbuffer[31],Uart_Rece_buffer,Batt_Cell_Num_2);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ {
|
|
|
+ PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Rece_index++;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ case PROCESS_UART_STATE_SLEEP:
|
|
|
+ {
|
|
|
+ free(Uart_Rece_buffer);
|
|
|
+ slpManPlatVoteEnableSleep(UartSlpHandler, SLP_SLP2_STATE);
|
|
|
+ while(true)
|
|
|
+ {
|
|
|
+ osDelay(5000/portTICK_PERIOD_MS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
//主任务线程初始化
|
|
|
void Main_Task_Init()
|
|
|
{
|
|
@@ -267,10 +504,27 @@ void Main_Task_Init()
|
|
|
|
|
|
osThreadNew(Main_Task, NULL, &task_attr);
|
|
|
|
|
|
+}
|
|
|
+//Uart读取线程初始化
|
|
|
+void Uart_Task_Init()
|
|
|
+{
|
|
|
+ osThreadAttr_t task_attr;
|
|
|
+ memset(&task_attr,0,sizeof(task_attr));
|
|
|
+ memset(gProcess_Uart_TaskStack, 0xA5, PROC_UART_TASK_STACK_SIZE);
|
|
|
+ task_attr.name = "Uart_Task";
|
|
|
+ task_attr.stack_mem = gProcess_Uart_TaskStack;
|
|
|
+ task_attr.stack_size = PROC_UART_TASK_STACK_SIZE;
|
|
|
+ task_attr.priority = osPriorityNormal;
|
|
|
+ task_attr.cb_mem = &gProcess_Uart_Task_t;
|
|
|
+ task_attr.cb_size = sizeof(StaticTask_t);
|
|
|
+
|
|
|
+ osThreadNew(Uart_Task, NULL, &task_attr);
|
|
|
+
|
|
|
}
|
|
|
void appInit(void *arg)
|
|
|
{
|
|
|
Main_Task_Init();
|
|
|
+ Uart_Task_Init();
|
|
|
}
|
|
|
//主函数入口
|
|
|
void main_entry(void) {
|