Pārlūkot izejas kodu

git-svn-id: https://svn.ti-link.com.cn/svn/G100/PowerManagement/PS100@5235 efa15413-de06-ce4f-a13f-2108acd733b2

liuguo1 5 gadi atpakaļ
vecāks
revīzija
00cb384b1f

+ 1785 - 0
Source/app.c

@@ -0,0 +1,1785 @@
+#include"common.h"
+#include "drv_io.h"
+#include "app.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "drv_can.h"
+#include "app_adas.h"
+#include "measure_vol.h"
+#include "app_can.h"
+#include "low_power.h"
+
+CB_VAL cb_val_last;
+uint8_t cb_operate_state = CB_BAT_NO;
+
+
+
+uint8_t Check_CB_oper_sta_start = 0;
+DELAY_COMMON Check_CB_oper_sta_delay;
+
+uint8_t cfg_operate = CFG_BAT_NO;
+uint8_t work_normal = 0;
+
+uint8_t is_intelligent = 1;
+uint8_t CB_OPERATE_PRECEDENCE_PARRALLEL = PRE_SERIES; 
+uint8_t CB_OPERATE_PRECEDENCE_Config = PRE_SERIES; 
+
+DELAY_COMMON Series_delay;
+DELAY_COMMON Next_Series_delay;
+uint8_t Next_Series_Not_Enable = 0;
+uint8_t define_bms_1_error = D_BMS_ERROR_NO,define_bms_2_error = D_BMS_ERROR_NO;
+
+uint8_t one_bat_charge_status = OBCS_CHARGER_OUT;
+
+uint8_t one_bat_initial = 1;
+
+uint8_t serise_low_enable = 0;
+uint8_t serise_low_qd_status = 0;
+
+UPDATE_BAT update_bat;
+
+const double nhb_default = 600;
+SHENG_YU_LI_CHENG sheng_yu_li_cheng;
+DELAY_COMMON save_param_delay;
+
+void Misc_Initial(void)
+{
+	GPIO_Initial();
+}
+
+void CB_Operate_Initial(void)
+{
+	_CB_Operate_Initial();
+	
+	memset(&cb_val_last,0x00,sizeof(cb_val_last));
+	//Check_CB_oper_sta_delay.set = 1;
+	//Check_CB_oper_sta_delay.count = 0;
+	Battery_CB_Switch(CB_BAT_NO);
+}
+
+void App_Initial(void)
+{
+	CB_OPERATE_PRECEDENCE_PARRALLEL = CB_OPERATE_PRECEDENCE_Config;
+	memset(&Series_delay,0x00,sizeof(Series_delay));
+	memset(&Next_Series_delay,0x00,sizeof(Next_Series_delay));
+	Initial_Neng_Hao_Bi();	
+}
+
+uint8_t Check_Battery_1_On(void)
+{
+	uint32_t vol = 0;
+	
+	if(IS_CHARGER_ON())
+		return 0;
+	
+	if((sub_bms_info_2.packet_common.bms_status & BMS_STA_S_OPEN) == 0)
+	{
+		vol = Measure_Vol();
+		if(vol != 0xFFFFFFFF && vol > sub_bms_info_2.packet_common.m_total_vol)
+			return 1;
+	}
+
+	return 0;
+}
+
+uint8_t Check_Battery_2_On(void)
+{
+	uint32_t vol = 0;
+
+	if(IS_CHARGER_ON())
+		return 0;
+	
+	if((sub_bms_info_1.packet_common.bms_status & BMS_STA_S_OPEN) == 0)
+	{
+		vol = Measure_Vol();
+		if(vol != 0xFFFFFFFF && vol > sub_bms_info_1.packet_common.m_total_vol)
+			return 1;
+	}
+
+	return 0;
+}
+void S11_FL_On(uint8_t on)
+{
+	S11_ENABLE(on);
+	FL_Enable(on);
+}
+uint8_t S11_May_Operate(void)
+{
+	if(cb_operate_state == CB_BAT2 || cb_operate_state == CB_BAT1_BAT2_PARRALLEL|| cb_operate_state == CB_BAT_NO)
+		return 1;
+	else
+		return 0;
+}
+void Battery_CB_Operate(CB_VAL *cb_val)
+{
+	if(cb_val == NULL)
+		return;
+	
+	S10_ENABLE(cb_val->s10_bit);
+	S11_ENABLE(cb_val->s11_bit);
+	S20_ENABLE(cb_val->s20_bit);
+	S21_ENABLE(cb_val->s21_bit);
+	SS__ENABLE(cb_val->ss__bit);
+}
+
+
+int8_t Battery_CB_Switch(uint8_t cb_operate)
+{
+	CB_VAL cb_val_temp;
+	uint16_t i = 0;
+#define COM_TIMEOUT  (15)
+
+	switch(cb_operate)
+	{
+		case CB_BAT1:
+			cb_val_temp.s10_bit = 0;
+			cb_val_temp.s11_bit = 0;
+			cb_val_temp.s20_bit = 0;
+			cb_val_temp.s21_bit = 0;
+			cb_val_temp.ss__bit = 0;
+			Battery_CB_Operate(&cb_val_temp);
+
+			for(i = 0;i < 500;i++)
+			{
+				if(Measure_Vol() <= SELECT_ONE_BATTERY_VOL)
+					break;
+				
+				if(Handle_Can_Data() == 1)
+				{
+					// output fail
+					
+					;
+				}
+				delay_1ms(10);
+			}
+			if(i >= 500)
+				goto SWITCH_ERROR;
+					
+			switch(cb_operate_state)
+			{
+				case CB_BAT_NO:
+					//
+					if(sub_bms_2_lt_state == SUB_BMS_CONT_HV485)
+					{
+						i = 0;
+						while(i++ < COM_TIMEOUT && RS485_busy_2)
+							delay_1ms(10);
+						
+						if(RS485_busy_2)
+							goto SWITCH_ERROR;
+						if(Operate_Sub_BMS_2_CD(0) == 0)
+							goto SWITCH_ERROR;
+					}
+					else if(sub_bms_2_lt_state == SUB_BMS_DISC_NO485)
+					{
+						if(Check_Battery_2_On())
+							goto SWITCH_ERROR;
+						
+					}
+					else
+					{
+						goto SWITCH_ERROR;
+					}
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_1)
+						delay_1ms(10);
+					
+					if(RS485_busy_1)
+						goto SWITCH_ERROR;
+
+					if(one_bat_initial == 0)
+					{
+						if(Operate_Sub_BMS_1_CD(2) == 0)
+							goto SWITCH_ERROR;
+				
+						delay_1ms(200);
+					}
+					
+					
+					if(Operate_Sub_BMS_1_CD(1) == 0)
+						goto SWITCH_ERROR;
+
+					
+					break;
+				case CB_BAT1:
+					break;
+				case CB_BAT2:
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_1)
+						delay_1ms(10);
+					
+					if(RS485_busy_1)
+						goto SWITCH_ERROR;
+
+					if(Operate_Sub_BMS_1_CD(1) == 0)
+						goto SWITCH_ERROR;
+
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_2)
+						delay_1ms(10);
+					
+					if(RS485_busy_2)
+						goto SWITCH_ERROR;
+					if(Operate_Sub_BMS_2_CD(0) == 0)
+						goto SWITCH_ERROR;
+					
+					break;
+				case CB_BAT1_BAT2_PARRALLEL:
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_2)
+						delay_1ms(10);
+					
+					if(RS485_busy_2)
+						goto SWITCH_ERROR;
+					if(Operate_Sub_BMS_2_CD(0) == 0)
+						goto SWITCH_ERROR;
+					break;
+				case CB_BAT1_BAT2_SERIES:
+					//
+					if(sub_bms_2_lt_state == SUB_BMS_CONT_HV485)
+					{
+						i = 0;
+						while(i++ < COM_TIMEOUT && RS485_busy_2)
+							delay_1ms(10);
+						
+						//if(RS485_busy_2)
+						//	goto SWITCH_ERROR;
+						if(Operate_Sub_BMS_2_CD(0) == 0)
+						{
+							//	goto SWITCH_ERROR;
+						}
+					}
+					else
+						Operate_Sub_BMS_2_CD(0);
+					
+					break;
+				default:
+					goto SWITCH_ERROR;
+			}
+
+			cb_val_temp.s10_bit = 0;
+			cb_val_temp.s11_bit = 0;
+			cb_val_temp.s20_bit = 1;
+			cb_val_temp.s21_bit = 1;
+			cb_val_temp.ss__bit = 0;
+			Battery_CB_Operate(&cb_val_temp);
+			break;
+		case CB_BAT2:
+			cb_val_temp.s10_bit = 0;
+			cb_val_temp.s11_bit = 0;
+			cb_val_temp.s20_bit = 0;
+			cb_val_temp.s21_bit = 0;
+			cb_val_temp.ss__bit = 0;
+			Battery_CB_Operate(&cb_val_temp);
+
+			for(i = 0;i < 500;i++)
+			{
+				if(Measure_Vol() <= SELECT_ONE_BATTERY_VOL)
+					break;
+				
+				if(Handle_Can_Data() == 1)
+				{
+					// output fail
+					
+					;
+				}
+				delay_1ms(10);
+			}
+			if(i >= 500)
+				goto SWITCH_ERROR;
+
+			
+			switch(cb_operate_state)
+			{
+				case CB_BAT_NO:
+					//
+					if(sub_bms_1_lt_state == SUB_BMS_CONT_HV485)
+					{
+						i = 0;
+						while(i++ < COM_TIMEOUT && RS485_busy_1)
+							delay_1ms(10);
+						
+						if(RS485_busy_1)
+							goto SWITCH_ERROR;
+						if(Operate_Sub_BMS_1_CD(0) == 0)
+							goto SWITCH_ERROR;
+					}
+					else if(sub_bms_1_lt_state == SUB_BMS_DISC_NO485)
+					{
+						if(Check_Battery_1_On())
+							goto SWITCH_ERROR;
+					}
+					else
+					{
+						goto SWITCH_ERROR;
+					}
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_2)
+						delay_1ms(10);
+					
+					if(RS485_busy_2)
+						goto SWITCH_ERROR;
+
+					if(one_bat_initial == 0)
+					{
+						if(Operate_Sub_BMS_2_CD(2) == 0)
+							goto SWITCH_ERROR;
+				
+						delay_1ms(200);
+					}
+					
+					if(Operate_Sub_BMS_2_CD(1) == 0)
+						goto SWITCH_ERROR;
+
+					
+					break;
+				case CB_BAT1:
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_2)
+						delay_1ms(10);
+					
+					if(RS485_busy_2)
+						goto SWITCH_ERROR;
+					if(Operate_Sub_BMS_2_CD(1) == 0)
+						goto SWITCH_ERROR;
+					
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_1)
+						delay_1ms(10);
+					
+					if(RS485_busy_1)
+						goto SWITCH_ERROR;
+
+					if(Operate_Sub_BMS_1_CD(0) == 0)
+						goto SWITCH_ERROR;
+					
+					break;
+				case CB_BAT2:
+					break;
+				case CB_BAT1_BAT2_PARRALLEL:
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_1)
+						delay_1ms(10);
+					
+					if(RS485_busy_1)
+						goto SWITCH_ERROR;
+
+					if(Operate_Sub_BMS_1_CD(0) == 0)
+						goto SWITCH_ERROR;
+					break;
+				case CB_BAT1_BAT2_SERIES:
+					//
+					if(sub_bms_1_lt_state == SUB_BMS_CONT_HV485)
+					{
+						i = 0;
+						while(i++ < COM_TIMEOUT && RS485_busy_1)
+							delay_1ms(10);
+						
+						//if(RS485_busy_1)
+						//	goto SWITCH_ERROR;
+
+						if(Operate_Sub_BMS_1_CD(0) == 0)
+						{
+							//goto SWITCH_ERROR;
+						}
+					}
+					else
+						Operate_Sub_BMS_1_CD(0);
+					
+					break;
+				default:
+					goto SWITCH_ERROR;
+			}
+			
+			cb_val_temp.s10_bit = 1;
+			cb_val_temp.s11_bit = 1;
+			cb_val_temp.s20_bit = 0;
+			cb_val_temp.s21_bit = 0;
+			cb_val_temp.ss__bit = 0;
+			Battery_CB_Operate(&cb_val_temp);
+			break;
+		case CB_BAT1_BAT2_PARRALLEL:			
+			cb_val_temp.s10_bit = 0;
+			cb_val_temp.s11_bit = 0;
+			cb_val_temp.s20_bit = 0;
+			cb_val_temp.s21_bit = 0;
+			cb_val_temp.ss__bit = 0;
+			Battery_CB_Operate(&cb_val_temp);
+
+			for(i = 0;i < 500;i++)
+			{
+				if(Measure_Vol() <= SELECT_ONE_BATTERY_VOL)
+					break;
+				
+				if(Handle_Can_Data() == 1)
+				{
+					// output fail
+					
+					;
+				}
+				delay_1ms(10);
+			}
+			if(i >= 500)
+				goto SWITCH_ERROR;
+			
+			switch(cb_operate_state)
+			{
+				case CB_BAT_NO:
+					goto SWITCH_ERROR;
+				case CB_BAT1:
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_2)
+						delay_1ms(10);
+					
+					if(RS485_busy_2)
+						goto SWITCH_ERROR;
+					if(Operate_Sub_BMS_2_CD(1) == 0)
+						goto SWITCH_ERROR;
+									
+					break;
+				case CB_BAT2:
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_1)
+						delay_1ms(10);
+					
+					if(RS485_busy_1)
+						goto SWITCH_ERROR;
+
+					if(Operate_Sub_BMS_1_CD(1) == 0)
+						goto SWITCH_ERROR;
+					break;
+				case CB_BAT1_BAT2_PARRALLEL:
+					break;
+				case CB_BAT1_BAT2_SERIES:
+					delay_1ms(10);
+					break;
+				default:
+					goto SWITCH_ERROR;
+			}
+			cb_val_temp.s10_bit = 1;
+			cb_val_temp.s11_bit = 1;
+			cb_val_temp.s20_bit = 1;
+			cb_val_temp.s21_bit = 1;
+			cb_val_temp.ss__bit = 0;
+			Battery_CB_Operate(&cb_val_temp);
+			break;
+		case CB_BAT1_BAT2_SERIES:
+
+			Power_On_Normal(0,2);
+			
+			cb_val_temp.s10_bit = 0;
+			cb_val_temp.s11_bit = 0;
+			cb_val_temp.s20_bit = 0;
+			cb_val_temp.s21_bit = 0;
+			cb_val_temp.ss__bit = 0;
+			Battery_CB_Operate(&cb_val_temp);		
+
+			//delay_1ms(2000);
+
+			//serise_low_qd_status = QD_Dect();
+			//Power_On_Normal(0,2);
+			
+			switch(cb_operate_state)
+			{
+				case CB_BAT_NO:
+					goto SWITCH_ERROR;
+				case CB_BAT1:
+					delay_1ms(10);
+					cb_val_temp.s10_bit = 1;
+					cb_val_temp.s11_bit = 0;
+					cb_val_temp.s20_bit = 1;
+					cb_val_temp.s21_bit = 0;
+					cb_val_temp.ss__bit = 1;
+					Battery_CB_Operate(&cb_val_temp);
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_2)
+						delay_1ms(10);
+					
+					if(RS485_busy_2)
+						goto SWITCH_ERROR;
+
+					if(Operate_Sub_BMS_2_CD(2) == 0)
+						goto SWITCH_ERROR;
+					
+					/*for(uint16_t i = 0;i < 20;i++)
+					{
+						
+						if(Handle_Can_Data() == 1)
+						{
+							// output fail
+							
+							;
+						}
+						delay_1ms(10);
+					}*/
+					delay_1ms(200);
+					
+					if(Operate_Sub_BMS_2_CD(1) == 0)
+						goto SWITCH_ERROR;
+									
+					break;
+				case CB_BAT2:
+					delay_1ms(10);
+					cb_val_temp.s10_bit = 1;
+					cb_val_temp.s11_bit = 0;
+					cb_val_temp.s20_bit = 1;
+					cb_val_temp.s21_bit = 0;
+					cb_val_temp.ss__bit = 1;
+					Battery_CB_Operate(&cb_val_temp);
+					//
+					i = 0;
+					while(i++ < COM_TIMEOUT && RS485_busy_1)
+						delay_1ms(10);
+					
+					if(RS485_busy_1)
+						goto SWITCH_ERROR;
+					
+					if(Operate_Sub_BMS_1_CD(2) == 0)
+						goto SWITCH_ERROR;
+					
+					/*for(uint16_t i = 0;i < 20;i++)
+					{
+						
+						if(Handle_Can_Data() == 1)
+						{
+							// output fail
+							
+							;
+						}
+						delay_1ms(10);
+					}*/
+
+					delay_1ms(200);
+					
+					if(Operate_Sub_BMS_1_CD(1) == 0)
+						goto SWITCH_ERROR;
+					break;
+				case CB_BAT1_BAT2_PARRALLEL:
+
+					if(sub_bms_info_1.packet_common.m_total_vol < sub_bms_info_2.packet_common.m_total_vol)
+					{
+						//
+						i = 0;
+						while(i++ < COM_TIMEOUT && RS485_busy_1)
+							delay_1ms(10);
+						
+						if(RS485_busy_1)
+							goto SWITCH_ERROR;
+
+						if(Operate_Sub_BMS_1_CD(0) == 0)
+							goto SWITCH_ERROR;
+
+						delay_1ms(50);
+
+						delay_1ms(10);
+						cb_val_temp.s10_bit = 1;
+						cb_val_temp.s11_bit = 0;
+						cb_val_temp.s20_bit = 1;
+						cb_val_temp.s21_bit = 0;
+						cb_val_temp.ss__bit = 1;
+						Battery_CB_Operate(&cb_val_temp);
+							
+						if(Operate_Sub_BMS_1_CD(2) == 0)
+							goto SWITCH_ERROR;
+						
+						/*for(uint16_t i = 0;i < 20;i++)
+						{
+							
+							if(Handle_Can_Data() == 1)
+							{
+								// output fail
+								
+								;
+							}
+							delay_1ms(10);
+						}*/
+
+						delay_1ms(200);
+						
+						if(Operate_Sub_BMS_1_CD(1) == 0)
+							goto SWITCH_ERROR;
+					}
+					else
+					{
+						//
+						i = 0;
+						while(i++ < COM_TIMEOUT && RS485_busy_2)
+							delay_1ms(10);
+						
+						if(RS485_busy_2)
+							goto SWITCH_ERROR;
+
+						if(Operate_Sub_BMS_2_CD(0) == 0)
+							goto SWITCH_ERROR;
+
+						delay_1ms(50);
+
+						delay_1ms(10);
+						cb_val_temp.s10_bit = 1;
+						cb_val_temp.s11_bit = 0;
+						cb_val_temp.s20_bit = 1;
+						cb_val_temp.s21_bit = 0;
+						cb_val_temp.ss__bit = 1;
+						Battery_CB_Operate(&cb_val_temp);
+						
+						if(Operate_Sub_BMS_2_CD(2) == 0)
+							goto SWITCH_ERROR;
+						
+						/*for(uint16_t i = 0;i < 20;i++)
+						{
+							
+							if(Handle_Can_Data() == 1)
+							{
+								// output fail
+								
+								;
+							}
+							delay_1ms(10);
+						}*/
+
+						delay_1ms(200);
+						
+						if(Operate_Sub_BMS_2_CD(1) == 0)
+							goto SWITCH_ERROR;
+					}
+					break;
+				case CB_BAT1_BAT2_SERIES:
+					break;
+				default:
+					goto SWITCH_ERROR;
+			}
+			delay_1ms(10);
+			cb_val_temp.s10_bit = 1;
+			cb_val_temp.s11_bit = 0;
+			cb_val_temp.s20_bit = 1;
+			cb_val_temp.s21_bit = 0;
+			cb_val_temp.ss__bit = 1;
+			Battery_CB_Operate(&cb_val_temp);
+			break;
+		case CB_BAT_NO:
+		default:
+			ACC2_Enable(0);
+			cb_val_temp.s10_bit = 0;
+			cb_val_temp.s11_bit = 0;
+			cb_val_temp.s20_bit = 0;
+			cb_val_temp.s21_bit = 0;
+			cb_val_temp.ss__bit = 0;
+			Battery_CB_Operate(&cb_val_temp);
+			cb_operate = CB_BAT_NO;
+			if(Is_Soak())
+			{
+				sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+				sub_bms_info_1.sub_bms_cmd.param = 0x00;
+				sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+				sub_bms_info_2.sub_bms_cmd.param = 0x00;
+			}
+			break;
+	}
+
+	
+	cb_val_last = cb_val_temp;
+
+	cb_operate_state = cb_operate;
+	
+	return cb_operate;
+
+SWITCH_ERROR:
+	cb_val_temp.s10_bit = 0;
+	cb_val_temp.s11_bit = 0;
+	cb_val_temp.s20_bit = 0;
+	cb_val_temp.s21_bit = 0;
+	cb_val_temp.ss__bit = 0;
+	Battery_CB_Operate(&cb_val_temp);
+	cb_val_last = cb_val_temp;
+	cb_operate_state = CB_BAT_NO;
+	return cb_operate_state;
+	
+#undef COM_TIMEOUT
+
+}
+void test_io(void)
+{
+	volatile uint8_t a,b;
+	
+	a = BAT1_IS_OPEN();
+	b = BAT2_IS_OPEN();
+
+	a++;
+	b++;
+}
+
+uint8_t Select_One_BAT(void)
+{
+	uint8_t temp_op = CB_BAT_NO;
+	
+	if(Is_Sub_BMS_1_Normal())
+	{
+		if(Is_Sub_BMS_2_Normal())
+		{
+			if(sub_bms_info_1.packet_common.m_total_vol >= sub_bms_info_2.packet_common.m_total_vol)
+			{
+				if(IS_CHARGE_IN())
+				{
+					temp_op = CB_BAT2;
+				}
+				else
+				{
+					temp_op = CB_BAT1;
+				}
+			}
+			else
+			{
+				if(IS_CHARGE_IN())
+				{
+					temp_op = CB_BAT1;
+				}
+				else
+				{
+					temp_op = CB_BAT2;
+				}
+			}
+		}
+		else
+		{
+			temp_op = CB_BAT1;
+		}
+	}
+	else if(Is_Sub_BMS_2_Normal())
+	{
+		temp_op = CB_BAT2;
+	}
+
+	return temp_op;
+	
+}
+
+
+uint8_t Check_CB_BAT_1(void)
+{
+	uint8_t temp_op = CB_MAX;
+	
+	if(Is_Sub_BMS_1_Normal())
+	{
+		if((sub_bms_info_1.packet_common.bms_status & (BMS_STA_D_OPEN | BMS_STA_C_OPEN)) != (BMS_STA_D_OPEN | BMS_STA_C_OPEN))
+		{
+			//sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+			//sub_bms_info_1.sub_bms_cmd.param = 0x03;
+			if((sub_bms_info_1.packet_common.work_status &(ST_OVRDISCHRG_VOL|ST_PDOWN)) != 0)
+				;
+			else
+				temp_op = CB_BAT_NO;
+		}
+
+		//
+		if((sub_bms_info_2.packet_common.bms_status & (BMS_STA_D_OPEN | BMS_STA_S_OPEN)) != 0)
+		{
+			sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+			sub_bms_info_2.sub_bms_cmd.param = 0x00;
+		}
+	}
+	else 
+	{
+		/*if(Is_Sub_BMS_2_Normal())
+			temp_op = CB_BAT2;
+		else*/
+			temp_op = CB_BAT_NO;
+	}
+
+	return temp_op;
+	
+}
+
+
+uint8_t Check_CB_BAT_2(void)
+{
+	uint8_t temp_op = CB_MAX;
+	
+	if(Is_Sub_BMS_2_Normal())
+	{
+		if((sub_bms_info_2.packet_common.bms_status & (BMS_STA_D_OPEN | BMS_STA_C_OPEN)) != (BMS_STA_D_OPEN | BMS_STA_C_OPEN))
+		{
+			//sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+			//sub_bms_info_2.sub_bms_cmd.param = 0x03;
+			if((sub_bms_info_2.packet_common.work_status &(ST_OVRDISCHRG_VOL|ST_PDOWN)) != 0)
+				;
+			else
+				temp_op = CB_BAT_NO;
+		}
+
+		//
+		if((sub_bms_info_1.packet_common.bms_status & (BMS_STA_D_OPEN | BMS_STA_S_OPEN)) != 0)
+		{
+			sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+			sub_bms_info_1.sub_bms_cmd.param = 0x00;
+		}
+	}
+	else 
+	{
+		/*if(Is_Sub_BMS_1_Normal())
+			temp_op = CB_BAT1;
+		else*/
+			temp_op = CB_BAT_NO;
+	}
+
+	return temp_op;
+	
+}
+
+int32_t Battery_1_Bu_Chang_Vol(void)
+{
+	return ((int32_t)sub_bms_info_1.packet_common.m_total_vol - (int32_t)(BATTERY_RESISTANCE_OHM * sub_bms_info_1.packet_common.m_current));
+}
+
+int32_t Battery_2_Bu_Chang_Vol(void)
+{
+	return ((int32_t)sub_bms_info_2.packet_common.m_total_vol - (int32_t)(BATTERY_RESISTANCE_OHM * sub_bms_info_2.packet_common.m_current));
+}
+
+uint8_t Check_CB_BAT1_BAT2_PARRALLEL(void)
+{
+	int32_t delta_vol;
+	int32_t m_1_total_vol,m_2_total_vol;
+	uint8_t temp_op = CB_MAX;
+
+	if(is_intelligent && CB_OPERATE_PRECEDENCE_PARRALLEL != PRE_PARRALLEL)
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}
+	//
+	if(Is_Sub_BMS_1_Normal()&&Is_Sub_BMS_2_Normal())
+	{
+		if((sub_bms_info_1.packet_common.bms_status & (BMS_STA_D_OPEN | BMS_STA_C_OPEN)) != (BMS_STA_D_OPEN | BMS_STA_C_OPEN))
+		{
+			sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+			sub_bms_info_1.sub_bms_cmd.param = 0x03;
+		}
+		if((sub_bms_info_2.packet_common.bms_status & (BMS_STA_D_OPEN | BMS_STA_C_OPEN)) != (BMS_STA_D_OPEN | BMS_STA_C_OPEN))
+		{
+			sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+			sub_bms_info_2.sub_bms_cmd.param = 0x03;
+		}
+	}
+	else
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}
+
+	//
+	if(sub_bms_info_1.packet_common.m_current > 20000 || sub_bms_info_2.packet_common.m_current > 20000)
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}
+
+	//
+	m_1_total_vol = Battery_1_Bu_Chang_Vol();
+	m_2_total_vol = Battery_2_Bu_Chang_Vol();
+
+	if(m_1_total_vol >= m_2_total_vol)
+	{
+		delta_vol = m_1_total_vol - m_2_total_vol;
+	}
+	else
+	{
+		delta_vol = m_2_total_vol - m_1_total_vol;
+	}
+
+	if(delta_vol > PARRALLEL_DELTA_VOL)
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}
+
+	return temp_op;
+		
+}
+
+void Series_Delay_Timeout(void)
+{
+	if(Series_delay.set)
+	{
+		Series_delay.count++;
+	}
+
+
+	if(Next_Series_delay.set)
+	{
+		Next_Series_delay.count++;
+		if(Next_Series_delay.count <= NEXT_SERIES_TIME_OUT)
+			Next_Series_Not_Enable = 1;
+		else
+		{
+			memset(&Next_Series_delay,0x00,sizeof(Next_Series_delay));
+			Next_Series_Not_Enable = 0;
+		}
+	}
+	
+	
+	
+}
+
+#ifdef HAN_GUO_VERSION
+uint8_t Select_One_BAT_Han_Guo(void)
+{
+	uint8_t temp_op = CB_BAT_NO;
+	
+	if(Is_Sub_BMS_1_Normal())
+	{
+		if(Is_Sub_BMS_2_Normal())
+		{
+			if(sub_bms_info_1.packet_common.m_total_vol >= sub_bms_info_2.packet_common.m_total_vol)
+			{
+				if(IS_CHARGE_IN())
+				{
+					temp_op = CB_BAT2;
+				}
+				else
+				{
+					temp_op = CB_BAT1;
+				}
+			}
+			else
+			{
+				if(IS_CHARGE_IN())
+				{
+					temp_op = CB_BAT1;
+				}
+				else
+				{
+					temp_op = CB_BAT2;
+				}
+			}
+		}
+		else
+		{
+			temp_op = CB_BAT1;
+		}
+	}
+	else if(Is_Sub_BMS_2_Normal())
+	{
+		temp_op = CB_BAT2;
+	}
+	else
+	{
+		if(sub_bms_info_1.packet_common.m_total_vol < sub_bms_info_2.packet_common.m_total_vol)
+			temp_op = CB_BAT2;
+		else
+			temp_op = CB_BAT1;
+	}
+
+	
+	return temp_op;
+	
+}
+#endif
+
+uint8_t Check_CB_BAT1_BAT2_SERIES(void)
+{
+	uint8_t temp_op = CB_MAX;
+	int32_t m_1_total_vol,m_2_total_vol;
+	
+	if(is_intelligent && CB_OPERATE_PRECEDENCE_PARRALLEL != PRE_SERIES)
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}
+
+	if(serise_low_enable)
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}
+	
+	if(IS_CHARGE_IN())
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}	
+	
+	if(Is_Sub_BMS_1_Normal()&&Is_Sub_BMS_2_Normal())
+	{
+		if((sub_bms_info_1.packet_common.bms_status & (BMS_STA_D_OPEN | BMS_STA_C_OPEN)) != (BMS_STA_D_OPEN | BMS_STA_C_OPEN))
+		{
+			//sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+			//sub_bms_info_1.sub_bms_cmd.param = 0x03;
+			define_bms_1_error = D_BMS_ERROR_SERISE_CD_OFF;
+			temp_op = Select_One_BAT();
+			define_bms_1_error = D_BMS_ERROR_NO;
+			return temp_op;
+		}
+		if((sub_bms_info_2.packet_common.bms_status & (BMS_STA_D_OPEN | BMS_STA_C_OPEN)) != (BMS_STA_D_OPEN | BMS_STA_C_OPEN))
+		{
+			//sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+			//sub_bms_info_2.sub_bms_cmd.param = 0x03;
+			define_bms_2_error = D_BMS_ERROR_SERISE_CD_OFF;
+			temp_op = Select_One_BAT();
+			define_bms_2_error = D_BMS_ERROR_NO;
+			return temp_op;
+		}
+	}
+	else
+	{
+	
+#ifdef HAN_GUO_VERSION
+		temp_op = Select_One_BAT_Han_Guo();
+#else
+		temp_op = Select_One_BAT();
+#endif
+
+		return temp_op;
+	}
+
+	/*if(Measure_Vol() <= CHECK_SERIES_VOL)
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}*/
+
+	m_1_total_vol = Battery_1_Bu_Chang_Vol();
+	m_2_total_vol = Battery_2_Bu_Chang_Vol();
+	if(m_1_total_vol <= CHECK_SERIES_PROTECT_VOL\
+		||m_2_total_vol <= CHECK_SERIES_PROTECT_VOL )
+	{
+		
+		if(Series_delay.set == 0)
+		{
+			Series_delay.set = 1;
+			Series_delay.count = 0;
+		}
+		
+	}
+	else
+	{
+		memset(&Series_delay,0x00,sizeof(Series_delay));
+	}
+
+	if(Series_delay.set&&Series_delay.count >= SERIES_UNDER_VOL_TIME_OUT)
+	{
+		memset(&Series_delay,0x00,sizeof(Series_delay));
+		temp_op = Select_One_BAT();
+		serise_low_enable = 1;
+		return temp_op;
+	}
+	
+/*	if(sub_bms_info_1.packet_common.m_percent < SERIES_UNDER_XX_PERCENT\
+		|| sub_bms_info_2.packet_common.m_percent < SERIES_UNDER_XX_PERCENT)
+	{
+		temp_op = Select_One_BAT();
+		return temp_op;
+	}
+*/	
+	return temp_op;
+}
+
+uint8_t power_switch_from = 0;
+void Power_On_Normal(uint8_t enable,uint8_t from)
+{
+	
+	if(enable)
+	{
+		//FL_Enable(1);
+		
+		//ACC2_Enable(1);
+		
+		Can_Power_Enable(1);
+
+		Enable_12V(1);
+		
+		one_bat_initial = 0;
+
+		Reset_Enter_Sleep_Delay();
+
+		/*if(serise_low_qd_status == 1)
+		{
+			QD_Enable(1);
+			serise_low_qd_status = 0;
+		}*/
+	}
+	else
+	{
+#if 0
+		NVIC_SystemReset();
+
+#else
+
+		FL_Enable(0);
+		
+		ACC2_Enable(0);
+		
+		Can_Power_Enable(0);
+
+		Can_Stop_Send();
+		
+		//QD_Enable(0);
+		QD_Enable_From(0,1);
+
+		ADAS_Enable(0);
+
+		Enable_12V(0);
+
+		Set_Enter_Sleep_Delay();
+
+		
+#endif
+	}
+	work_normal = enable;
+	power_switch_from = from;
+	
+}
+
+
+void Check_CB_Operate_State(void)
+{
+	uint8_t temp_op = CB_MAX;
+
+	//if(Check_CB_oper_sta_start == 0)
+	//	return;
+
+	if(!Sub_BMS_1_COM_Finish() || !Sub_BMS_2_COM_Finish())
+		return;
+	
+	switch(cb_operate_state)
+	{
+		case CB_BAT_NO:
+			temp_op = Select_One_BAT();
+			break;
+		case CB_BAT1:
+			temp_op = Check_CB_BAT_1();
+			break;
+		case CB_BAT2:	
+			temp_op = Check_CB_BAT_2();
+			break;
+		case CB_BAT1_BAT2_PARRALLEL:
+			temp_op = Check_CB_BAT1_BAT2_PARRALLEL();
+			break;
+		case CB_BAT1_BAT2_SERIES:
+			temp_op = Check_CB_BAT1_BAT2_SERIES();
+			/*if(temp_op != CB_MAX)
+			{
+				Next_Series_delay.set = 1;
+				Next_Series_delay.count = 0;
+				Next_Series_Not_Enable = 1;
+			}*/
+			break;
+		default:
+			return;	
+	}
+
+	if(temp_op >= CB_MAX)
+	{
+		//test-start
+		if(work_normal == 0)
+		{
+			Power_On_Normal(1,3);
+		}
+		//test-end
+		return;
+	}
+	else if(temp_op == CB_BAT_NO)
+	{
+		if(work_normal == 1)
+		{
+			Power_On_Normal(0,1);
+		}
+	}
+	else
+	{
+		/*if(work_normal == 1)
+		{
+			Power_On_Normal(0);
+		}*/
+	}
+	
+	Battery_CB_Switch(temp_op);
+	
+}
+
+uint8_t Is_BAT1_Lock(void)
+{
+
+	return 0;
+		
+}
+
+uint8_t Is_BAT2_Lock(void)
+{
+	
+
+	return 0;
+		
+}
+
+void Charger_Out(void)
+{
+	Set_Charger_In(0);
+	one_bat_charge_status = OBCS_CHARGER_OUT;
+
+	if(sub_bms_info_1.packet_common.m_percent >= 100 && sub_bms_info_2.packet_common.m_percent >= 100)
+		battery_charged_full = 1;
+}
+void Check_Charge_In(void)
+{
+
+	if(sub_bms_info_1.packet_common.m_percent < 97 || sub_bms_info_2.packet_common.m_percent < 97)
+		battery_charged_full = 0;
+	//if(gpio_input_bit_get(GPIOC,GPIO_PIN_4) == 0)
+	{
+	//	Set_Charger_In(1);
+	}
+
+	if(IS_CHARGE_IN())
+	{
+		
+		if(is_intelligent)
+		{
+			CB_OPERATE_PRECEDENCE_PARRALLEL = PRE_PARRALLEL; 
+			if(cb_operate_state == CB_BAT1_BAT2_SERIES)
+			{
+				if(Battery_Change_Mode(CFG_BAT1_BAT2_PARRALLEL) == CB_BAT1_BAT2_PARRALLEL)
+					CHARG_PROTECT_OPEN(1);
+				
+			}
+			else
+			{
+				CHARG_PROTECT_OPEN(1);
+				if(cb_operate_state == CB_BAT1 || cb_operate_state == CB_BAT2)
+				{
+					if(one_bat_charge_status == OBCS_CHARGER_OUT)
+						one_bat_charge_status = OBCS_CHARGER_IN;
+				}
+			}
+		}
+		else
+		{
+			if(cb_operate_state == CB_BAT1_BAT2_SERIES)
+			{
+				;		
+			}
+			else
+				CHARG_PROTECT_OPEN(1);
+		}
+		
+
+		if(IS_CHARGER_ON())
+		{
+			if(sub_bms_info_1.packet_common.charge_flag == 0 && sub_bms_info_2.packet_common.charge_flag == 0)
+			{
+				if(charge_delay.set == 0)
+				{
+					charge_delay.set = 1;
+					charge_delay.count = 0;
+				}
+				else
+				{
+					if(charge_delay.count >= CHARGE_DELAY_TIME_OUT_COUNT)
+					{
+						memset(&charge_delay,0x00,sizeof(charge_delay));						
+						Charger_Out();
+					}
+				}
+			}
+			else
+			{
+				memset(&charge_delay,0x00,sizeof(charge_delay));
+			}
+
+			if(cb_operate_state == CB_BAT1_BAT2_PARRALLEL)
+			{
+				if(sub_bms_info_1.packet_common.charge_flag)
+				{
+					if((sub_bms_info_2.packet_common.work_status&ST_DISCHRG_CUR)!= 0)
+					{
+						if(sub_bms_info_1.packet_common.m_current + sub_bms_info_2.packet_common.m_current\
+							< 5000)
+							Charger_Out();	
+					}
+				}	
+				else if(sub_bms_info_2.packet_common.charge_flag)
+				{
+					if((sub_bms_info_1.packet_common.work_status&ST_DISCHRG_CUR)!= 0)
+					{
+						if(sub_bms_info_1.packet_common.m_current + sub_bms_info_2.packet_common.m_current\
+							< 5000)
+							Charger_Out();	
+					}
+				}
+			}
+			
+	
+		}
+	}	
+	else
+	{
+		CHARG_PROTECT_OPEN(0);
+		if(is_intelligent)
+		{
+			CB_OPERATE_PRECEDENCE_PARRALLEL = CB_OPERATE_PRECEDENCE_Config; 
+		}
+	}
+}
+
+uint8_t Change_Mode_Sub_BMS_1_Normal(void)
+{
+	return Is_Sub_BMS_1_Normal();
+}
+uint8_t Change_Mode_Sub_BMS_2_Normal(void)
+{
+	return Is_Sub_BMS_2_Normal();
+}
+
+uint8_t Change_Mode_Sub_BMS_PARRALLEL(void)
+{
+	int32_t delta_vol;
+	int32_t m_1_total_vol,m_2_total_vol;
+
+	//
+	if(cb_operate_state == CB_BAT_NO)
+		return 0;
+
+	if(is_intelligent && CB_OPERATE_PRECEDENCE_PARRALLEL != PRE_PARRALLEL)
+		return 0;
+	//
+	if(Is_Sub_BMS_1_Normal()&&Is_Sub_BMS_2_Normal())
+		;
+	else
+		return 0;
+	
+	m_1_total_vol = Battery_1_Bu_Chang_Vol();
+	m_2_total_vol = Battery_2_Bu_Chang_Vol();
+
+	if(m_1_total_vol >= m_2_total_vol)
+	{
+		delta_vol = m_1_total_vol - m_2_total_vol;
+	}
+	else
+	{
+		delta_vol = m_2_total_vol - m_1_total_vol;
+	}
+
+	if(delta_vol <= PARRALLEL_BL_DELTA_VOL)
+		return 1;
+
+
+	return 0;
+
+}
+
+uint8_t Change_Mode_Sub_BMS_SERIES(void)
+{
+	int32_t m_1_total_vol,m_2_total_vol;
+	//
+	if(!(cb_operate_state == CB_BAT1 || cb_operate_state == CB_BAT2))
+		return 0;
+	
+	if(is_intelligent && CB_OPERATE_PRECEDENCE_PARRALLEL != PRE_SERIES)
+		return 0;
+#ifdef HAN_GUO_VERSION
+#else
+	if(serise_low_enable)
+		return 0;
+#endif
+
+	if(IS_CHARGE_IN())
+		return 0;
+	
+	if(!(Is_Sub_BMS_1_Normal()&&Is_Sub_BMS_2_Normal()))
+		return 0;
+
+	/*if(cb_operate_state == CB_BAT1)
+	{
+		
+		if((sub_bms_info_2.packet_common.bms_status & BMS_STA_S_BAHU) != 0)
+		{
+			return 0;
+		}
+	}
+	else if(cb_operate_state == CB_BAT2)
+	{
+		
+		if((sub_bms_info_1.packet_common.bms_status & BMS_STA_S_BAHU) != 0)
+		{
+			return 0;
+		}
+	}*/
+#ifdef HAN_GUO_VERSION
+	if(sub_bms_info_1.packet_common.m_percent < 2\
+		|| sub_bms_info_2.packet_common.m_percent < 2)
+		return 0;
+#else
+	if(Next_Series_Not_Enable)
+		return 0;
+
+	
+	m_1_total_vol = Battery_1_Bu_Chang_Vol();
+	m_2_total_vol = Battery_2_Bu_Chang_Vol();
+		
+		
+	if(m_1_total_vol <= SERIES_PROTECT_VOL\
+			||m_2_total_vol <= SERIES_PROTECT_VOL )
+		return 0;
+
+	if(sub_bms_info_1.packet_common.m_percent < SERIES_UNDER_XX_PERCENT\
+		|| sub_bms_info_2.packet_common.m_percent < SERIES_UNDER_XX_PERCENT)
+		return 0;
+#endif	
+	return 1;
+}
+
+
+uint8_t Battery_Change_Mode(uint8_t cfg_mode)
+{
+	uint8_t cb_operate = CB_MAX;
+	
+	if(!work_normal)
+		return 0;
+
+	switch(cfg_mode)
+	{
+		case CFG_BAT_NO:
+			return 0;
+		case CFG_BAT1:
+			if(Change_Mode_Sub_BMS_1_Normal())
+			{
+				cb_operate = CB_BAT1;
+			}
+			break;
+		case CFG_BAT2:
+			if(Change_Mode_Sub_BMS_2_Normal())
+			{
+				cb_operate = CB_BAT2;
+			}
+			break;
+		case CFG_BAT1_BAT2_PARRALLEL:
+			if(Change_Mode_Sub_BMS_PARRALLEL())
+			{
+				cb_operate = CB_BAT1_BAT2_PARRALLEL;
+			}
+			break;
+		case CFG_BAT1_BAT2_SERIES:
+			if(Change_Mode_Sub_BMS_SERIES())
+			{
+				cb_operate = CB_BAT1_BAT2_SERIES;
+			}
+			break;
+		case CFG_MAX:
+		default:
+			return 0;
+	}
+
+	if(cb_operate >= CB_MAX)
+		return 0;
+
+	return Battery_CB_Switch(cb_operate);
+	
+}
+
+void Intelligent_Management_Battery(void)
+{
+	if(is_intelligent)
+	{
+		if(CB_OPERATE_PRECEDENCE_PARRALLEL == PRE_PARRALLEL)
+		{
+			if(cb_operate_state == CB_BAT1_BAT2_PARRALLEL)
+				return;		
+			else if(Battery_Change_Mode(CFG_BAT1_BAT2_PARRALLEL) == CB_BAT1_BAT2_PARRALLEL)
+				return;
+		}
+		else
+		{
+			if(cb_operate_state == CB_BAT1_BAT2_SERIES)
+				return;		
+			else if(Battery_Change_Mode(CB_BAT1_BAT2_SERIES) == CB_BAT1_BAT2_SERIES)
+				return;
+		}
+
+		
+		switch(cb_operate_state)
+		{
+			case CB_BAT1:
+				if(IS_CHARGER_ON())
+				{
+					if((sub_bms_info_1.packet_common.bms_status & BMS_STA_C_FULL) == BMS_STA_C_FULL)
+					{
+						Battery_Change_Mode(CFG_BAT2);
+					}
+					else
+					{
+
+						if(one_bat_charge_status == OBCS_CHARGER_IN)
+						{
+							if(Battery_2_Bu_Chang_Vol() < Battery_1_Bu_Chang_Vol())
+							{
+								Battery_Change_Mode(CFG_BAT2);
+							}
+
+							one_bat_charge_status = OBCS_CHARGER_CHECK_FINISH;
+						}
+					}
+						
+				}
+				else
+				{
+					if((abs(sub_bms_info_1.packet_common.m_current) <= 1000)\
+						&&(Battery_2_Bu_Chang_Vol() > Battery_1_Bu_Chang_Vol()+ONE_BATTERY_DELTA_VOL))
+					{
+						Battery_Change_Mode(CFG_BAT2);
+					}
+				}
+				break;
+			case CB_BAT2:
+				if(IS_CHARGER_ON())
+				{
+					if((sub_bms_info_2.packet_common.bms_status & BMS_STA_C_FULL) == BMS_STA_C_FULL)
+					{
+						Battery_Change_Mode(CFG_BAT1);
+					}
+					else
+					{
+
+						if(one_bat_charge_status == OBCS_CHARGER_IN)
+						{
+							if(Battery_1_Bu_Chang_Vol() < Battery_2_Bu_Chang_Vol())
+							{
+								Battery_Change_Mode(CFG_BAT1);
+							}
+
+							one_bat_charge_status = OBCS_CHARGER_CHECK_FINISH;
+						}
+					}
+				}
+				else
+				{
+					if((abs(sub_bms_info_2.packet_common.m_current) <= 1000)\
+						&&(Battery_1_Bu_Chang_Vol() > Battery_2_Bu_Chang_Vol()+ONE_BATTERY_DELTA_VOL))
+					{
+						Battery_Change_Mode(CFG_BAT1);
+					}
+				}
+				break;	
+			case CB_BAT_NO:
+			case CB_BAT1_BAT2_SERIES:
+			default:
+				break;
+		}
+		
+		
+	}
+}
+
+
+void Check_Battery_Small_Current(void)
+{
+	switch(cb_operate_state)
+	{
+		case CB_BAT1:
+			if((sub_bms_info_2.packet_common.bms_status & BMS_STA_S_OPEN) == BMS_STA_S_OPEN)
+			{
+				sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+				sub_bms_info_2.sub_bms_cmd.param = 0x00;
+			}
+			break;
+		case CB_BAT2:
+			if((sub_bms_info_1.packet_common.bms_status & BMS_STA_S_OPEN) == BMS_STA_S_OPEN)
+			{
+				sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+				sub_bms_info_1.sub_bms_cmd.param = 0x00;
+			}
+			break;
+		case CB_BAT_NO:
+		case CB_BAT1_BAT2_PARRALLEL:
+		case CB_BAT1_BAT2_SERIES:
+		default:
+			break;
+	}
+	
+}
+
+
+
+void Save_Neng_Hao_Bi(uint8_t *data,uint16_t len)
+{
+	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	uint32_t address = 0x08000000 + (capacity - SYLC_FLASH_ADDRESS);
+	uint8_t i = 0;
+	uint32_t df_value = 0x0325;
+	
+	
+	fmc_unlock();
+	Flash_flag_clear();
+	fmc_page_erase(address);
+	Flash_flag_clear();
+	fmc_lock();
+
+
+
+	fmc_unlock();
+	
+	i = 0;
+	while(i<len)
+	{
+		memcpy(&df_value,&data[i],4);
+		fmc_word_program(address + i,df_value);
+		Flash_flag_clear();	
+		i+= 4;
+	}
+
+	fmc_lock();
+	
+}
+
+void Save_Param_Time_Out(void)

+{
+	if(save_param_delay.set)
+	{
+		save_param_delay.count++;
+		if(save_param_delay.count > 600)
+		{
+			save_param_delay.count = 0;
+			g_event |= SAVE_PARAM_EVENT;
+		}
+	}
+}
+void Initial_Neng_Hao_Bi(void)
+{
+	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	uint32_t address = 0x08000000 + (capacity - SYLC_FLASH_ADDRESS);
+	
+	
+	SYLC_SAVE_PARM *sylc_temp = (SYLC_SAVE_PARM *)address;
+
+	memset(&sheng_yu_li_cheng,0x00,sizeof(sheng_yu_li_cheng));
+	
+	if(sylc_temp->sy_valid_flag != SY_VALID_FLAG_KEY)
+	{
+		sheng_yu_li_cheng.sy_ss_parm.sy_valid_flag = SY_VALID_FLAG_KEY;
+		sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi = nhb_default;
+		Save_Neng_Hao_Bi((uint8_t *)&sheng_yu_li_cheng.sy_ss_parm,sizeof(sheng_yu_li_cheng.sy_ss_parm));
+	}
+	else
+	{
+		sheng_yu_li_cheng.sy_ss_parm = *sylc_temp;
+
+		if(sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi < NENG_HAO_BI_MIN)
+		{
+			sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi = NENG_HAO_BI_MIN;
+			Save_Neng_Hao_Bi((uint8_t *)&sheng_yu_li_cheng.sy_ss_parm,sizeof(sheng_yu_li_cheng.sy_ss_parm));
+		}
+		if(sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi > NENG_HAO_BI_MAX)
+		{
+			sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi = NENG_HAO_BI_MAX;
+			Save_Neng_Hao_Bi((uint8_t *)&sheng_yu_li_cheng.sy_ss_parm,sizeof(sheng_yu_li_cheng.sy_ss_parm));
+		}
+	}
+
+	save_param_delay.set = 1;
+	save_param_delay.count = 0;
+	
+}
+
+extern uint8_t Get_QD_State(void);
+uint8_t Reset_Cal(void)
+{
+	if(Get_QD_State() == 0)
+		return 1;
+	
+	if(sheng_yu_li_cheng.sy_dan_ci_li_cheng_temp < sheng_yu_li_cheng.sy_dan_ci_li_cheng)
+		return 1;
+
+	if(sheng_yu_li_cheng.sy_percent_dlta && sheng_yu_li_cheng.sy_dan_ci_li_cheng <= 50)
+		return 1;
+	
+	return 0;
+}
+void Cal_Sheng_Yu_Li_Cheng(void)
+{
+	uint8_t dlta = 0;
+	uint32_t lc_temp;
+	
+	if(Reset_Cal())
+	{
+		sheng_yu_li_cheng.sy_percent_1 = sub_bms_info_1.packet_common.m_percent;
+		sheng_yu_li_cheng.sy_percent_2 = sub_bms_info_2.packet_common.m_percent;
+		sheng_yu_li_cheng.sy_percent_dlta = 0;
+		//Left_Light_Enable(1);
+	}
+	sheng_yu_li_cheng.sy_dan_ci_li_cheng = sheng_yu_li_cheng.sy_dan_ci_li_cheng_temp;
+
+	
+	if(sub_bms_info_1.rs485_connect && sub_bms_info_1.packet_common.m_percent != 0)
+	{
+		if(sheng_yu_li_cheng.sy_percent_1 > sub_bms_info_1.packet_common.m_percent)
+		{
+			dlta = sheng_yu_li_cheng.sy_percent_1 - sub_bms_info_1.packet_common.m_percent;
+			sheng_yu_li_cheng.sy_percent_dlta += dlta;
+		}
+	}
+	sheng_yu_li_cheng.sy_percent_1 = sub_bms_info_1.packet_common.m_percent;
+	
+	if(sub_bms_info_2.rs485_connect && sub_bms_info_2.packet_common.m_percent != 0)
+	{
+		if(sheng_yu_li_cheng.sy_percent_2 > sub_bms_info_2.packet_common.m_percent)
+		{
+			dlta = sheng_yu_li_cheng.sy_percent_2 - sub_bms_info_2.packet_common.m_percent;
+			sheng_yu_li_cheng.sy_percent_dlta += dlta;
+		}
+	}
+	sheng_yu_li_cheng.sy_percent_2 = sub_bms_info_2.packet_common.m_percent;
+
+	sheng_yu_li_cheng.sy_percent_total = sub_bms_info_1.packet_common.m_percent + sub_bms_info_2.packet_common.m_percent;
+
+	if(dlta && sheng_yu_li_cheng.sy_percent_dlta >= 7 && sheng_yu_li_cheng.sy_dan_ci_li_cheng > 700 )
+	{
+		double nhb_temp = (double)(sheng_yu_li_cheng.sy_dan_ci_li_cheng)/sheng_yu_li_cheng.sy_percent_dlta;
+		if(nhb_temp < NENG_HAO_BI_MIN)
+			nhb_temp = NENG_HAO_BI_MIN;
+		if(nhb_temp > NENG_HAO_BI_MAX)
+			nhb_temp = NENG_HAO_BI_MAX;
+		
+		sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi = sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi*0.8 + nhb_temp*0.2;
+		
+	}
+	else
+	{
+		
+	}
+
+	
+	
+	lc_temp = (uint32_t)(sheng_yu_li_cheng.sy_percent_total*sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi/1000);
+	if(lc_temp > 200)
+		lc_temp = 200;
+	#if 0
+	//bang zi ce shi start
+	sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng = (uint8_t)(lc_temp*2);
+	//bang zi ce shi end
+	#else
+	sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng = (uint8_t)lc_temp;
+	#endif
+	if(sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng == 0\
+		|| (sub_bms_info_1.packet_common.bms_status & BMS_STA_JIAO_YAN)\
+		|| (sub_bms_info_2.packet_common.bms_status & BMS_STA_JIAO_YAN))
+	{
+		
+		sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng = sub_bms_info_1.packet_common.yjkxslc\
+															+ sub_bms_info_2.packet_common.yjkxslc;
+	}
+	
+}
+
+void Save_Param(void)
+{
+	Save_Neng_Hao_Bi((uint8_t *)&sheng_yu_li_cheng.sy_ss_parm,sizeof(sheng_yu_li_cheng.sy_ss_parm));
+}
+

+ 236 - 0
Source/app.h

@@ -0,0 +1,236 @@
+#ifndef APP_H
+#define APP_H
+
+//#define IS_CHARGE_IN()			!gpio_input_bit_get(GPIOC,GPIO_PIN_4)
+#define IS_CHARGER_ON() 		gpio_output_bit_get(GPIOB,GPIO_PIN_12)
+#define CHARG_PROTECT_OPEN(x)   gpio_bit_write(GPIOB,GPIO_PIN_12,(bit_status)(x))
+#define BAT1_IS_OPEN()          !gpio_input_bit_get(GPIOC,GPIO_PIN_2)
+#define BAT2_IS_OPEN()          !gpio_input_bit_get(GPIOC,GPIO_PIN_1)
+
+#define S10_ENABLE(x)  //gpio_bit_write()
+#define S11_ENABLE(x)  gpio_bit_write(GPIOB,GPIO_PIN_13,(bit_status)(x))
+#define S20_ENABLE(x)  //gpio_bit_write()
+#define S21_ENABLE(x)  gpio_bit_write(GPIOB,GPIO_PIN_15,(bit_status)(x))
+#define SS__ENABLE(x)  gpio_bit_write(GPIOB,GPIO_PIN_14,(bit_status)(x))
+
+#define BATTERY_RESISTANCE_OHM    (0.1F)
+#define PARRALLEL_DELTA_VOL    	  (2500)
+#define PARRALLEL_BL_DELTA_VOL    (100)
+
+#define CHARGE_DELAY_TIME_OUT_COUNT   (10000)
+
+#define ONE_BATTERY_DELTA_VOL    (500)
+
+enum
+{
+	PRE_PARRALLEL,
+	PRE_SERIES,
+	
+
+	PRE_MAX
+};
+
+enum
+{
+	CFG_BAT_NO,
+	CFG_BAT1,
+	CFG_BAT2,
+	CFG_BAT1_BAT2_PARRALLEL,
+	CFG_BAT1_BAT2_SERIES,
+
+
+	
+	CFG_MAX
+};
+
+
+
+enum
+{
+	CB_BAT_NO,
+	CB_BAT1,
+	CB_BAT2,
+	CB_BAT1_BAT2_PARRALLEL,
+	CB_BAT1_BAT2_SERIES,
+
+
+	
+	CB_MAX
+};
+
+enum
+{
+	CB_NO_ERR,
+	CB_NO_BAT1,
+	CB_NO_BAT2,
+	CB_NO_OPERATE,
+
+	CB_MAX_ERR
+};
+
+typedef struct
+{
+	uint8_t s10_bit:1;
+	uint8_t s11_bit:1;
+	uint8_t s20_bit:1;
+	uint8_t s21_bit:1;
+	uint8_t ss__bit:1;
+}CB_VAL;
+
+
+extern CB_VAL cb_val_last;
+extern uint8_t cb_operate_state;
+extern uint8_t Check_CB_oper_sta_start;
+extern DELAY_COMMON Check_CB_oper_sta_delay;
+extern uint8_t is_intelligent;
+extern uint8_t CB_OPERATE_PRECEDENCE_Config;
+
+__inline void Check_CB_Oper_Sta_Delay(void)
+{
+	if(Check_CB_oper_sta_delay.set)
+	{
+		if(++Check_CB_oper_sta_delay.count >= 2000)
+		{
+			Check_CB_oper_sta_delay.count = 0;
+			Check_CB_oper_sta_start = 1;
+		}
+	}
+		
+}
+
+#define CHECK_SERIES_VOL  (80000)
+
+#ifdef HAN_GUO_VERSION
+#define CHECK_SERIES_PROTECT_VOL  (20000)
+#else
+#define CHECK_SERIES_PROTECT_VOL  (40000)
+#endif
+
+#define SERIES_PROTECT_VOL  (CHECK_SERIES_PROTECT_VOL + 3000)
+#define SERIES_UNDER_VOL_TIME_OUT  (4000)
+#define NEXT_SERIES_TIME_OUT  (5000)
+#define SELECT_ONE_BATTERY_VOL  (65000)
+#define SERIES_UNDER_XX_PERCENT  (20)
+
+enum
+{
+	D_BMS_ERROR_NO,
+	D_BMS_ERROR_SERISE_CD_OFF,
+
+
+	D_BMS_ERROR_MAX
+};
+extern uint8_t define_bms_1_error;
+extern uint8_t define_bms_2_error;
+
+enum
+{
+	OBCS_CHARGER_OUT,
+	OBCS_CHARGER_IN,
+	OBCS_CHARGER_CHECK_FINISH,
+
+
+	OBCS_CHARGER_MAX
+};
+extern uint8_t one_bat_charge_status;
+extern uint8_t serise_low_enable;
+extern uint8_t serise_low_qd_status;
+
+enum
+{
+	UPDATE_BAT_NO,
+	UPDATE_BAT_1,
+	UPDATE_BAT_2,
+
+	UPDATE_BAT_MAX
+};
+enum
+{
+	UPDATE_STEP_NO,
+	UPDATE_STEP_REQ,
+	UPDATE_STEP_DATA,
+
+	UPDATE_STEP_MAX
+};
+
+#pragma  pack (push,1)  
+#define UB_DATA_MAX   (128)
+typedef struct
+{
+	uint8_t ub_step;
+	uint8_t ub_bat;
+	uint16_t ub_total;
+	uint16_t ub_sq;
+	uint16_t ub_len;
+	uint8_t ub_data[UB_DATA_MAX];
+}UPDATE_BAT;
+#pragma pack(pop)
+extern UPDATE_BAT update_bat;
+
+
+#define NENG_HAO_BI_MIN   (300)
+#define NENG_HAO_BI_MAX   (700)
+#define SY_VALID_FLAG_KEY   (0x0325)
+typedef struct
+{
+	uint16_t sy_valid_flag;
+	double neng_hao_bi;
+}SYLC_SAVE_PARM;
+
+typedef struct
+{
+	uint32_t sy_dan_ci_li_cheng_temp;
+	uint32_t sy_dan_ci_li_cheng;
+	uint8_t sy_percent_1;
+	uint8_t sy_percent_2;
+	uint8_t sy_percent_dlta;
+	uint8_t sy_percent_total;
+	uint8_t sy_yu_ji_ke_xing_shi_li_cheng;
+	SYLC_SAVE_PARM sy_ss_parm;
+}SHENG_YU_LI_CHENG;
+extern SHENG_YU_LI_CHENG sheng_yu_li_cheng;
+extern uint8_t power_switch_from;
+extern uint8_t work_normal;
+
+void App_Initial(void);
+
+void CB_Operate_Initial(void);
+
+void Misc_Initial(void);
+
+void Battery_CB_Operate(CB_VAL *cb_val);
+
+int8_t Battery_CB_Switch(uint8_t cb_operate);
+
+uint8_t Is_BAT1_Lock(void);
+
+uint8_t Is_BAT2_Lock(void);
+
+void Check_Charge_In(void);
+
+void Check_CB_Operate_State(void);
+
+uint8_t Battery_Change_Mode(uint8_t cfg_mode);
+
+void Power_On_Normal(uint8_t enable,uint8_t from);
+
+void Intelligent_Management_Battery(void);
+
+void Check_Battery_Small_Current(void);
+
+uint8_t Is_Soak(void);
+
+void Series_Delay_Timeout(void);
+
+void Cal_Sheng_Yu_Li_Cheng(void);
+
+void Initial_Neng_Hao_Bi(void);
+
+extern void Flash_flag_clear(void);
+
+void Save_Param_Time_Out(void)
;
+
+void Save_Param(void);
+
+#endif
+

+ 361 - 0
Source/app_adas.c

@@ -0,0 +1,361 @@
+#include "common.h"
+#include "drv_adas.h"
+#include "drv_can.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "app_can.h"
+#include "app.h"
+#include "app_adas.h"
+
+
+uint16_t array_juli_1[ADAS_ARRAY_JU_LI_MAX];
+uint16_t array_juli_1_index = 0;
+
+uint16_t array_juli_2[ADAS_ARRAY_JU_LI_MAX];
+uint16_t array_juli_2_index = 0;
+
+DELAY_COMMON adas_delay;
+uint8_t adas_receive_stag = ADAS_RECEIVE_0;
+uint16_t ju_li_1 = 0xFFFF;
+uint16_t ju_li_2 = 0xFFFF;
+uint8_t current_pwm_no = ADAS_PWM_0;
+
+
+void Sort(uint16_t *arr,uint16_t size)
+{
+	uint16_t i,j,tmp;
+
+	for(i = 0; i < size - 1;i++)
+	{
+		for(j = 0; j < size - i - 1;j++)
+		{
+			if(arr[j] > arr[j+1])
+			{
+				tmp = arr[j];
+				arr[j] = arr[j+1];
+				arr[j+1] = tmp;			
+			}
+		}
+	}
+}
+
+void ADAS_Measure_Finish_Ju_Li_1(void)
+{
+	Sort(array_juli_1,ADAS_ARRAY_JU_LI_MAX);
+	ju_li_1 = array_juli_1[ADAS_ARRAY_JU_LI_MAX>>1];
+}
+
+void ADAS_Measure_Finish_Ju_Li_2(void)
+{
+	Sort(array_juli_2,ADAS_ARRAY_JU_LI_MAX);
+	ju_li_2 = array_juli_2[ADAS_ARRAY_JU_LI_MAX>>1];
+}
+
+void ADAS_Measure_Ju_Li_1(void)
+{
+	 uint32_t time;
+	 uint16_t temp_juli = 0;
+	 
+	if(current_pwm_no != ADAS_PWM_1)
+		return;
+	
+	if(gpio_input_bit_get(GPIOC,GPIO_PIN_8) == 1&&adas_receive_stag == ADAS_RECEIVE_1)
+	{
+	
+		time = timer_counter_read(TIMER0);
+		if(time > ADAS_PWM_SENDING_MAX_TIME)
+		{
+			//<30CM
+			temp_juli = ADAS_JU_LI_JING;
+			adas_receive_stag = ADAS_RECEIVE_0;
+			current_pwm_no = ADAS_PWM_0;
+			timer_disable(TIMER0);
+		}
+		else
+			adas_receive_stag = ADAS_RECEIVE_2;
+	}
+	else if(gpio_input_bit_get(GPIOC,GPIO_PIN_8) == 0&&adas_receive_stag == ADAS_RECEIVE_2)
+	{
+		time = timer_counter_read(TIMER0);
+		time >>= 1;
+
+		temp_juli = (uint16_t)((double)time*YIN_SU/10);
+		adas_receive_stag = ADAS_RECEIVE_0;
+		current_pwm_no = ADAS_PWM_0;
+		timer_disable(TIMER0);
+	}
+
+	//
+	if(adas_receive_stag == ADAS_RECEIVE_0)
+	{
+		array_juli_1[array_juli_1_index++] = temp_juli;
+
+		if(array_juli_1_index >= ADAS_ARRAY_JU_LI_MAX)
+		{
+			array_juli_1_index = 0;
+
+			g_event |= ADAS_MEAS_1_FINISH_EVENT;
+		}
+	}
+}
+
+void ADAS_Measure_Ju_Li_2(void)
+{
+	uint32_t time;
+	uint16_t temp_juli = 0;
+	
+	if(current_pwm_no != ADAS_PWM_2)
+		return;
+	
+	if(gpio_input_bit_get(GPIOC,GPIO_PIN_9) == 1&&adas_receive_stag == ADAS_RECEIVE_1)
+	{
+	
+		time = timer_counter_read(TIMER0);
+		if(time > ADAS_PWM_SENDING_MAX_TIME)
+		{
+			//<30CM
+			temp_juli = ADAS_JU_LI_JING;
+			adas_receive_stag = ADAS_RECEIVE_0;
+			current_pwm_no = ADAS_PWM_0;
+			timer_disable(TIMER0);
+		}
+		else
+			adas_receive_stag = ADAS_RECEIVE_2;
+	}
+	else if(gpio_input_bit_get(GPIOC,GPIO_PIN_9) == 0&&adas_receive_stag == ADAS_RECEIVE_2)
+	{
+		time = timer_counter_read(TIMER0);
+		time >>= 1;
+
+		temp_juli = (uint16_t)((double)time*YIN_SU/10);
+		adas_receive_stag = ADAS_RECEIVE_0;
+		current_pwm_no = ADAS_PWM_0;
+		timer_disable(TIMER0);
+	}
+
+	//
+	if(adas_receive_stag == ADAS_RECEIVE_0)
+	{
+		array_juli_2[array_juli_2_index++] = temp_juli;
+
+		if(array_juli_2_index >= ADAS_ARRAY_JU_LI_MAX)
+		{
+			array_juli_2_index = 0;
+
+			g_event |= ADAS_MEAS_2_FINISH_EVENT;
+		}
+	}
+}
+
+
+void ADAS_PWM_1_Enable(void)
+{
+	 timer_disable(TIMER1);
+
+	 ADAS_PWM_Initial(ADAS_PWM_1);
+
+	 timer_enable(TIMER2);
+
+	 timer_enable(TIMER0);
+
+	 timer_counter_value_config(TIMER0,0);
+	 
+	 adas_receive_stag = ADAS_RECEIVE_1;
+	 
+	 //ju_li_1 = 0;
+
+	 current_pwm_no = ADAS_PWM_1;
+}
+
+void ADAS_PWM_2_Enable(void)
+{
+	 timer_disable(TIMER1);
+
+	 ADAS_PWM_Initial(ADAS_PWM_2);
+	 
+	 timer_enable(TIMER2);
+
+	 timer_enable(TIMER0);
+
+	 timer_counter_value_config(TIMER0,0);
+	 
+	 adas_receive_stag = ADAS_RECEIVE_1;
+
+	 //ju_li_2 = 0;
+
+	 current_pwm_no = ADAS_PWM_2;
+}
+
+void ADAS_Timeout(void)
+{
+	
+	if(adas_delay.set)
+	{
+		++adas_delay.count;
+		if(adas_delay.count >= ADAS_ZONG_TIME)
+		{
+			g_event |= ADAS_PWM_1_TIMEOUT_EVENT;
+			adas_delay.count = 0;
+		}
+		else if(adas_delay.count == ADAS_LIANG_TIME)
+		{
+			g_event |= ADAS_PWM_2_TIMEOUT_EVENT;
+		}
+	}
+}
+
+void ADAS_Enable(uint8_t enable)
+{
+	if(enable)
+	{
+		adas_delay.set = 1;
+		adas_delay.count = ADAS_ZONG_TIME;
+	}
+	else
+	{
+		adas_delay.set = 0;
+		adas_delay.count = 0;
+	}
+}
+ void ADAS_Initial(void)
+{
+	 ADAS_Drv_Initial();
+	 
+	 ADAS_Enable(0);
+}
+
+
+void Can_ADAS_Self_Send(CAN_FRAME*can_adas_frame)
+{
+	uint16_t len;
+	uint8_t *buf = can_adas_frame->data;
+
+	len = 0;
+	buf[len++] = (uint8_t)(KEY_ADAS_SELF_UP >> 0);
+	buf[len++] = (uint8_t)(KEY_ADAS_SELF_UP >> 8);
+	buf[len++] = (uint8_t)(ju_li_1 >> 0);
+	buf[len++] = (uint8_t)(ju_li_1 >> 8);
+	buf[len++] = (uint8_t)(ju_li_2 >> 0);
+	buf[len++] = (uint8_t)(ju_li_2 >> 8);
+
+	//
+	can_adas_frame->head.rsp = FRAME_PT_NO_RSP;
+	can_adas_frame->head.dest = CTR_ID;
+	can_adas_frame->head.sour = SELF_ID;
+	can_adas_frame->head.index = 1;
+	can_adas_frame->head.total = (len - 1)/8 + 1;
+	can_adas_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_adas_frame->len = len;
+
+	//
+	if(!Send_Data_Can(can_adas_frame,ADAS_SELF))
+	{
+		//g_event |= ADAS_RESEND_CMD_EVENT;
+		//return 0;
+	}
+	
+}
+
+int8_t Handle_Can_Adas_CMD(CAN_FRAME*can_adas_frame)
+{
+	uint16_t key;
+	uint8_t *buf = can_adas_frame->data;
+
+	memcpy(&key,can_adas_frame->data,sizeof(key));
+
+	switch(key)
+	{
+		case KEY_ADAS_COMMON:
+			break;
+		
+		case KEY_ADAS_ENABLE:
+			switch(buf[2])
+			{
+				case 0:
+					ADAS_Enable(0);
+					
+					break;
+				case 1:
+					ADAS_Enable(1);
+					
+					break;
+				default:
+					return 0;
+			}
+			break;
+	
+		case KEY_ADAS_SELF_UP:
+			return 0;	
+		default:
+			return 0;
+
+	}
+	
+	return 1;
+	
+}
+
+int8_t Rsp_Can_Adas_CMD(CAN_FRAME*can_adas_frame)
+{
+	uint16_t key,len;
+	uint8_t *buf = can_adas_frame->data;
+	
+	memcpy(&key,can_adas_frame->data,sizeof(key));
+
+	switch(key)
+	{
+		case KEY_ADAS_COMMON:
+			if((can_adas_frame->head.rsp != FRAME_PT_NEED_RSP))
+				return 1;
+			len = 0;
+			buf[len++] = (uint8_t)(KEY_ADAS_COMMON >> 0);
+			buf[len++] = (uint8_t)(KEY_ADAS_COMMON >> 8);
+			buf[len++] = 0;
+			buf[len++] = adas_delay.set;
+			buf[len++] = (uint8_t)(ju_li_1 >> 0);
+			buf[len++] = (uint8_t)(ju_li_1 >> 8);
+			buf[len++] = (uint8_t)(ju_li_2 >> 0);
+			buf[len++] = (uint8_t)(ju_li_2 >> 8);
+			
+			break;	
+		case KEY_ADAS_ENABLE:
+			if((can_adas_frame->head.rsp != FRAME_PT_NEED_RSP))
+				return 1;
+			
+			len = 0;
+			buf[len++] = (uint8_t)(KEY_ADAS_ENABLE >> 0);
+			buf[len++] = (uint8_t)(KEY_ADAS_ENABLE >> 8);
+			buf[len++] = 0;
+			buf[len++] = adas_delay.set;
+			break;	
+		case KEY_ADAS_SELF_UP:
+			return 0;
+		default:
+			return 0;
+	}
+	//
+	can_adas_frame->head.rsp = FRAME_PT_RSP;
+	can_adas_frame->head.dest = can_adas_frame->head.sour;
+	can_adas_frame->head.sour = SELF_ID;
+	can_adas_frame->head.index = 1;
+	can_adas_frame->head.total = (len - 1)/8 + 1;
+	can_adas_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_adas_frame->len = len;
+
+	//
+	if(!Send_Data_Can(can_adas_frame,ADAS_RSP))
+	{
+		g_event |= ADAS_RESEND_CMD_EVENT;
+		return 0;
+	}
+	
+	return 1;
+
+}
+
+
+
+
+

+ 52 - 0
Source/app_adas.h

@@ -0,0 +1,52 @@
+#ifndef APP_ADAS_H
+#define APP_ADAS_H
+
+#define ADAS_LIANG_TIME  (100)
+#define ADAS_ZONG_TIME    (200)
+
+
+#define ADAS_ARRAY_JU_LI_MAX    (5)
+#define ADAS_JU_LI_JING    (40)
+#define ADAS_PWM_SENDING_MAX_TIME    (2500)
+#define YIN_SU                       (0.34F) //unit:mm/us
+
+
+enum
+{
+	ADAS_RECEIVE_0,
+	ADAS_RECEIVE_1,
+	ADAS_RECEIVE_2	
+};
+extern uint8_t adas_receive_stag;
+extern uint16_t ju_li_1;//cm
+extern uint16_t ju_li_2;//cm
+
+//END CTR
+#define KEY_ADAS_COMMON          (0x5200)
+#define KEY_ADAS_ENABLE          (0x5201)
+#define KEY_ADAS_SELF_UP         (0x5280)
+
+
+
+void ADAS_Measure_Finish_Ju_Li_1(void);
+
+void ADAS_Measure_Finish_Ju_Li_2(void);
+
+void ADAS_PWM_1_Enable(void);
+
+void ADAS_PWM_2_Enable(void);
+
+void ADAS_Timeout(void);
+
+ void ADAS_Initial(void);
+
+void Can_ADAS_Self_Send(CAN_FRAME*can_adas_frame);
+
+int8_t Handle_Can_Adas_CMD(CAN_FRAME*can_adas_frame);
+
+int8_t Rsp_Can_Adas_CMD(CAN_FRAME*can_adas_frame);
+
+void ADAS_Enable(uint8_t enable);
+
+#endif
+

+ 346 - 0
Source/app_bms_1.c

@@ -0,0 +1,346 @@
+#include "common.h"
+#include "drv_can.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "app_can.h"
+#include "app.h"
+#include "app_bms_1.h"
+
+BMS_SELF_SEND_STATUS bms_1_self_ss;
+BMS_SELF_CUR_VOL_STATUS bms_1_cur_vol_ss;
+DELAY_COMMON bms_1_self_stimeout;
+
+
+void Can_Bms_1_Cur_Vol_Self_Send_Check(CAN_FRAME*can_bms_1_frame)
+{
+	uint16_t len;
+	uint8_t *buf = can_bms_1_frame->data;
+
+	
+	do
+	{
+		if(bms_1_cur_vol_ss.m_cur != sub_bms_info_1.packet_common.m_current/RESOLUTION_DELTA_50M)
+			break;
+		if(bms_1_cur_vol_ss.m_vol != sub_bms_info_1.packet_common.m_total_vol/RESOLUTION_DELTA_50M)
+			break;
+		
+		return;
+	}while(0);
+
+	bms_1_cur_vol_ss.m_cur = sub_bms_info_1.packet_common.m_current/RESOLUTION_DELTA_10M;
+	bms_1_cur_vol_ss.m_vol = sub_bms_info_1.packet_common.m_total_vol/RESOLUTION_DELTA_10M;
+	len = sizeof(bms_1_cur_vol_ss);
+	//
+	can_bms_1_frame->head.rsp = FRAME_PT_NO_RSP;
+	can_bms_1_frame->head.dest = CTR_ID;
+	can_bms_1_frame->head.sour = SELF_ID;
+	can_bms_1_frame->head.index = 1;
+	can_bms_1_frame->head.total = (len - 1)/8 + 1;
+	can_bms_1_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_bms_1_frame->len = len;
+	memcpy(buf,&bms_1_cur_vol_ss,len);
+	
+	bms_1_self_stimeout.set = 0;
+	bms_1_self_stimeout.count = 0;
+	g_event &= ~BMS_1_SELF_TIMEOUT_EVENT;
+	//
+	if(!Send_Data_Can(can_bms_1_frame,BMS_1_CUR_VOL_SELF))
+	{
+		//g_event |= BMS_1_RESEND_CMD_EVENT;
+		//return;
+	}
+
+	//
+	bms_1_cur_vol_ss.m_cur = sub_bms_info_1.packet_common.m_current/RESOLUTION_DELTA_50M;
+	bms_1_cur_vol_ss.m_vol = sub_bms_info_1.packet_common.m_total_vol/RESOLUTION_DELTA_50M;
+	
+}
+
+void Can_Bms_1_Self_Send_Check(CAN_FRAME*can_bms_1_frame)
+{
+	uint16_t len;
+	uint8_t *buf = can_bms_1_frame->data;
+
+	
+	do
+	{
+		if(bms_1_self_ss.m_percent != sub_bms_info_1.packet_common.m_percent)
+			break;
+		if(bms_1_self_ss.charge_flag != sub_bms_info_1.packet_common.charge_flag)
+			break;
+		if(bms_1_self_ss.work_status != sub_bms_info_1.packet_common.work_status)
+			break;
+		//if(bms_1_self_ss.bms_status != sub_bms_info_1.packet_common.bms_status)
+		//	break;
+		//Can_Bms_1_Cur_Vol_Self_Send_Check(can_bms_1_frame);
+		return;
+	}while(0);
+
+	bms_1_self_ss.m_percent = sub_bms_info_1.packet_common.m_percent;
+	bms_1_self_ss.charge_flag = sub_bms_info_1.packet_common.charge_flag;
+	bms_1_self_ss.work_status = sub_bms_info_1.packet_common.work_status;
+	len = sizeof(bms_1_self_ss);
+	//
+	can_bms_1_frame->head.rsp = FRAME_PT_NEED_RSP;
+	can_bms_1_frame->head.dest = CTR_ID;
+	can_bms_1_frame->head.sour = SELF_ID;
+	can_bms_1_frame->head.index = 1;
+	can_bms_1_frame->head.total = (len - 1)/8 + 1;
+	can_bms_1_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_bms_1_frame->len = len;
+	memcpy(buf,&bms_1_self_ss,len);
+	
+	bms_1_self_stimeout.set = 1;
+	bms_1_self_stimeout.count = 0;
+	//
+	if(!Send_Data_Can(can_bms_1_frame,BMS_1_SELF))
+	{
+		//g_event |= BMS_1_RESEND_CMD_EVENT;
+		//return;
+	}
+	
+}
+int8_t Handle_Can_Bms_1_CMD(CAN_FRAME*can_bms_1_frame)
+{
+	uint16_t key;
+
+	memcpy(&key,can_bms_1_frame->data,sizeof(key));
+
+	switch(key)
+	{
+		case KEY_BMS_1_COMMON:
+			break;
+		case KEY_BMS_1_READ_INFO:
+			break;
+		case KEY_BMS_1_READ_VER:
+			break;
+		case KEY_BMS_1_ALARM_TIMES:
+			break;
+		case KEY_BMS_1_ALARM_TIMES_1:
+			break;
+		case KEY_BMS_1_ALARM_TIMES_2:
+			break;
+		case KEY_BMS_1_CELL_VOL:
+			break;
+		case KEY_BMS_1_CELL_VOL_1:
+			break;
+		case KEY_BMS_1_CELL_VOL_2:
+			break;
+		case KEY_BMS_1_TEMP_OTHER:
+			break;
+		case KEY_BMS_1_SELF_UP:
+			bms_1_self_stimeout.set = 0;
+			return 0;	
+		default:
+			return 0;
+
+	}
+	
+	return 1;
+	
+}
+
+int8_t Rsp_Can_Bms_1_CMD(CAN_FRAME*can_bms_1_frame)
+{
+	uint16_t key,len;
+	uint8_t *buf = can_bms_1_frame->data,*bt;
+	uint16_t temp;
+
+	memcpy(&key,can_bms_1_frame->data,sizeof(key));
+
+	switch(key)
+	{
+		case KEY_BMS_1_COMMON:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			memcpy(&buf[len],&sub_bms_info_1.packet_common,sizeof(sub_bms_info_1.packet_common) - 1);
+			if(sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng)
+			{
+				if(sheng_yu_li_cheng.sy_percent_total == sub_bms_info_1.packet_common.m_percent)
+					buf[3] = sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng;
+				else
+					#if 0
+					//bang zi ce shi start
+					buf[3] = sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng*sub_bms_info_1.packet_common.m_percent/50;
+					//bang zi ce shi start
+					#else
+					{
+						if(Is_Sub_BMS_1_Normal())
+						{
+							temp = (uint16_t)(sub_bms_info_1.packet_common.m_percent*sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi*10/1000);
+							if(temp%10 >= 5)
+								buf[3] = temp/10 + 1;
+							else
+								buf[3] = temp/10;
+							
+						}
+						else
+							buf[3] = 0;
+					}
+					#endif
+			}
+			len += sizeof(sub_bms_info_1.packet_common) - 1;
+			break;
+		case KEY_BMS_1_READ_INFO:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			memcpy(&buf[len],sub_bms_info_1.bat_dev_info.sn,sizeof(sub_bms_info_1.bat_dev_info.sn));
+			len += sizeof(sub_bms_info_1.bat_dev_info.sn);
+			break;	
+		case KEY_BMS_1_READ_VER:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			memcpy(&buf[len],sub_bms_info_1.bat_dev_info.soft_ver,sizeof(sub_bms_info_1.bat_dev_info.soft_ver));
+			len += sizeof(sub_bms_info_1.bat_dev_info.soft_ver);
+			break;
+		case KEY_BMS_1_ALARM_TIMES:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			//memcpy(&buf[len],&sub_bms_info_1.bat_times,sizeof(sub_bms_info_1.bat_times));
+			//len += sizeof(sub_bms_info_1.bat_times);
+			bt = (uint8_t*)(&sub_bms_info_1.bat_times);
+			memcpy(&buf[len],bt,14);
+			len += 14;
+			break;
+		case KEY_BMS_1_ALARM_TIMES_1:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_1.bat_times);
+			memcpy(&buf[len],&bt[14],16);
+			len += 16;
+			break;
+		case KEY_BMS_1_ALARM_TIMES_2:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_1.bat_times);
+			memcpy(&buf[len],&bt[30],12);
+			len += 12;
+			break;
+		case KEY_BMS_1_CELL_VOL:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_1.cell_vol);
+			memcpy(&buf[len],bt,13);
+			len += 13;
+			break;
+		case KEY_BMS_1_CELL_VOL_1:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_1.cell_vol);	
+			memcpy(&buf[len],&bt[13],12);
+			len += 12;
+			break;
+		case KEY_BMS_1_CELL_VOL_2:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_1.cell_vol);
+			memcpy(&buf[len],&bt[25],6);
+			len += 6;
+			//
+			memset(&buf[len],0x00,6);
+			len += 6;
+			break;
+		case KEY_BMS_1_TEMP_OTHER:
+			if((can_bms_1_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_1_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_1.temp_other);
+			memcpy(&buf[len],bt,5);
+			len += 5;
+			break;
+		case KEY_BMS_1_SELF_UP:
+			return 0;
+		default:
+			return 0;
+	}
+	//
+	can_bms_1_frame->head.rsp = FRAME_PT_RSP;
+	can_bms_1_frame->head.dest = can_bms_1_frame->head.sour;
+	can_bms_1_frame->head.sour = SELF_ID;
+	can_bms_1_frame->head.index = 1;
+	can_bms_1_frame->head.total = (len - 1)/8 + 1;
+	can_bms_1_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_bms_1_frame->len = len;
+
+	//
+	if(!Send_Data_Can(can_bms_1_frame,BMS_1_RSP))
+	{
+		g_event |= BMS_1_RESEND_CMD_EVENT;
+		return 0;
+	}
+	
+	return 1;
+
+}
+
+
+void Bms_1_Self_Send_Timeout(void)
+{
+	if(bms_1_self_stimeout.set)
+	{
+		++bms_1_self_stimeout.count;
+		if(bms_1_self_stimeout.count >= 300)
+		{
+			memset(&bms_1_self_stimeout,0x00,sizeof(bms_1_self_stimeout));
+			g_event |= BMS_1_SELF_TIMEOUT_EVENT;
+		}
+		else if(bms_1_self_stimeout.count == 200)
+			g_event |= BMS_1_SELF_TIMEOUT_EVENT;
+		else if(bms_1_self_stimeout.count == 100)
+			g_event |= BMS_1_SELF_TIMEOUT_EVENT;
+	}
+	else
+		bms_1_self_stimeout.count = 0;
+	
+}
+
+#define RS485_PRINT_ENABLE   (0)
+void RS485_Print(uint8_t dest,uint8_t * dbuf,uint16_t dbuf_len)
+{
+
+#if RS485_PRINT_ENABLE
+	CAN_FRAME can_bms_1_frame;
+	
+	can_bms_1_frame.head.rsp = FRAME_PT_NO_RSP;
+	can_bms_1_frame.head.dest = dest;
+	can_bms_1_frame.head.sour = SELF_ID;
+	can_bms_1_frame.head.index = 1;
+	can_bms_1_frame.head.total = (dbuf_len - 1)/8 + 1;
+	can_bms_1_frame.head.pro   =FRAME_PRO_D;
+	//
+	can_bms_1_frame.len = dbuf_len;
+	memcpy(can_bms_1_frame.data,dbuf,dbuf_len);
+
+	//
+	if(!Send_Data_Can(&can_bms_1_frame,OTHER_SEND))
+	{
+		//g_event |= BMS_1_RESEND_CMD_EVENT;
+		//return;
+	}
+#endif
+
+}

+ 42 - 0
Source/app_bms_1.h

@@ -0,0 +1,42 @@
+#ifndef APP_BMS_1_H
+#define APP_BMS_1_H
+
+#define KEY_BMS_1_COMMON            (0x3100)
+#define KEY_BMS_1_BOND  			(0x3101)
+#define KEY_BMS_1_UNBOND            (0x3102)
+#define KEY_BMS_1_PAIR              (0x3103)
+#define KEY_BMS_1_UPDATE_PAIR       (0x3104)
+#define KEY_BMS_1_READ_INFO         (0x3105)
+#define KEY_BMS_1_ALARM_TIMES       (0x3106)
+#define KEY_BMS_1_CELL_VOL          (0x3107)
+#define KEY_BMS_1_BAT_VOL           (0x3108)
+#define KEY_BMS_1_CHARGER_ONOFF     (0x3109)
+#define KEY_BMS_1_READ_BAT          (0x310A)
+#define KEY_BMS_1_OPEN_FET          (0x310B)
+#define KEY_BMS_1_READ_VER          (0x310C)
+#define KEY_BMS_1_ALARM_TIMES_1     (0x310D)
+#define KEY_BMS_1_ALARM_TIMES_2     (0x310E)
+#define KEY_BMS_1_CELL_VOL_1        (0x310F)
+#define KEY_BMS_1_CELL_VOL_2        (0x3110)
+#define KEY_BMS_1_TEMP_OTHER        (0x3111)
+#define KEY_BMS_1_TEMP_OTHER_1      (0x3112)
+#define KEY_BMS_1_TEMP_OTHER_2      (0x3113)
+#define KEY_BMS_1_SELF_UP           (0x3181)
+#define KEY_BMS_1_CUR_VOL_SELF_UP   (0x3182)
+
+extern BMS_SELF_SEND_STATUS bms_1_self_ss;
+extern BMS_SELF_CUR_VOL_STATUS bms_1_cur_vol_ss;
+extern DELAY_COMMON bms_1_self_stimeout;
+
+int8_t Handle_Can_Bms_1_CMD(CAN_FRAME*can_bms_1_frame);
+
+int8_t Rsp_Can_Bms_1_CMD(CAN_FRAME*can_bms_1_frame);
+
+void Can_Bms_1_Self_Send_Check(CAN_FRAME*can_bms_1_frame);
+
+void Bms_1_Self_Send_Timeout(void);
+
+
+
+#endif
+

+ 319 - 0
Source/app_bms_2.c

@@ -0,0 +1,319 @@
+#include "common.h"
+#include "drv_can.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "app_can.h"
+#include "app.h"
+#include "app_bms_2.h"
+
+BMS_SELF_SEND_STATUS bms_2_self_ss;
+BMS_SELF_CUR_VOL_STATUS bms_2_cur_vol_ss;
+DELAY_COMMON bms_2_self_stimeout;
+
+void Can_Bms_2_Cur_Vol_Self_Send_Check(CAN_FRAME*can_bms_2_frame)
+{
+	uint16_t len;
+	uint8_t *buf = can_bms_2_frame->data;
+
+	
+	do
+	{
+		if(bms_2_cur_vol_ss.m_cur != sub_bms_info_2.packet_common.m_current/RESOLUTION_DELTA_50M)
+			break;
+		if(bms_2_cur_vol_ss.m_vol != sub_bms_info_2.packet_common.m_total_vol/RESOLUTION_DELTA_50M)
+			break;
+		
+		return;
+	}while(0);
+
+	bms_2_cur_vol_ss.m_cur = sub_bms_info_2.packet_common.m_current/RESOLUTION_DELTA_10M;
+	bms_2_cur_vol_ss.m_vol = sub_bms_info_2.packet_common.m_total_vol/RESOLUTION_DELTA_10M;
+	len = sizeof(bms_2_cur_vol_ss);
+	//
+	can_bms_2_frame->head.rsp = FRAME_PT_NO_RSP;
+	can_bms_2_frame->head.dest = CTR_ID;
+	can_bms_2_frame->head.sour = SELF_ID;
+	can_bms_2_frame->head.index = 1;
+	can_bms_2_frame->head.total = (len - 1)/8 + 1;
+	can_bms_2_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_bms_2_frame->len = len;
+	memcpy(buf,&bms_2_cur_vol_ss,len);
+	
+	bms_2_self_stimeout.set = 0;
+	bms_2_self_stimeout.count = 0;
+	g_event &= ~BMS_2_SELF_TIMEOUT_EVENT;
+	//
+	if(!Send_Data_Can(can_bms_2_frame,BMS_2_CUR_VOL_SELF))
+	{
+		//g_event |= BMS_2_RESEND_CMD_EVENT;
+		//return;
+	}
+
+	//
+	bms_2_cur_vol_ss.m_cur = sub_bms_info_2.packet_common.m_current/RESOLUTION_DELTA_50M;
+	bms_2_cur_vol_ss.m_vol = sub_bms_info_2.packet_common.m_total_vol/RESOLUTION_DELTA_50M;
+	
+}
+
+void Can_Bms_2_Self_Send_Check(CAN_FRAME*can_bms_2_frame)
+{
+	uint16_t len;
+	uint8_t *buf = can_bms_2_frame->data;
+
+	
+	do
+	{
+		if(bms_2_self_ss.m_percent != sub_bms_info_2.packet_common.m_percent)
+			break;
+		if(bms_2_self_ss.charge_flag != sub_bms_info_2.packet_common.charge_flag)
+			break;
+		if(bms_2_self_ss.work_status != sub_bms_info_2.packet_common.work_status)
+			break;
+		//if(bms_2_self_ss.bms_status != sub_bms_info_2.packet_common.bms_status)
+		//	break;
+		//Can_Bms_2_Cur_Vol_Self_Send_Check(can_bms_2_frame);
+		return;
+	}while(0);
+
+	bms_2_self_ss.m_percent = sub_bms_info_2.packet_common.m_percent;
+	bms_2_self_ss.charge_flag = sub_bms_info_2.packet_common.charge_flag;
+	bms_2_self_ss.work_status = sub_bms_info_2.packet_common.work_status;
+	len = sizeof(bms_2_self_ss);
+	//
+	can_bms_2_frame->head.rsp = FRAME_PT_NEED_RSP;
+	can_bms_2_frame->head.dest = CTR_ID;
+	can_bms_2_frame->head.sour = SELF_ID;
+	can_bms_2_frame->head.index = 1;
+	can_bms_2_frame->head.total = (len - 1)/8 + 1;
+	can_bms_2_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_bms_2_frame->len = len;
+	memcpy(buf,&bms_2_self_ss,len);
+	
+	bms_2_self_stimeout.set = 1;
+	bms_2_self_stimeout.count = 0;
+	//
+	if(!Send_Data_Can(can_bms_2_frame,BMS_2_SELF))
+	{
+		//g_event |= BMS_2_RESEND_CMD_EVENT;
+		//return;
+	}
+	
+}
+int8_t Handle_Can_Bms_2_CMD(CAN_FRAME*can_bms_2_frame)
+{
+	uint16_t key;
+
+	memcpy(&key,can_bms_2_frame->data,sizeof(key));
+
+	switch(key)
+	{
+		case KEY_BMS_2_COMMON:
+			break;
+		case KEY_BMS_2_READ_INFO:
+			break;
+		case KEY_BMS_2_READ_VER:
+			break;
+		case KEY_BMS_2_ALARM_TIMES:
+			break;
+		case KEY_BMS_2_ALARM_TIMES_1:
+			break;
+		case KEY_BMS_2_ALARM_TIMES_2:
+			break;
+		case KEY_BMS_2_CELL_VOL:
+			break;
+		case KEY_BMS_2_CELL_VOL_1:
+			break;
+		case KEY_BMS_2_CELL_VOL_2:
+			break;
+		case KEY_BMS_2_TEMP_OTHER:
+			break;
+		case KEY_BMS_2_SELF_UP:
+			bms_2_self_stimeout.set = 0;
+			return 0;	
+		default:
+			return 0;
+
+	}
+	
+	return 1;
+	
+}
+
+int8_t Rsp_Can_Bms_2_CMD(CAN_FRAME*can_bms_2_frame)
+{
+	uint16_t key,len;
+	uint8_t *buf = can_bms_2_frame->data,*bt;
+	uint16_t temp;
+
+	memcpy(&key,can_bms_2_frame->data,sizeof(key));
+
+	switch(key)
+	{
+		case KEY_BMS_2_COMMON:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			memcpy(&buf[len],&sub_bms_info_2.packet_common,sizeof(sub_bms_info_2.packet_common) - 1);
+			if(sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng)
+			{
+				if(sheng_yu_li_cheng.sy_percent_total == sub_bms_info_2.packet_common.m_percent)
+					buf[3] = sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng;
+				else
+					#if 0
+					//bang zi ce shi start
+					buf[3] = sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng*sub_bms_info_2.packet_common.m_percent/50;
+					//bang zi ce shi start
+					#else
+					{
+						if(Is_Sub_BMS_2_Normal())
+						{
+							temp = (uint8_t)(sub_bms_info_2.packet_common.m_percent*sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi/1000);
+							if(temp%10 >= 5)
+								buf[3] = temp/10 + 1;
+							else
+								buf[3] = temp/10;
+						}
+						else
+							buf[3] = 0;
+					}
+					#endif
+			}
+			len += sizeof(sub_bms_info_2.packet_common) - 1;
+			break;
+		case KEY_BMS_2_READ_INFO:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			memcpy(&buf[len],sub_bms_info_2.bat_dev_info.sn,sizeof(sub_bms_info_2.bat_dev_info.sn));
+			len += sizeof(sub_bms_info_2.bat_dev_info.sn);
+			break;
+		case KEY_BMS_2_READ_VER:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			memcpy(&buf[len],sub_bms_info_2.bat_dev_info.soft_ver,sizeof(sub_bms_info_2.bat_dev_info.soft_ver));
+			len += sizeof(sub_bms_info_2.bat_dev_info.soft_ver);
+			break;	
+		case KEY_BMS_2_ALARM_TIMES:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			//memcpy(&buf[len],&sub_bms_info_2.bat_times,sizeof(sub_bms_info_2.bat_times));
+			//len += sizeof(sub_bms_info_2.bat_times);
+			bt = (uint8_t*)(&sub_bms_info_2.bat_times);
+			memcpy(&buf[len],bt,14);
+			len += 14;
+			break;
+		case KEY_BMS_2_ALARM_TIMES_1:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_2.bat_times);
+			memcpy(&buf[len],&bt[14],16);
+			len += 16;
+			break;
+		case KEY_BMS_2_ALARM_TIMES_2:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_2.bat_times);
+			memcpy(&buf[len],&bt[30],12);
+			len += 12;
+			break;
+		case KEY_BMS_2_CELL_VOL:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_2.cell_vol);
+			memcpy(&buf[len],bt,13);
+			len += 13;
+			break;
+		case KEY_BMS_2_CELL_VOL_1:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_2.cell_vol);
+			memcpy(&buf[len],&bt[13],12);
+			len += 12;
+			break;
+		case KEY_BMS_2_CELL_VOL_2:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_2.cell_vol);
+			memcpy(&buf[len],&bt[25],6);
+			len += 6;
+			//
+			memset(&buf[len],0x00,6);
+			len += 6;
+			break;
+		case KEY_BMS_2_TEMP_OTHER:
+			if((can_bms_2_frame->head.rsp != FRAME_PT_NEED_RSP) || bms_2_self_stimeout.set)
+				return 1;
+			len = 2;
+			buf[len++] = 0;
+			bt = (uint8_t*)(&sub_bms_info_2.temp_other);
+			memcpy(&buf[len],bt,5);
+			len += 5;
+			break;
+		case KEY_BMS_2_SELF_UP:
+			return 0;
+		default:
+			return 0;
+	}
+	//
+	can_bms_2_frame->head.rsp = FRAME_PT_RSP;
+	can_bms_2_frame->head.dest = can_bms_2_frame->head.sour;
+	can_bms_2_frame->head.sour = SELF_ID;
+	can_bms_2_frame->head.index = 1;
+	can_bms_2_frame->head.total = (len - 1)/8 + 1;
+	can_bms_2_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_bms_2_frame->len = len;
+
+	//
+	if(!Send_Data_Can(can_bms_2_frame,BMS_2_RSP))
+	{
+		g_event |= BMS_2_RESEND_CMD_EVENT;
+		return 0;
+	}
+	
+	return 1;
+
+}
+
+
+void Bms_2_Self_Send_Timeout(void)
+{
+	if(bms_2_self_stimeout.set)
+	{
+		++bms_2_self_stimeout.count;
+		if(bms_2_self_stimeout.count >= 300)
+		{
+			memset(&bms_2_self_stimeout,0x00,sizeof(bms_2_self_stimeout));
+			g_event |= BMS_2_SELF_TIMEOUT_EVENT;
+		}
+		else if(bms_2_self_stimeout.count == 200)
+			g_event |= BMS_2_SELF_TIMEOUT_EVENT;
+		else if(bms_2_self_stimeout.count == 100)
+			g_event |= BMS_2_SELF_TIMEOUT_EVENT;
+	}
+	else
+		bms_2_self_stimeout.count = 0;
+	
+}
+
+

+ 41 - 0
Source/app_bms_2.h

@@ -0,0 +1,41 @@
+#ifndef APP_BMS_2_H
+#define APP_BMS_2_H
+
+
+#define KEY_BMS_2_COMMON            (0x3200)
+#define KEY_BMS_2_BOND  			(0x3201)
+#define KEY_BMS_2_UNBOND            (0x3202)
+#define KEY_BMS_2_PAIR              (0x3203)
+#define KEY_BMS_2_UPDATE_PAIR       (0x3204)
+#define KEY_BMS_2_READ_INFO         (0x3205)
+#define KEY_BMS_2_ALARM_TIMES       (0x3206)
+#define KEY_BMS_2_CELL_VOL          (0x3207)
+#define KEY_BMS_2_BAT_VOL           (0x3208)
+#define KEY_BMS_2_CHARGER_ONOFF     (0x3209)
+#define KEY_BMS_2_READ_BAT          (0x320A)
+#define KEY_BMS_2_OPEN_FET          (0x320B)
+#define KEY_BMS_2_READ_VER          (0x320C)
+#define KEY_BMS_2_ALARM_TIMES_1     (0x320D)
+#define KEY_BMS_2_ALARM_TIMES_2     (0x320E)
+#define KEY_BMS_2_CELL_VOL_1        (0x320F)
+#define KEY_BMS_2_CELL_VOL_2        (0x3210)
+#define KEY_BMS_2_TEMP_OTHER        (0x3211)
+#define KEY_BMS_2_TEMP_OTHER_1      (0x3212)
+#define KEY_BMS_2_TEMP_OTHER_2      (0x3213)
+#define KEY_BMS_2_SELF_UP           (0x3281)
+#define KEY_BMS_2_CUR_VOL_SELF_UP   (0x3282)
+
+extern BMS_SELF_SEND_STATUS bms_2_self_ss;
+extern BMS_SELF_CUR_VOL_STATUS bms_2_cur_vol_ss;
+extern DELAY_COMMON bms_2_self_stimeout;
+
+int8_t Handle_Can_Bms_2_CMD(CAN_FRAME*can_bms_2_frame);
+
+int8_t Rsp_Can_Bms_2_CMD(CAN_FRAME*can_bms_2_frame);
+
+void Can_Bms_2_Self_Send_Check(CAN_FRAME*can_bms_2_frame);
+
+void Bms_2_Self_Send_Timeout(void);
+	
+#endif
+

+ 441 - 0
Source/app_can.c

@@ -0,0 +1,441 @@
+#include "common.h"
+#include "drv_can.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "app_can.h"
+#include "app.h"
+#include "measure_temprature.h"
+#include "measure_vol.h"
+#include "app_adas.h"
+#include "app_end_ctr.h"
+#include "app_bms_1.h"
+#include "app_bms_2.h"
+
+//can
+static uint8_t app_can_buf[CAN_TX_BUF_MAX];
+CAN_FRAME app_can_frame;
+
+static uint8_t app_can_bms_1_buf[CAN_BMS_TX_BUF_MAX];
+CAN_FRAME app_can_bms_1_frame;
+
+static uint8_t app_can_bms_2_buf[CAN_BMS_TX_BUF_MAX];
+CAN_FRAME app_can_bms_2_frame;
+
+static uint8_t app_can_ctr_buf[CAN_CTR_TX_BUF_MAX];
+CAN_FRAME app_can_ctr_frame;
+
+static uint8_t app_can_adas_buf[CAN_ADAS_TX_BUF_MAX];
+CAN_FRAME app_can_adas_frame;
+
+uint8_t mode = 0;
+uint8_t adjust_step = 0;
+	
+int8_t Resend_can_bms_1_frame(void)
+{
+	return Send_Data_Can(&app_can_bms_1_frame,BMS_1_RESEND);
+}
+
+int8_t Resend_can_bms_2_frame(void)
+{
+	return Send_Data_Can(&app_can_bms_2_frame,BMS_2_RESEND);
+}
+
+int8_t Resend_can_ctr_frame(void)
+{
+	return Send_Data_Can(&app_can_ctr_frame,CTR_RESEND);
+}
+
+int8_t Resend_can_adas_frame(void)
+{
+	return Send_Data_Can(&app_can_adas_frame,ADAS_RESEND);
+}
+
+
+int8_t Timeout_Resend_can_bms_1_frame(void)
+{
+	return Send_Data_Can(&app_can_bms_1_frame,TIMEOUT_BMS_1_RESEND);
+}
+
+int8_t Timeout_Resend_can_bms_2_frame(void)
+{
+	return Send_Data_Can(&app_can_bms_2_frame,TIMEOUT_BMS_2_RESEND);
+}
+
+int8_t Timeout_Resend_can_ctr_frame(void)
+{
+	return Send_Data_Can(&app_can_ctr_frame,TIMEOUT_CTR_RESEND);
+}
+
+int8_t Timeout_Resend_can_adas_frame(void)
+{
+	return Send_Data_Can(&app_can_adas_frame,TIMEOUT_ADAS_RESEND);
+}
+
+void ADAS_Self_Send_Up(void)
+{
+	Can_ADAS_Self_Send(&app_can_adas_frame);
+}
+
+void Check_Can_Self_Send_Status(void)
+{
+	Can_Bms_1_Self_Send_Check(&app_can_bms_1_frame);
+	Can_Bms_2_Self_Send_Check(&app_can_bms_2_frame);
+	Can_End_Ctr_Self_Send_Check(&app_can_ctr_frame);
+	
+}
+
+static int8_t Handle_Can_CMD(CAN_FRAME*can_frame)
+{
+	uint8_t key = can_frame->data[1];
+
+	switch(key)
+	{
+		case 0x31:
+			memcpy(&app_can_bms_1_frame.head,&can_frame->head,sizeof(can_frame->head));
+			app_can_bms_1_frame.len = can_frame->len;
+			memcpy(app_can_bms_1_frame.data,can_frame->data,app_can_bms_1_frame.len);
+			
+			if(!Handle_Can_Bms_1_CMD(&app_can_bms_1_frame))
+				return 0;
+			if(!Rsp_Can_Bms_1_CMD(&app_can_bms_1_frame))
+				return 0;
+			break;
+		case 0x32:
+			memcpy(&app_can_bms_2_frame.head,&can_frame->head,sizeof(can_frame->head));
+			app_can_bms_2_frame.len = can_frame->len;
+			memcpy(app_can_bms_2_frame.data,can_frame->data,app_can_bms_2_frame.len);
+			
+			if(!Handle_Can_Bms_2_CMD(&app_can_bms_2_frame))
+				return 0;
+			if(!Rsp_Can_Bms_2_CMD(&app_can_bms_2_frame))
+				return 0;
+			break;
+		case 0x48:
+		case 0x42:
+		case 0x43:
+			memcpy(&app_can_ctr_frame.head,&can_frame->head,sizeof(can_frame->head));
+			app_can_ctr_frame.len = can_frame->len;
+			memcpy(app_can_ctr_frame.data,can_frame->data,app_can_ctr_frame.len);
+			
+			if(!Handle_Can_Ctr_CMD(&app_can_ctr_frame))
+				return 0;
+			if(!Rsp_Can_Ctr_CMD(&app_can_ctr_frame))
+				return 0;
+			break;
+		case 0x52:
+			memcpy(&app_can_adas_frame.head,&can_frame->head,sizeof(can_frame->head));
+			app_can_adas_frame.len = can_frame->len;
+			memcpy(app_can_adas_frame.data,can_frame->data,app_can_adas_frame.len);
+#if 0
+			if(!Handle_Can_Adas_CMD(&app_can_adas_frame))
+				return 0;
+			if(!Rsp_Can_Adas_CMD(&app_can_adas_frame))
+				return 0;
+#endif
+			break;
+		default:
+			break;
+	}
+	
+	return 1;
+	
+}
+
+int8_t Handle_Can_Data(void)
+{
+	uint8_t len = Get_Data_Can(&app_can_frame);
+
+	if(len == 0)
+		return 0;
+
+	
+	if((mode == 1)&&(app_can_buf[0] == 0xFF) &&(app_can_buf[1] == 0xFF))
+	{
+		len = 2;
+		adjust_step = app_can_buf[len++];
+		
+		switch(adjust_step)
+		{	
+			/*case 0:
+				break;
+			case OPERATE_UN_INPUT:
+				memcpy(&Un,&app_can_buf[len],sizeof(Un));
+				break;
+			case OPERATE_UNIBA_INPUT:
+				memcpy(&Iba,&app_can_buf[len],sizeof(Iba));
+				break;
+			case OPERATE_UNIBB_INPUT:
+				memcpy(&Ibb,&app_can_buf[len],sizeof(Ibb));
+				break;
+			case OPERATE_POWERA_INPUT:
+				memcpy(&tPowerA,&app_can_buf[len],sizeof(tPowerA));
+				break;
+			case OPERATE_POWERB_INPUT:
+				memcpy(&tPowerB,&app_can_buf[len],sizeof(tPowerB));
+				break;*/
+			case OPERATE_READ_DATA:
+				printf("return:%d\r\n",Battery_CB_Switch(app_can_buf[len]));
+				break;
+			case OPERATE_POWER_DATA:
+				printf("sub_bms_1_lt_state:%d\r\n",sub_bms_1_lt_state);
+				printf("rs485_connect_1:%d\r\n",sub_bms_info_1.rs485_connect);
+				printf("rs485_time_out_1:%d\r\n",sub_bms_info_1.rs485_time_out);
+				printf("yjkxslc_1:%d\r\n",sub_bms_info_1.packet_common.yjkxslc);
+				printf("m_percent_1:%d\r\n",sub_bms_info_1.packet_common.m_percent);
+				printf("yjcdwcsj_1:%d\r\n",sub_bms_info_1.packet_common.yjcdwcsj);
+				printf("charge_flag_1:%d\r\n",sub_bms_info_1.packet_common.charge_flag);
+				printf("m_current_1:%dma\r\n",sub_bms_info_1.packet_common.m_current);
+				printf("m_total_vol_1:%umv\r\n",sub_bms_info_1.packet_common.m_total_vol);
+				printf("bms_temp_1:%d\r\n",sub_bms_info_1.packet_common.bms_temp);
+				printf("work_status_1:%x\r\n",sub_bms_info_1.packet_common.work_status);
+				printf("banlance_cell_1:%x\r\n",sub_bms_info_1.packet_common.banlance_cell);
+				printf("bms_status_1:%x\r\n",sub_bms_info_1.packet_common.bms_status);
+
+				memcpy(app_can_buf,sub_bms_info_1.bat_dev_info.sn,SERIAL_NUM_SIZE);
+				app_can_buf[SERIAL_NUM_SIZE] = 0;
+				printf("sn_1:%s\r\n",app_can_buf);
+
+				memcpy(app_can_buf,sub_bms_info_1.bat_dev_info.soft_ver,SOFTWARE_SIZE);
+				app_can_buf[SOFTWARE_SIZE] = 0;
+				printf("soft_ver_1:%s\r\n",app_can_buf);
+
+				printf("dcsmxs_1:%d\r\n",sub_bms_info_1.bat_times.dcsmxs);
+				printf("Charge_Num_1:%lu\r\n",sub_bms_info_1.bat_times.charge_times);
+				printf("OvCh_vol_Num_1:%lu\r\n",sub_bms_info_1.bat_times.charge_over_vol_times);
+				printf("OvDis_vol_Num_1:%lu\r\n",sub_bms_info_1.bat_times.discharge_under_vol_times);
+				printf("OvCharge_cur_Num_1:%lu\r\n",sub_bms_info_1.bat_times.charge_over_cur_times);
+				printf("OvDischarge_cur_Num_1:%lu\r\n",sub_bms_info_1.bat_times.discharge_under_cur_times);
+				printf("Short_Num_1:%lu\r\n",sub_bms_info_1.bat_times.short_times);
+				printf("UdTempeCh_Num_1:%lu\r\n",sub_bms_info_1.bat_times.charge_under_temp_times);
+				printf("UdTempeDis_Num_1:%lu\r\n",sub_bms_info_1.bat_times.discharge_under_temp_times);
+				printf("OvTempeCh_Num_1:%lu\r\n",sub_bms_info_1.bat_times.charge_over_temp_times);
+				printf("OvTempeDis_Num_1:%lu\r\n",sub_bms_info_1.bat_times.discharge_over_temp_times);
+
+
+				
+				break;
+				
+			case OPERATE_ENERGY_DATA: //0x0C
+				printf("sub_bms_2_lt_state:%d\r\n",sub_bms_2_lt_state);
+				
+				printf("rs485_connect_2:%d\r\n",sub_bms_info_2.rs485_connect);
+				printf("rs485_time_out_2:%d\r\n",sub_bms_info_2.rs485_time_out);
+				printf("yjkxslc_2:%d\r\n",sub_bms_info_2.packet_common.yjkxslc);
+				printf("m_percent_2:%d\r\n",sub_bms_info_2.packet_common.m_percent);
+				printf("yjcdwcsj_2:%d\r\n",sub_bms_info_2.packet_common.yjcdwcsj);
+				printf("charge_flag_2:%d\r\n",sub_bms_info_2.packet_common.charge_flag);
+				printf("m_current_2:%dma\r\n",sub_bms_info_2.packet_common.m_current);
+				printf("m_total_vol_2:%umv\r\n",sub_bms_info_2.packet_common.m_total_vol);
+				printf("bms_temp_2:%d\r\n",sub_bms_info_2.packet_common.bms_temp);
+				printf("work_status_2:%x\r\n",sub_bms_info_2.packet_common.work_status);
+				printf("banlance_cell_2:%x\r\n",sub_bms_info_2.packet_common.banlance_cell);
+				printf("bms_status_2:%x\r\n",sub_bms_info_2.packet_common.bms_status);
+
+				memcpy(app_can_buf,sub_bms_info_2.bat_dev_info.sn,SERIAL_NUM_SIZE);
+				app_can_buf[SERIAL_NUM_SIZE] = 0;
+				printf("sn_2:%s\r\n",app_can_buf);
+
+				memcpy(app_can_buf,sub_bms_info_2.bat_dev_info.soft_ver,SOFTWARE_SIZE);
+				app_can_buf[SOFTWARE_SIZE] = 0;
+				printf("soft_ver_2:%s\r\n",app_can_buf);
+
+				printf("dcsmxs_2:%d\r\n",sub_bms_info_2.bat_times.dcsmxs);
+				printf("Charge_Num_2:%lu\r\n",sub_bms_info_2.bat_times.charge_times);
+				printf("OvCh_vol_Num_2:%lu\r\n",sub_bms_info_2.bat_times.charge_over_vol_times);
+				printf("OvDis_vol_Num_2:%lu\r\n",sub_bms_info_2.bat_times.discharge_under_vol_times);
+				printf("OvCharge_cur_Num_2:%lu\r\n",sub_bms_info_2.bat_times.charge_over_cur_times);
+				printf("OvDischarge_cur_Num_2:%lu\r\n",sub_bms_info_2.bat_times.discharge_under_cur_times);
+				printf("Short_Num_2:%lu\r\n",sub_bms_info_2.bat_times.short_times);
+				printf("UdTempeCh_Num_2:%lu\r\n",sub_bms_info_2.bat_times.charge_under_temp_times);
+				printf("UdTempeDis_Num_2:%lu\r\n",sub_bms_info_2.bat_times.discharge_under_temp_times);
+				printf("OvTempeCh_Num_2:%lu\r\n",sub_bms_info_2.bat_times.charge_over_temp_times);
+				printf("OvTempeDis_Num_2:%lu\r\n",sub_bms_info_2.bat_times.discharge_over_temp_times);
+				break;
+				
+			case OPERATE_DEEP_DATA://0x0D
+				printf("ctr_temperature[0]:%d\r\n",ctr_temperature[0]);
+				printf("ctr_temperature[1]:%d\r\n",ctr_temperature[1]);
+				printf("Batter_Vol:%lu\r\n",Measure_Vol());
+				
+				printf("cb_val_last:%d\r\n",*(uint8_t*)(&cb_val_last));
+				printf("cb_operate_state:%d\r\n",cb_operate_state);
+				break;
+				
+			case OPERATE_ERASE_RECORD_TIMES://0x0E
+				if(app_can_buf[len])
+				{
+					sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+					sub_bms_info_1.sub_bms_cmd.param = 0x03;
+				}
+				else
+				{
+					sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+					sub_bms_info_1.sub_bms_cmd.param = 0x00;
+				}
+				printf("BMS_1:%d\r\n",sub_bms_info_1.sub_bms_cmd.param);
+				break;
+				
+			case OPERATE_RECORD_DATA://0x0F
+				if(app_can_buf[len])
+				{
+					sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+					sub_bms_info_2.sub_bms_cmd.param = 0x03;
+				}
+				else
+				{
+					sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+					sub_bms_info_2.sub_bms_cmd.param = 0x00;
+				}
+				printf("BMS_2:%d\r\n",sub_bms_info_2.sub_bms_cmd.param);
+				break;
+				
+			case OPERATE_LOW_SHAKE_DATA:
+				
+
+				
+				break;
+
+			case OPERATE_MEASURE_LOW_VOL:
+				
+				break;
+			case OPERATE_TIMES_DATA:
+				
+				
+				break;
+			case 0x13:
+				
+				break;
+			case 0x14:
+				printf("mode:%d\r\n",mode);
+				
+				break;	
+			case 0x30: // FF 0X30 LEN ADDR0 ADDR1 DATA
+				
+				break;
+			case 0x31: // FF 0X31 LEN ADDR0 ADDR1 DATA
+				
+				break;
+			default: break;
+		}
+		return 1;
+	}
+	else if(memcmp(app_can_buf,"mode",4) == 0)
+	{
+		if(memcmp(&app_can_buf[4],"test",4) == 0)
+		{
+			mode = 1;
+			printf("test success!");
+		}
+		else if(memcmp(&app_can_buf[4],"jiaozhun",8) == 0)
+		{
+			
+			mode = 4;
+			printf("jiaozhun success!");
+		}
+		else if(memcmp(&app_can_buf[4],"peizhi",6) == 0)
+		{
+			mode = 2;
+			printf("peizhi success!");
+		}
+		else if(memcmp(&app_can_buf[4],"ceshi",5) == 0)
+		{
+			mode = 3;
+			printf("ceshi success!");
+		}
+		else if(memcmp(&app_can_buf[4],"tuichu",6) == 0)
+		{
+			mode = 0;
+			printf("tuichu success!");
+		}
+		else if(memcmp(&app_can_buf[4],"cachu",5) == 0)
+		{
+			printf("cachu success!");
+		}
+		else
+			return 0;	
+
+		return 1;
+	}
+	else if(mode == 2&&app_can_buf[0] == 0xFC && app_can_buf[1] == 0xFC)
+	{
+	}
+	else if(mode == 3&&app_can_buf[0] == 0xFE && app_can_buf[1] == 0xFE)
+	{
+	}
+	else if(mode == 4&&app_can_buf[0] == 0xFD && app_can_buf[1] == 0xFD)
+	{
+
+	}
+	else
+	{
+		mode = 0;
+		Handle_Can_CMD(&app_can_frame);
+		return 1;
+	}
+	/**/
+
+	if(!Send_Data_Can(&app_can_frame,OTHER_SEND))
+		return 0;
+
+	return 1;
+	
+}
+
+
+void Can_Com_Initial(void)
+{
+	CAN_Config();
+
+	memset(app_can_buf,0x00,sizeof(app_can_buf));
+	memset(&app_can_frame,0x00,sizeof(app_can_frame));
+	app_can_frame.data = app_can_buf;
+
+	memset(app_can_bms_1_buf,0x00,sizeof(app_can_bms_1_buf));
+	memset(&app_can_bms_1_frame,0x00,sizeof(app_can_bms_1_frame));
+	app_can_bms_1_frame.data = app_can_bms_1_buf;
+
+	memset(app_can_bms_2_buf,0x00,sizeof(app_can_bms_2_buf));
+	memset(&app_can_bms_2_frame,0x00,sizeof(app_can_bms_2_frame));
+	app_can_bms_2_frame.data = app_can_bms_2_buf;
+	
+	memset(app_can_ctr_buf,0x00,sizeof(app_can_ctr_buf));
+	memset(&app_can_ctr_frame,0x00,sizeof(app_can_ctr_frame));
+	app_can_ctr_frame.data = app_can_ctr_buf;
+	
+	memset(app_can_adas_buf,0x00,sizeof(app_can_adas_buf));
+	memset(&app_can_adas_frame,0x00,sizeof(app_can_adas_frame));
+	app_can_adas_frame.data = app_can_adas_buf;
+
+	memset(&bms_1_self_ss,0x00,sizeof(bms_1_self_ss));
+	bms_1_self_ss.key = KEY_BMS_1_SELF_UP;
+	memset(&bms_1_cur_vol_ss,0x00,sizeof(bms_1_cur_vol_ss));
+	bms_1_cur_vol_ss.key = KEY_BMS_1_CUR_VOL_SELF_UP;
+
+	memset(&bms_2_self_ss,0x00,sizeof(bms_2_self_ss));
+	bms_2_self_ss.key = KEY_BMS_2_SELF_UP;
+	memset(&bms_2_cur_vol_ss,0x00,sizeof(bms_2_cur_vol_ss));
+	bms_2_cur_vol_ss.key = KEY_BMS_2_CUR_VOL_SELF_UP;
+	
+	memset(&end_ctr_self_ss,0x00,sizeof(end_ctr_self_ss));
+	end_ctr_self_ss.key = KEY_END_CTR_SELF_UP;
+	memset(&end_ctr_self_ss_new,0x00,sizeof(end_ctr_self_ss_new));
+	end_ctr_self_ss_new.key = KEY_END_CTR_SELF_UP;
+	memset(&end_ctr_rsp,0x00,sizeof(end_ctr_rsp));
+	end_ctr_rsp.key = KEY_END_CTR_COMMON;
+	
+}
+
+void Can_Test(void)
+{
+	app_can_frame.head.rsp = FRAME_PT_NEED_RSP;
+	app_can_frame.head.dest = CTR_ID;
+	app_can_frame.head.sour = SELF_ID;
+	app_can_frame.head.index = 1;
+	app_can_frame.head.total = 2;
+	app_can_frame.head.pro   =FRAME_PRO_D;
+	//
+	app_can_frame.len = 15;
+	memset(app_can_frame.data,0xCC,15);
+	Send_Data_Can(&app_can_frame,CAN_TEST);
+}
+

+ 93 - 0
Source/app_can.h

@@ -0,0 +1,93 @@
+#ifndef APP_CAN_H
+#define APP_CAN_H
+
+enum
+{
+	OPERATE_GND_INPUT = 1,
+	OPERATE_NOR_INPUT,	
+	OPERATE_UN_INPUT,
+	OPERATE_UNIBA_INPUT,
+	OPERATE_UNIBB_INPUT,
+	
+	OPERATE_POWERA_INPUT,
+	OPERATE_POWERB_INPUT,
+	
+	OPERATE_UNIBA0_INPUT,
+	OPERATE_UNIBB0_INPUT,
+	OPERATE_READ_DATA,//0X0A
+	OPERATE_POWER_DATA,
+	OPERATE_ENERGY_DATA,
+
+	OPERATE_DEEP_DATA,
+	
+	OPERATE_ERASE_RECORD_TIMES,// 0X0E
+
+	OPERATE_RECORD_DATA,//0x0F
+
+	OPERATE_LOW_SHAKE_DATA,//0x10
+
+	OPERATE_MEASURE_LOW_VOL,//0x11
+
+	OPERATE_TIMES_DATA,//0X12
+	
+	OPERATE_MAX 
+};
+
+#define CAN_BMS_TX_BUF_MAX  (CAN_TX_BUF_MAX >> 0)
+#define CAN_CTR_TX_BUF_MAX  (CAN_TX_BUF_MAX >> 0)
+#define CAN_ADAS_TX_BUF_MAX  (CAN_TX_BUF_MAX >> 2)
+
+#pragma  pack (push,1)  
+typedef struct
+{
+	uint16_t key;
+	
+	uint8_t m_percent;
+	
+	uint8_t charge_flag;
+
+	uint16_t work_status;
+
+	uint8_t bms_status;
+}BMS_SELF_SEND_STATUS;
+#define RESOLUTION_DELTA_50M    (50)
+#define RESOLUTION_DELTA_10M    (10)
+typedef struct
+{
+	uint16_t key;
+	
+	int16_t m_cur;
+	
+	uint16_t m_vol;
+
+}BMS_SELF_CUR_VOL_STATUS;
+#pragma pack(pop)
+
+void Can_Com_Initial(void);
+
+int8_t Handle_Can_Data(void);
+
+void Can_Test(void);
+
+int8_t Resend_can_bms_1_frame(void);
+
+int8_t Resend_can_bms_2_frame(void);
+
+int8_t Resend_can_ctr_frame(void);
+
+int8_t Resend_can_adas_frame(void);
+
+int8_t Timeout_Resend_can_bms_1_frame(void);
+
+int8_t Timeout_Resend_can_bms_2_frame(void);
+
+int8_t Timeout_Resend_can_ctr_frame(void);
+
+int8_t Timeout_Resend_can_adas_frame(void);
+
+void ADAS_Self_Send_Up(void);
+
+void Check_Can_Self_Send_Status(void);
+
+#endif
+

+ 873 - 0
Source/app_end_ctr.c

@@ -0,0 +1,873 @@
+#include "common.h"
+#include "drv_io.h"
+#include "drv_can.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "app_can.h"
+#include "app.h"
+#include "app_end_ctr.h"
+#include "measure_temprature.h"
+#include "hardware_test.h"
+#include "drv_io.h"
+
+END_CTR_SELF_SEND_STATUS end_ctr_self_ss;
+END_CTR_SELF_SEND_STATUS end_ctr_self_ss_new;
+END_CTR_SELF_SEND_STATUS end_ctr_rsp;
+
+DELAY_COMMON end_ctr_self_stimeout;
+
+uint8_t Get_QD_State(void)
+{
+	return end_ctr_self_ss_new.qd_sta;
+}
+
+uint8_t Is_Soak(void)
+{
+	return end_ctr_self_ss_new.soak_sta;
+}
+
+void Shield_XL_Timeout(void)
+{
+	if(shield_xl.set)
+	{
+		if(++shield_xl.count >= SHIELD_XL_TIME)
+		{
+			memset(&shield_xl,0x00,sizeof(shield_xl));
+		}
+	}
+}
+
+void Can_End_Ctr_Self_Send_Check(CAN_FRAME*can_ctr_frame)
+{
+	uint16_t len;
+	uint8_t *buf = can_ctr_frame->data;
+
+	if(!memcmp(&end_ctr_self_ss,&end_ctr_self_ss_new,sizeof(END_CTR_SELF_SEND_STATUS)))
+		return;
+	
+	memcpy(&end_ctr_self_ss,&end_ctr_self_ss_new,sizeof(END_CTR_SELF_SEND_STATUS));
+	
+	len = sizeof(end_ctr_self_ss);
+	//
+	can_ctr_frame->head.rsp = FRAME_PT_NEED_RSP;
+	can_ctr_frame->head.dest = CTR_ID;
+	can_ctr_frame->head.sour = SELF_ID;
+	can_ctr_frame->head.index = 1;
+	can_ctr_frame->head.total = (len - 1)/8 + 1;
+	can_ctr_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_ctr_frame->len = len;
+	memcpy(buf,&end_ctr_self_ss,len);
+	
+	end_ctr_self_stimeout.set = 1;
+	end_ctr_self_stimeout.count = 0;
+	//
+	if(!Send_Data_Can(can_ctr_frame,CTR_SELF))
+	{
+		//g_event |= END_CTR_RESEND_CMD_EVENT;
+		//return;
+	}
+	
+}
+
+#ifdef CONFIG_CAN_IAP
+void qws_iap_fmc_flag_clear(void)
+{
+	fmc_flag_clear(FMC_FLAG_BANK0_PGERR | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_END);
+}
+
+void qws_iap_write_magic(uint32_t magic)
+{
+	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	uint32_t address = 0x08000000 + (capacity - 1024);
+	uint32_t length, checksum, value;
+
+	value = REG32(address + 8);
+	if (magic == value) {
+		return;
+	}
+
+	length = REG32(address);
+	checksum = REG32(address + 4);
+
+	fmc_unlock();
+
+	if (value != 0xFFFFFFFF) {
+		qws_iap_fmc_flag_clear();
+		fmc_page_erase(address);
+
+		qws_iap_fmc_flag_clear();
+		fmc_word_program(address, length);
+
+		qws_iap_fmc_flag_clear();
+		fmc_word_program(address + 4, checksum);
+	}
+
+	if (magic != 0xFFFFFFFF) {
+		qws_iap_fmc_flag_clear();
+		fmc_word_program(address + 8, magic);
+	}
+
+	fmc_lock();
+}
+
+void qws_iap_reboot(void)
+{
+	qws_iap_write_magic(0xFFFFFFFF);
+	__set_FAULTMASK(1);
+	NVIC_SystemReset();
+}
+
+uint8_t qws_iap_read_string(uint8_t *buff)
+{
+	uint32_t address = ((uint32_t) buff[4]) << 16 | ((uint32_t) buff[3]) << 8 | buff[2];
+	const char *text = (const char *) (0x08000000 + address);
+	int length = strlen(text);
+
+	if (length > 250) {
+		length = 250;
+	}
+
+	buff[5] = buff[4];
+	buff[4] = buff[3];
+	buff[3] = buff[2];
+	buff[2] = 0x00;
+
+	memcpy(buff + 6, text, length);
+
+	return length + 6;
+}
+#endif
+
+
+int8_t Handle_Can_Ctr_CMD(CAN_FRAME*can_ctr_frame)
+{
+	uint16_t key;
+	uint8_t *buf = can_ctr_frame->data;
+
+	memcpy(&key,can_ctr_frame->data,sizeof(key));
+
+	switch(key)
+	{
+		case KEY_END_CTR_COMMON:
+			soak_dec_delay.enable = (buf[2]&0x01);
+			break;
+		case KEY_END_CTR_SWI_BAT:	
+			break;
+		case KEY_END_CTR_BAT_INT_EN:
+			is_intelligent = buf[2];
+			break;
+		case KEY_END_CTR_BAT_INT_PRE:
+			if(buf[2] == 1)
+				CB_OPERATE_PRECEDENCE_Config = PRE_SERIES;
+			else if(buf[2] == 2)
+				CB_OPERATE_PRECEDENCE_Config = PRE_PARRALLEL;
+			else
+				return 0;
+			break;
+		case KEY_END_CTR_SOFT_WARE:	
+			break;
+		case KEY_END_CTR_SN:	
+			break;
+		case KEY_END_CTR_WRITER_SN:	
+			Writer_SN(&buf[2]);
+			break;
+		case KEY_END_CTR_BAT_UPDATE_REQ:		
+			break;
+		case KEY_END_CTR_BAT_UPDATE:
+			break;
+		case KEY_END_CTR_BAT_UPDATE_EXIT:
+			break;
+			
+		case KEY_END_CTR_DAN_CI_LI_CHENG:
+			memcpy(&sheng_yu_li_cheng.sy_dan_ci_li_cheng_temp,&buf[2],sizeof(sheng_yu_li_cheng.sy_dan_ci_li_cheng_temp));
+			break;
+		case KEY_END_CTR_ZHEN_JI_CE_SHI:
+			break;
+		case KEY_END_CTR_QD:
+			if(work_normal == 1)
+			{
+				switch(buf[2])
+				{
+					case 0:
+						//QD_Enable(0);
+						//ACC2_Enable(0);
+						QD_Enable_From(0,2);
+						serise_low_enable = 0;
+						break;
+					case 1:
+						//QD_Enable(1);
+						QD_Enable_From(1,3);
+						if(ACC2_Is_On() == 0)
+							ACC2_Enable(1);
+						break;
+					default:
+						return 0;
+				}
+				delay_1ms(10);
+			}
+			break;
+		case KEY_END_CTR_LOCK:
+			switch(buf[2])
+			{
+				case 0:
+					Lock_Enable(0);
+					break;
+				case 1:
+					Lock_Enable(1);
+					break;
+				default:
+					return 0;
+			}
+			
+			break;
+		case KEY_END_CTR_L_R_LIGHT:
+			
+			if(buf[2] == 0)
+			{
+				Left_Light_Enable(0);
+				left_light_delay.set = 0;
+				left_light_delay.count = 0;
+			}
+			if(buf[2] == 1)
+			{
+				Left_Light_Enable(1);
+			}
+			if(buf[2] == 2)
+			{
+				Left_Light_Enable(1);
+				left_light_delay.set = 1;
+				left_light_delay.count = 0;
+			}
+
+			if(buf[2] == 3)
+			{
+				Left_Light_Enable(0);
+				left_light_delay.set = 1;
+				left_light_delay.count = 600;
+			}
+			
+			if(buf[3] == 0)
+			{
+				Right_Light_Enable(0);
+				right_light_delay.set = 0;
+				right_light_delay.count = 0;
+			}
+			if(buf[3] == 1)
+			{
+				Right_Light_Enable(1);
+				
+			}
+			if(buf[3] == 2)
+			{
+				Right_Light_Enable(1);
+				right_light_delay.set = 1;
+				right_light_delay.count = 0;
+			}
+
+			if(buf[3] == 3)
+			{
+				Right_Light_Enable(0);
+				right_light_delay.set = 1;
+				right_light_delay.count = 600;
+			}
+			break;
+		case KEY_END_CTR_CARPET_LIGHT:
+			switch(buf[2])
+			{
+				case 0:
+					Carpet_Light_Enable(0);
+					break;
+				case 1:
+					Carpet_Light_Enable(1);
+					break;
+				default:
+					return 0;
+			}
+			break;
+		case KEY_END_CTR_TAIL_LIGHT:
+			switch(buf[2])
+			{
+				case 0:				
+					Tail_Light_Enable(0);	
+					break;
+				case 1:
+					Tail_Light_Enable(1);
+					break;
+				default:
+					return 0;
+			}
+			break;
+		case KEY_END_CTR_ACC12:
+
+			if(work_normal == 1)
+			{
+				switch(buf[2])
+				{
+					case 0:
+						if(QD_Dect() == 0)
+						{
+							ACC2_Enable(0);
+						}
+						break;
+					case 1:
+						if(ACC2_Is_On() == 0)
+							ACC2_Enable(1);		
+						break;
+					default:
+						return 0;
+				}
+				delay_1ms(10);
+			}
+		
+			break;
+		case KEY_END_CTR_ACC12_TEST:
+			if(work_normal == 1)
+			{
+				bms_1_test_define_error = buf[2];
+				bms_2_test_define_error = buf[3];
+			}
+			break;
+		case KEY_END_CTR_ACC12_TEST_1:
+			switch(buf[2])
+			{
+				case 0:
+					//if(QD_Dect() == 0)
+					{
+						ACC2_Enable(0);
+					}
+					break;
+				case 1:
+					if(ACC2_Is_On() == 0)
+						ACC2_Enable(1);		
+					break;
+				default:
+					return 0;
+			}
+			delay_1ms(10);
+			break;
+		case KEY_END_CTR_HEART_TICK:
+			break;
+		case KEY_END_CTR_SELF_UP:
+			end_ctr_self_stimeout.set = 0;
+			return 0;
+#ifdef CONFIG_CAN_IAP
+		case 0x42F0:
+			qws_iap_reboot();
+			return 0;
+
+		case 0x42F5:
+		case 0x42F6:
+		case 0x42F8:
+			break;
+#endif
+		default:
+			return 0;
+
+	}
+	
+	return 1;
+	
+}
+
+int8_t Rsp_Can_Ctr_CMD(CAN_FRAME*can_ctr_frame)
+{
+	uint16_t key,len;
+	uint8_t *buf = can_ctr_frame->data;
+	uint8_t temp = 0,rtn = 0;
+	
+	memcpy(&key,can_ctr_frame->data,sizeof(key));
+
+	switch(key)
+	{
+		case KEY_END_CTR_COMMON:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			end_ctr_rsp.key = KEY_END_CTR_COMMON;
+			end_ctr_rsp.op_result = 0;
+			len = sizeof(end_ctr_rsp);
+			memcpy(buf,&end_ctr_rsp,len);
+			
+			buf[len++] = QD_switch_from;
+			buf[len++] = power_switch_from;
+			buf[len++] = (uint8_t)utc_seconds;
+			buf[len++] = (uint8_t)(utc_seconds >> 8);
+			
+			break;
+		case KEY_END_CTR_SWI_BAT:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			
+			if(is_intelligent)
+			{
+				buf[len++] = 0;
+				buf[len++] = CB_BAT_NO;
+			}
+			else
+			{
+				if(buf[len] > CB_BAT_NO && buf[len] < CB_MAX)
+				{
+					if(cb_operate_state != buf[len])
+					{
+						Battery_Change_Mode(buf[len]);	
+					}
+					buf[len++] = 0;
+				}
+				else
+				{
+					buf[len++] = 1;
+				}
+				
+				buf[len++] = cb_operate_state;	
+			}
+			
+			break;
+		case KEY_END_CTR_BAT_INT_EN:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			break;	
+		case KEY_END_CTR_BAT_INT_PRE:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			break;
+		case KEY_END_CTR_SOFT_WARE:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			memcpy(&buf[len],soft_version,PS100_SOFTWARE_SIZE);
+			len += PS100_SOFTWARE_SIZE;
+			break;
+		case KEY_END_CTR_SN:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			memcpy(&buf[len],sn,sizeof(sn));
+			len += sizeof(sn);
+			break;
+		case KEY_END_CTR_WRITER_SN:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			break;
+		case KEY_END_CTR_BAT_UPDATE_REQ:
+			//if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+			//	return 1;
+			
+			rtn = 0;
+			len = buf[2];
+			if(len == UPDATE_BAT_1 || len == UPDATE_BAT_2)
+			{
+				if(len == UPDATE_BAT_1)
+				{
+					temp = Update_Sub_BMS_1_Software(UPDATE_STEP_REQ);
+				}
+				else
+				{
+					temp = Update_Sub_BMS_2_Software(UPDATE_STEP_REQ);
+				}
+				if(temp)
+				{
+					update_bat.ub_step = UPDATE_STEP_REQ;
+					update_bat.ub_bat = buf[2];
+					update_bat.ub_total = buf[4];
+					update_bat.ub_total = (update_bat.ub_total<<8)|buf[3];
+				}
+				else
+					rtn = 3;
+				
+			}
+			else
+				rtn = 1;
+			
+			len = 2;
+			buf[len++] = rtn;
+			break;
+		case KEY_END_CTR_BAT_UPDATE:
+			//if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+			///	return 1;
+
+			rtn = 0;
+			
+			len = buf[3];
+			len = (len<<8)|buf[2];
+			if(len <= update_bat.ub_total)
+			{
+				if(len == update_bat.ub_sq || len == update_bat.ub_sq + 1)
+				{
+					len = buf[5];
+					len = (len<<8)|buf[4];
+					if(len <= sizeof(update_bat.ub_data))
+					{
+						update_bat.ub_step = UPDATE_STEP_DATA;
+						update_bat.ub_sq = buf[3];
+						update_bat.ub_sq = (update_bat.ub_sq<<8)|buf[2];
+						update_bat.ub_len = buf[5];
+						update_bat.ub_len = (update_bat.ub_len<<8)|buf[4];
+						memcpy(update_bat.ub_data,&buf[6],update_bat.ub_len);
+
+						//
+						if(update_bat.ub_bat == UPDATE_BAT_1)
+						{
+							temp = Update_Sub_BMS_1_Software(UPDATE_STEP_DATA);
+						}
+						else
+						{
+							temp = Update_Sub_BMS_2_Software(UPDATE_STEP_DATA);
+						}
+						
+						if(temp)
+						{
+							if(update_bat.ub_sq == update_bat.ub_total)
+							{
+								memset(&update_bat,0x00,sizeof(update_bat));
+							}
+						}
+						else
+							rtn = 4;
+					}
+					else
+						rtn = 3;
+				}
+				else
+					rtn = 2;
+			}
+			else
+				rtn = 1;
+			
+			len = 2;
+			buf[len++] = rtn;
+			break;
+		case KEY_END_CTR_BAT_UPDATE_EXIT:
+			//if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+			//	return 1;
+
+			memset(&update_bat,0x00,sizeof(update_bat));
+			
+			len = 2;
+			buf[len++] = 0;
+			break;
+		case KEY_END_CTR_DAN_CI_LI_CHENG:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+
+			len = 2;
+			buf[len++] = sheng_yu_li_cheng.sy_yu_ji_ke_xing_shi_li_cheng;
+			break;
+		case KEY_END_CTR_ZHEN_JI_CE_SHI:
+			Writer_HT_Flash(1);
+			len = 2;
+			buf[len++] = 0;
+			break;
+		case KEY_END_CTR_QD:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			if(work_normal == 1)
+			{
+				buf[len++] = QD_Dect();
+
+				qd_dec_delay.count = QD_DEC_TIMEOUT;
+				
+				shield_xl.set = 1;
+				shield_xl.count = 0;
+				xl_dec_delay.count = 0;	
+				xl_count = 0;
+			}
+			else
+				buf[len++] = 0;
+			
+			break;	
+		case KEY_END_CTR_LOCK:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			buf[len++] = Lock_Dect();
+			break;
+		case KEY_END_CTR_L_R_LIGHT:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			break;
+		case KEY_END_CTR_CARPET_LIGHT:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			break;
+		case KEY_END_CTR_TAIL_LIGHT:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			break;
+		case KEY_END_CTR_ACC12:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			if(work_normal == 1)
+			{
+				buf[len++] = ACC2_Dect();
+				acc2_dec_delay.count = ACC2_DEC_TIMEOUT;
+			}
+			else
+				buf[len++] = 0;
+			break;	
+			
+		case KEY_END_CTR_ACC12_TEST:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			break;	
+		case KEY_END_CTR_ACC12_TEST_1:
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			if(work_normal == 1)
+			{
+				buf[len++] = ACC2_Dect();
+				acc2_dec_delay.count = ACC2_DEC_TIMEOUT;
+			}
+			else
+				buf[len++] = 0;
+			break;
+		case KEY_END_CTR_HEART_TICK:	
+			if((can_ctr_frame->head.rsp != FRAME_PT_NEED_RSP) || end_ctr_self_stimeout.set)
+				return 1;
+			
+			len = 2;
+			buf[len++] = 0;
+			break;
+		case KEY_END_CTR_SELF_UP:
+			return 0;
+#ifdef CONFIG_CAN_IAP
+		case 0x42F5:
+		case 0x42F6:
+			len = 3;
+			buf[2] = 0;
+			break;
+
+		case 0x42F8:
+			len = qws_iap_read_string(buf);
+			break;
+#endif
+		default:
+			return 0;
+	}
+	//
+	can_ctr_frame->head.rsp = FRAME_PT_RSP;
+	can_ctr_frame->head.dest = can_ctr_frame->head.sour;
+	can_ctr_frame->head.sour = SELF_ID;
+	can_ctr_frame->head.index = 1;
+	can_ctr_frame->head.total = (len - 1)/8 + 1;
+	can_ctr_frame->head.pro   =FRAME_PRO_D;
+	//
+	can_ctr_frame->len = len;
+
+	//
+	if(!Send_Data_Can(can_ctr_frame,CTR_RSP))
+	{
+		g_event |= END_CTR_RESEND_CMD_EVENT;
+		return 0;
+	}
+	
+	return 1;
+
+}
+
+void Check_End_Ctr_Status(void)
+{
+	
+	if(side_stay_dec_delay.set&&side_stay_dec_delay.count >= SIDE_STAY_DEC_TIMEOUT)
+	{
+		memset(&side_stay_dec_delay,0x00,sizeof(side_stay_dec_delay));
+		end_ctr_self_ss_new.side_sta = !Side_Stay_Dect();
+	}
+
+	if(soak_dec_delay.set&&soak_dec_delay.count >= SOAK_DEC_TIMEOUT)
+	{
+		soak_dec_delay.set = 0;
+		soak_dec_delay.count = 0;
+		end_ctr_self_ss_new.soak_sta = Soak_Dect();
+	}
+
+	if(sti_dec_delay.set&&sti_dec_delay.count >= STI_DEC_TIMEOUT)
+	{
+		memset(&sti_dec_delay,0x00,sizeof(sti_dec_delay));
+		end_ctr_self_ss_new.sit_sta = !Sitting_Dect();
+	}
+
+	if(repair_dec_delay.set&&repair_dec_delay.count >= REPAIR_DEC_TIMEOUT)
+	{
+		memset(&repair_dec_delay,0x00,sizeof(repair_dec_delay));
+		//end_ctr_self_ss_new.side_sta = !Repair_Key_Dect();
+	}
+
+	if(qd_dec_delay.set&&qd_dec_delay.count >= QD_DEC_TIMEOUT/*&&serise_low_qd_status == 0*/)
+	{
+		memset(&qd_dec_delay,0x00,sizeof(qd_dec_delay));
+		end_ctr_self_ss_new.qd_sta = QD_Dect();
+	}
+
+	//xl_dec_delay
+	if(xl_dec_delay.set&&xl_dec_delay.count >= XL_DEC_TIMEOUT)
+	{
+		xl_dec_delay.count = 0;	
+		if(shield_xl.set == 0)
+		{
+			end_ctr_self_ss_new.xl_sta = (xl_count)?1:0;
+		}
+		xl_count = 0;
+	}
+
+	if(acc2_dec_delay.set&&acc2_dec_delay.count >= ACC2_DEC_TIMEOUT)
+	{
+		memset(&acc2_dec_delay,0x00,sizeof(acc2_dec_delay));
+		end_ctr_self_ss_new.acc12_sta = ACC2_Dect();
+	}
+
+	//
+	end_ctr_self_ss_new.charger_in = IS_CHARGE_IN();
+	
+	end_ctr_self_ss_new.moto_temp = ctr_temperature[1];
+
+	end_ctr_self_ss_new.ps100_temp = ctr_temperature[0];
+	end_ctr_self_ss_new.bms_1_status = sub_bms_1_lt_state;
+	end_ctr_self_ss_new.bms_2_status = sub_bms_2_lt_state;
+	end_ctr_self_ss_new.using_bms_mode = cb_operate_state;
+
+	end_ctr_self_ss_new.nhb = (uint16_t)(sheng_yu_li_cheng.sy_ss_parm.neng_hao_bi);
+
+
+	//
+	end_ctr_rsp = end_ctr_self_ss_new;
+	
+	end_ctr_rsp.lock_sta = Lock_Dect();
+	end_ctr_rsp.carpet_sta = Carpet_Dect();
+	end_ctr_rsp.tail_sta = Tail_Dect();
+
+	
+}
+
+void End_Ctr_Initial(void)
+{
+	 E_CTR_Initial();
+
+	 memset(&update_bat,0x00,sizeof(update_bat));
+}
+
+void End_Ctr_Self_Send_Timeout(void)
+{
+	if(end_ctr_self_stimeout.set)
+	{
+		++end_ctr_self_stimeout.count;
+		if(end_ctr_self_stimeout.count >= 300)
+		{
+			memset(&end_ctr_self_stimeout,0x00,sizeof(end_ctr_self_stimeout));
+			g_event |= END_CTR_SELF_TIMEOUT_EVENT;
+		}
+		else if(end_ctr_self_stimeout.count == 200)
+			g_event |= END_CTR_SELF_TIMEOUT_EVENT;
+		else if(end_ctr_self_stimeout.count == 100)
+			g_event |= END_CTR_SELF_TIMEOUT_EVENT;
+	}
+	else
+		end_ctr_self_stimeout.count = 0;
+	
+}
+
+
+
+DELAY_COMMON acc12_delay;
+
+void ACC12_OVER_Loader_Timeout(void)
+{
+#if ACC2_USE_PWM
+	/*if(acc12_delay.set)
+	{
+		if(++acc12_delay.count >= 1)
+		{
+			memset(&acc12_delay,0x00,sizeof(acc12_delay));
+			gpio_bit_write(GPIOC,GPIO_PIN_15,(bit_status)0x01);
+		}
+	}*/
+#else
+
+	if(acc12_delay.set)
+	{
+	
+		if((acc12_delay.count&0x01UL) == 0)
+		{
+			if(ACC2_Over_Loader_Dect() == 1)
+			{
+				acc12_delay.set = 0;
+				acc12_delay.count = 0;
+				
+			}
+			else
+			{
+				//ACC2_Enable(0);
+				acc12_delay.count++;
+			}
+		}
+		else
+		{
+			//ACC2_Enable(1);
+			acc12_delay.count++;
+		}
+		
+
+	}
+#endif
+	
+}
+
+void ACC12_OVER_Loader_Interrupt(void)
+{
+#if ACC2_USE_PWM
+	/*if(acc12_delay.set)
+			return;
+		
+	acc12_delay.set = 1;
+
+	acc12_delay.count = 0;
+	gpio_bit_write(GPIOC,GPIO_PIN_15,(bit_status)0x00);*/
+#else
+
+	if(acc12_delay.set)
+			return;
+		
+	acc12_delay.set = 1;
+
+	acc12_delay.count = 0;
+#endif		
+}
+
+

+ 97 - 0
Source/app_end_ctr.h

@@ -0,0 +1,97 @@
+#ifndef APP_END_CTR_H
+#define APP_END_CTR_H
+
+#define LEFT_LIGHT  (0x01)
+#define RIGHT_LIGHT (0x02)
+#define LIANG_TIME  (200)
+#define ZONG_TIME    (900)
+
+#define SHIELD_XL_TIME    (400)
+
+
+//END CTR
+#define KEY_END_CTR_COMMON          (0x4200)
+#define KEY_END_CTR_SWI_BAT         (0x4201)
+#define KEY_END_CTR_BAT_INT_EN      (0x4202)
+#define KEY_END_CTR_BAT_INT_PRE     (0x4203)
+#define KEY_END_CTR_SOFT_WARE       (0x4204)
+#define KEY_END_CTR_SN				(0x4205)
+#define KEY_END_CTR_WRITER_SN		(0x4206)
+#define KEY_END_CTR_BAT_UPDATE_REQ	(0x4207)
+#define KEY_END_CTR_BAT_UPDATE		(0x4208)
+#define KEY_END_CTR_BAT_UPDATE_EXIT	(0x4209)
+#define KEY_END_CTR_DAN_CI_LI_CHENG	(0x420A)
+#define KEY_END_CTR_ZHEN_JI_CE_SHI	(0x420B)
+#define KEY_END_CTR_SELF_UP         (0x4280)
+
+
+#define KEY_END_CTR_QD  			(0x4301)
+#define KEY_END_CTR_LOCK  			(0x4302)
+#define KEY_END_CTR_ACC12  			(0x4306)
+#define KEY_END_CTR_ACC12_TEST		(0x4307)
+#define KEY_END_CTR_ACC12_TEST_1	(0x4308)
+#define KEY_END_CTR_L_R_LIGHT		(0x4303)
+#define KEY_END_CTR_CARPET_LIGHT	(0x4305)
+#define KEY_END_CTR_TAIL_LIGHT		(0x4318)
+
+#define KEY_END_CTR_HEART_TICK		(0x4800)
+
+
+
+#pragma  pack (push,1)  
+typedef struct
+{
+	uint16_t key;
+	uint8_t op_result;
+	
+	uint8_t qd_sta:1;
+	uint8_t lock_sta:1;
+	uint8_t xl_sta:1;
+	uint8_t side_sta:1;
+	uint8_t sit_sta:1;
+	uint8_t carpet_sta:1;
+	uint8_t tail_sta:1;
+	uint8_t soak_sta:1;
+
+	uint8_t acc12_sta:1;
+	uint8_t charger_in:1;
+	uint8_t res4_sta:6;
+
+	
+	int8_t moto_temp;
+
+
+	int8_t ps100_temp;
+	uint8_t bms_1_status;
+	uint8_t bms_2_status;
+	uint8_t using_bms_mode;
+	uint16_t nhb;
+	
+}END_CTR_SELF_SEND_STATUS;
+#pragma pack(pop)
+extern END_CTR_SELF_SEND_STATUS end_ctr_self_ss;
+extern END_CTR_SELF_SEND_STATUS end_ctr_self_ss_new;
+extern END_CTR_SELF_SEND_STATUS end_ctr_rsp;
+extern DELAY_COMMON end_ctr_self_stimeout;
+
+
+int8_t Handle_Can_Ctr_CMD(CAN_FRAME*can_ctr_frame);
+
+int8_t Rsp_Can_Ctr_CMD(CAN_FRAME*can_ctr_frame);
+
+void Can_End_Ctr_Self_Send_Check(CAN_FRAME*can_ctr_frame);
+
+void End_Ctr_Initial(void);
+
+void Check_End_Ctr_Status(void);
+
+void End_Ctr_Self_Send_Timeout(void);
+
+void ACC12_OVER_Loader_Timeout(void);
+
+void ACC12_OVER_Loader_Interrupt(void);
+
+void Shield_XL_Timeout(void);
+
+#endif
+

+ 646 - 0
Source/app_rs485_1.c

@@ -0,0 +1,646 @@
+#include "common.h"
+#include "drv_usart.h"
+#include "app_rs485_1.h"
+#include "app.h"
+#include "hardware_test.h"
+
+//uart1
+static uint8_t app_rs485_buf[TX_BUFFER_SIZE];
+
+static uint8_t bms_addr = SUB_BMS_ADDRESS_1;
+SUB_BMS_COM sub_rs485_time_out_1;
+
+SUB_BMS_INFO sub_bms_info_1;
+
+DELAY_COMMON send_delay;
+
+uint8_t RS485_busy_1 = 0;
+
+uint8_t sub_bms_1_lt_state = SUB_BMS_INVALID_STATUS;
+
+uint8_t sub_bms_1_connect = 0;
+
+uint8_t cang_wei = CW_CHE_SHANG_NO_CHARGER;
+
+uint16_t bms_1_work_status = 0;
+
+uint8_t bms_1_test_define_error = 0;
+
+static int8_t Get_Check_Sum_1(uint16_t*value,uint8_t*data,uint16_t size)
+{
+	uint32_t checksum;
+	if((NULL==value)||(NULL==data)||(0==size))
+	{
+		return 0;
+	}
+//
+	checksum = 0;
+	while(size>1)
+	{
+		checksum += *(uint16_t*)data;
+		data += 2;
+		size -= 2;
+	}
+//
+	if(size>0)
+	{
+		checksum += *data;
+	}
+//
+	while(checksum>>16)
+	{
+		checksum = (checksum&0xFFFF)+(checksum>>16);
+	}	
+//
+	*value = (uint16_t)~checksum;
+	
+	return 1;
+}
+
+uint8_t SUB_BMS_1_DEC(void)
+{
+	return sub_bms_1_connect;
+}
+
+void RS485_Communication_Time_Out_1(void)
+{
+
+	if(sub_bms_info_1.rs485_connect)
+	{
+		sub_bms_1_lt_state = SUB_BMS_CONT_NO485;
+	}
+	else
+	{
+		sub_bms_1_lt_state = SUB_BMS_DISC_NO485;
+	}
+	
+	if(sub_bms_info_1.rs485_time_out)
+		return;
+	memset(&sub_bms_info_1.packet_common,0x00,sizeof(sub_bms_info_1.packet_common));
+	memset(&sub_bms_info_1.bat_dev_info,0x00,sizeof(sub_bms_info_1.bat_dev_info));
+	memset(&sub_bms_info_1.bat_times,0x00,sizeof(sub_bms_info_1.bat_times));
+	memset(&sub_bms_info_1.cell_vol,0x00,sizeof(sub_bms_info_1.cell_vol));
+	memset(&sub_bms_info_1.temp_other,0x00,sizeof(sub_bms_info_1.temp_other));
+	memset(&sub_bms_info_1.sub_bms_cmd,0x00,sizeof(sub_bms_info_1.sub_bms_cmd));
+	sub_bms_info_1.rs485_time_out = 1;
+	sub_bms_info_1.sub_bms_cmd.operate = OP_READ_INFO;
+	//
+	sub_bms_1_connect = 0;
+
+}
+
+
+
+static int8_t Handle_Sub_BMS_CMD_1(uint8_t *data)
+{
+	static uint8_t send_times = 0;
+	COMMAND_BODY *bms = (COMMAND_BODY *)data;
+	int8_t bStatus;
+	uint16_t count;
+	SUB_BMS_INFO *temp_bms;
+	
+
+	do
+	{
+
+		if(bms->type != bms_addr || bms->dir != BMS_DIR || bms->bStatus == 0)
+			break;
+		
+		
+		memset(&sub_rs485_time_out_1,0x00,sizeof(sub_rs485_time_out_1));
+		g_event &= ~SUB_BMS_1_RS485_DISC_EVENT;
+		temp_bms = &sub_bms_info_1;
+		temp_bms->rs485_time_out = 0;
+		//
+		sub_bms_1_connect = 1;
+
+		RS485_busy_1 = 0;
+
+		if(sub_bms_info_1.rs485_connect)
+		{
+			sub_bms_1_lt_state = SUB_BMS_CONT_HV485;
+		}
+		else
+		{
+			sub_bms_1_lt_state = SUB_BMS_DISC_HV485;
+		}
+		
+		//CRC 
+		count = bms->checksum;
+		bms->checksum = 0;
+		bStatus = Get_Check_Sum_1((void*)&bms->checksum,data,bms->size);
+		if(1!=bStatus || count != bms->checksum)
+		{
+			break;
+		}
+
+		//handle frame
+		count = sizeof(COMMAND_BODY);
+		
+		memcpy(&temp_bms->packet_common,&data[count],sizeof(temp_bms->packet_common));
+		count += sizeof(temp_bms->packet_common);
+
+		//bang zi ce shi start
+		//temp_bms ->packet_common.m_percent /= 2;
+		//bang zi ce shi end
+
+		
+		if((temp_bms->packet_common.operate_result&0x01) != 0x01)
+			break;
+
+		switch((temp_bms->packet_common.operate_result&0xF0)>>4)
+		{
+			case OP_NONE:
+				
+				break;
+
+			case OP_BOND:
+				
+				break;
+				
+			case OP_WRITE_SN:	
+				
+				break;
+				
+			case OP_PAIR:
+				
+				break;
+			case OP_UPDATE_PAIR:
+				
+				break;
+			case OP_READ_INFO:
+				memcpy(&temp_bms->bat_dev_info,&data[count],sizeof(temp_bms->bat_dev_info));
+				count += sizeof(temp_bms->bat_dev_info);
+				break;
+			case OP_ALARM_TIMES:
+				memcpy(&temp_bms->bat_times,&data[count],sizeof(temp_bms->bat_times));
+				count += sizeof(temp_bms->bat_times);
+				break;	
+			case OP_CELL_VOL:
+				memcpy(&temp_bms->cell_vol,&data[count],sizeof(temp_bms->cell_vol));
+				count += sizeof(temp_bms->cell_vol);
+				break;
+			case OP_TEMP_OTHER:
+				memcpy(&temp_bms->temp_other,&data[count],sizeof(temp_bms->temp_other));
+				count += sizeof(temp_bms->temp_other);
+				break;
+
+				
+			case OP_OPEN_FET:
+				
+				break;
+
+			case OP_CLEAR_PAIR:
+				break;
+
+			case OP_UPDATE_SOFTWARE_REQ:
+				break;
+			case OP_UPDATE_SOFTWARE:
+				break;
+			default:break;
+
+		}
+		if(((temp_bms->packet_common.operate_result&0xF0)>>4) == temp_bms->sub_bms_cmd.operate)
+		{
+			memset(&temp_bms->sub_bms_cmd,0x00,sizeof(temp_bms->sub_bms_cmd));
+			++send_times;
+			if(send_times > 90)
+			{
+				temp_bms->sub_bms_cmd.operate = OP_ALARM_TIMES;
+				send_times = 0;
+			}
+			else if(send_times > 60)
+			{
+				temp_bms->sub_bms_cmd.operate = OP_CELL_VOL;
+				
+			}
+			else if(send_times > 30)
+			{
+				temp_bms->sub_bms_cmd.operate = OP_TEMP_OTHER;
+				
+			}
+			else
+				temp_bms->sub_bms_cmd.operate = OP_NONE;
+		}
+		return 1;
+		
+	}while(0);
+
+	return 0;
+	
+}
+
+
+static int8_t Send_Sub_BMS_CMD_1(void)
+{
+	int8_t bStatus;// 默认需要回复
+	COMMAND_BODY*body = (COMMAND_BODY*)app_rs485_buf;
+	uint8_t *buf = app_rs485_buf;
+	SUB_BMS_INFO *temp_bms;
+	
+	
+	temp_bms = &sub_bms_info_1;
+	
+	
+// 填帧头
+	body->size =  sizeof(COMMAND_BODY);
+	body->type = bms_addr;
+	body->protocol = 'B';
+	body->cmd = SET_COMMAND;
+	body->dir = BMS_DIR;
+	body->checksum = 0;
+	body->bStatus = 0;
+
+	// 填帧数据
+	//实时转速
+	buf[body->size++] = 0;
+
+	//本次电门打开已经行驶的里程
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+
+	//电门开关信号
+	buf[body->size++] = 0;
+
+	//操作
+	buf[body->size++] = temp_bms->sub_bms_cmd.operate;
+
+	//对码
+	buf[body->size++] = cang_wei;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	//更换对码,新对码
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+
+	switch(temp_bms->sub_bms_cmd.operate)
+	{
+		case OP_NONE:
+			
+			break;
+
+		case OP_BOND:
+			
+			break;
+			
+		case OP_WRITE_SN:	
+			switch(temp_bms->sub_bms_cmd.param)
+			{
+				case 3:
+					buf[body->size++] = (uint8_t)(temp_bms->sub_bms_cmd.param);
+					break;
+				case 4:
+					buf[body->size++] = (uint8_t)(temp_bms->sub_bms_cmd.param);
+					
+					buf[body->size++] = (uint8_t)(update_bat.ub_total>>0);
+					buf[body->size++] = (uint8_t)(update_bat.ub_total>>8);
+					buf[body->size++] = 0;
+					buf[body->size++] = 0;
+					buf[body->size++] = (uint8_t)(update_bat.ub_sq>>0);
+					buf[body->size++] = (uint8_t)(update_bat.ub_sq>>8);
+					buf[body->size++] = 0;
+					buf[body->size++] = 0;
+					memcpy(&buf[body->size],update_bat.ub_data,update_bat.ub_len);
+					body->size += update_bat.ub_len;
+					break;
+			}
+			break;
+			
+		case OP_PAIR:
+			
+			break;
+		case OP_UPDATE_PAIR:
+			
+			break;
+		case OP_READ_INFO:
+			
+			break;
+		case OP_ALARM_TIMES:
+			
+			break;	
+		case OP_CELL_VOL:
+			
+			break;
+
+		case OP_OPEN_FET:
+			buf[body->size++] = (uint8_t)(temp_bms->sub_bms_cmd.param);
+			break;
+		case OP_UPDATE_SOFTWARE_REQ:
+			
+			break;
+		case OP_UPDATE_SOFTWARE:
+			
+			break;
+		case OP_CLEAR_PAIR:
+			break;
+		default:break;
+	}
+	
+	bStatus = Get_Check_Sum_1((void*)&body->checksum,(void*)body,body->size);
+	if(1!=bStatus)
+	{
+		return 0;
+	}
+
+	Send_Data_RS485(buf,body->size);
+		
+	sub_rs485_time_out_1.set = 1;
+	sub_rs485_time_out_1.count = 0;
+
+	
+	RS485_busy_1 = 1;
+	
+	return 1;
+
+}
+
+void Send_Sub_BMS_1_CMD(void)
+{
+	
+	if(RS485_busy_1)
+		return;
+	
+	Send_Sub_BMS_CMD_1();
+}
+
+
+
+
+void Check_Sub_BMS_1(void)
+{
+	if(SUB_BMS_1_DEC())
+	{
+		if(sub_bms_info_1.rs485_connect == 0)
+		{
+			sub_bms_info_1.rs485_connect = 1;
+			sub_bms_info_1.sub_bms_cmd.operate = OP_READ_INFO;
+			
+	
+		}
+	}
+	else
+	{
+		if(sub_bms_info_1.rs485_connect)
+		{
+			memset(&sub_bms_info_1,0x00,sizeof(sub_bms_info_1));
+			memset(&sub_rs485_time_out_1,0x00,sizeof(sub_rs485_time_out_1));
+			RS485_busy_1 = 0;
+
+			//sub_bms_1_lt_state = SUB_BMS_DISC_NO485;
+			sub_bms_info_1.sub_bms_cmd.operate = OP_READ_INFO;
+
+
+			if(cb_operate_state == CB_BAT1)
+			{
+				//Power_On_Normal(0);
+			}
+		}
+	}
+
+		
+}
+
+
+
+int8_t Handle_RS485_1_Data(void)
+{
+	uint16_t len = Get_RS485_Data(app_rs485_buf,sizeof(app_rs485_buf));
+	if(len != app_rs485_buf[0])
+	{
+		if(memcmp(app_rs485_buf,"zhengjiceshi",12) == 0 && ht_mode == 0)
+		{
+			Writer_HT_Flash(1);
+			__set_FAULTMASK(1);
+			NVIC_SystemReset();
+		}
+		//idra-test-start
+		RS485_Print(0x22,app_rs485_buf,len);
+		//idra-test-end
+		return 0;
+	}
+
+	if((app_rs485_buf[0] > sizeof(COMMAND_BODY)))
+	{
+
+		if(!Handle_Sub_BMS_CMD_1(app_rs485_buf))
+		{
+			//idra-test-start
+			RS485_Print(0x22,app_rs485_buf,len);
+			//idra-test-end
+			return 0;
+		}
+	}
+
+	return 1;
+	
+}
+
+void Sub_BMS_1_Initial(void)
+{
+	Usart1_Initial();
+
+	memset(&sub_rs485_time_out_1,0x00,sizeof(sub_rs485_time_out_1));
+	memset(&sub_bms_info_1,0x00,sizeof(sub_bms_info_1));
+	send_delay.set = 1;
+	send_delay.count = 0;
+
+	sub_bms_info_1.sub_bms_cmd.operate = OP_READ_INFO;
+}
+
+void  Sub_BMS_1_lt_State(void)
+{
+	switch(sub_bms_1_lt_state)
+	{
+		case SUB_BMS_INVALID_STATUS:
+			break;
+		case SUB_BMS_DISC_NO485:
+			break;
+		case SUB_BMS_DISC_HV485:
+			break;
+		case SUB_BMS_CONT_HV485:
+			break;
+		case SUB_BMS_CONT_NO485:
+			break;
+	}
+	
+}
+
+uint8_t Is_Sub_BMS_1_Normal(void)
+{
+	uint16_t work_sta = sub_bms_info_1.packet_common.work_status;
+
+	work_sta &= ~ST_CHRG_CUR;
+	work_sta &= ~ST_DISCHRG_CUR;
+	work_sta &= ~ST_OVRDISCHRG_CUR;
+	work_sta &= ~ST_SMALL_CURRENT_OVER;
+	if(IS_CHARGER_ON())
+	//if(IS_CHARGE_IN())
+	{
+		work_sta &= ~ST_OVRDISCHRG_VOL;
+		work_sta &= ~ST_PDOWN;
+		work_sta &= ~ST_UDR_TEMPE_DISCHRG;
+		work_sta &= ~ST_OVR_TEMPE_DISCHRG;
+	}
+	else
+	{
+		work_sta &= ~ST_OVRCHRG_VOL;
+		work_sta &= ~ST_OVR_TEMPE_CHRG;
+		work_sta &= ~ST_UDR_TEMPE_CHRG;
+	}
+
+	
+	do
+	{
+		/*if(cb_operate_state != CB_BAT1_BAT2_PARRALLEL && cb_operate_state != CB_BAT_NO  )
+		{
+			if((BAT1_IS_OPEN() == 0))
+				break;
+		}*/
+
+		if(update_bat.ub_bat == UPDATE_BAT_1)
+			break;
+		
+		if(define_bms_1_error != D_BMS_ERROR_NO)
+			break;
+		
+		if((cb_operate_state == CB_BAT1_BAT2_SERIES)&&(BAT1_IS_OPEN() == 0))
+				break;
+		if(Is_Soak())
+			break;
+		
+		if(SUB_BMS_1_DEC() == 0)
+			break;
+		
+		if(work_sta)
+		{
+			bms_1_work_status = sub_bms_info_1.packet_common.work_status;
+			break;
+		}
+
+		if(sub_bms_1_lt_state != SUB_BMS_CONT_HV485)
+			break;
+
+		if(bms_1_test_define_error != 0)
+			break;
+		
+		return 1;
+	}while(0);
+
+	return 0;
+	
+}
+
+int8_t Operate_Sub_BMS_1_CD(uint8_t on)
+{
+	uint8_t cd_fet,rtn;
+	uint16_t i,timeout = RS485_COM_TIMEOUT;
+	
+	sub_bms_info_1.sub_bms_cmd.operate = OP_OPEN_FET;
+	switch(on)
+	{
+		case 1:
+			cd_fet = 0x03;
+			break;
+		case 0:
+			cd_fet = 0x00;
+			break;
+		case 2:
+			cd_fet = 0x04;
+			timeout = 2000;
+			break;
+		default:
+			cd_fet = 0x00;
+			break;
+			
+	}
+	sub_bms_info_1.sub_bms_cmd.param = cd_fet;
+	
+	g_event &= ~RS485_RECEIVE_END_EVENT;
+	Send_Sub_BMS_CMD_1();
+
+	cd_fet <<= 1;
+	rtn = 0;
+	for(i = 0; i < timeout/10;i++)
+	{
+		delay_1ms(10);
+		if(g_event & RS485_RECEIVE_END_EVENT)
+		{
+			g_event &= ~RS485_RECEIVE_END_EVENT;
+			Handle_RS485_1_Data();
+			if(on != 2)
+			{
+				if((sub_bms_info_1.packet_common.bms_status & cd_fet) == cd_fet)
+				{
+					rtn = 1;
+				}
+			}
+			else
+			{
+				rtn = 1;
+			}
+			break;
+		}
+		
+	}
+	
+	return rtn;
+	
+}
+
+
+
+int8_t Update_Sub_BMS_1_Software(uint8_t step)
+{
+	uint8_t rtn;
+	uint16_t i,timeout = RS485_COM_UPDATE_TIMEOUT;
+	
+	
+	switch(step)
+	{
+		case UPDATE_STEP_NO:
+			return 0;
+		case UPDATE_STEP_REQ:
+			sub_bms_info_1.sub_bms_cmd.operate = OP_WRITE_SN;
+			sub_bms_info_1.sub_bms_cmd.param = 0x03;
+			break;
+		case UPDATE_STEP_DATA:
+			sub_bms_info_1.sub_bms_cmd.operate = OP_WRITE_SN;
+			sub_bms_info_1.sub_bms_cmd.param = 0x04;
+			break;
+		default:
+			return 0;
+			
+	}
+	
+	g_event &= ~RS485_RECEIVE_END_EVENT;
+	Send_Sub_BMS_CMD_1();
+
+	rtn = 0;
+	for(i = 0; i < timeout/10;i++)
+	{
+		delay_1ms(10);
+		if(g_event & RS485_RECEIVE_END_EVENT)
+		{
+			g_event &= ~RS485_RECEIVE_END_EVENT;
+			rtn = Handle_RS485_1_Data();
+			
+			break;
+		}
+		
+	}
+	
+	return rtn;
+	
+}
+
+
+uint8_t Sub_BMS_1_COM_Finish(void)
+{
+	return sub_bms_1_lt_state;
+}
+

+ 324 - 0
Source/app_rs485_1.h

@@ -0,0 +1,324 @@
+#ifndef APP_RS485_1_H
+#define APP_RS485_1_H
+
+enum
+{
+	OP_NONE,
+	OP_BOND,
+	OP_WRITE_SN,
+	OP_PAIR,
+	OP_UPDATE_PAIR,
+	OP_READ_INFO,
+	OP_ALARM_TIMES,
+	OP_CELL_VOL,//0x07
+	OP_TEMP_OTHER,//0x08
+	
+	OP_OPEN_FET = 0x0B,
+
+	OP_CLEAR_PAIR = OP_TEMP_OTHER + 1,
+	OP_UPDATE_SOFTWARE_REQ = 0x0E,
+	OP_UPDATE_SOFTWARE = 0x0F,
+	OP_MAX
+};
+
+typedef struct
+{	
+	uint8_t operate;
+	uint8_t op_result;
+	uint16_t resver;
+	uint32_t param;
+}SUB_BMS_CMD;
+
+
+#define RS485_COM_TIMEOUT     (150)
+#define RS485_COM_ERROR     (3)
+#define RS485_COM_UPDATE_TIMEOUT     (1500)
+/*******************************************通用帧头-start*********************************************************/
+#pragma  pack (push,1)  
+typedef struct
+{
+//整个包大小
+	uint8_t size;
+//命令设备
+	uint8_t type;
+//协议类型
+	uint8_t protocol;
+//命令类型
+	uint8_t cmd;
+//命令校验
+	uint16_t checksum;
+//命令处理调用
+	uint8_t dir;
+//命令返回状态
+	uint8_t bStatus;
+//命令数据部分	
+}COMMAND_BODY;
+#pragma pack(pop)
+
+//
+#define BMS_STA_BOND       (0x01)
+#define BMS_STA_D_OPEN     (0x02)
+#define BMS_STA_C_OPEN     (0x04)
+#define BMS_STA_S_OPEN     (0x08)
+#define BMS_STA_C_FULL     (0x10)
+#define BMS_STA_S_BAHU     (0x20)
+#define BMS_STA_JIAO_YAN   (0x40)
+/*******************************************通用帧头-end*********************************************************/
+
+/*******************************************BMS帧头-start*********************************************************/
+#define SBU_BMS_ADDRESS               (0x30)
+#define SUB_BMS_ADDRESS_0             (SBU_BMS_ADDRESS)
+#define SUB_BMS_ADDRESS_1             (SBU_BMS_ADDRESS + 1)
+#define SUB_BMS_ADDRESS_2             (SBU_BMS_ADDRESS + 1)
+
+#define BMS_DIR                              (0x16)
+#define SET_COMMAND                          (0x10)
+#define GET_COMMAND                          (0x20)
+#define ACK_COMMAND                          (0x30)
+#define ENG_COMMAND                          (0x40)
+
+/*******************************************BMS帧头-end*********************************************************/
+#pragma  pack (push,1)  
+typedef struct
+{
+	uint8_t yjkxslc;
+	uint8_t m_percent;
+	uint8_t yjcdwcsj;
+	uint8_t charge_flag;
+	
+	int32_t m_current;
+	
+	uint32_t m_total_vol;
+	
+	uint8_t bms_temp;
+	uint16_t work_status;
+	uint32_t banlance_cell;
+
+	uint8_t bms_status;
+	
+	uint8_t operate_result;
+}PACKET_COMMON;
+
+#define SERIAL_NUM_SIZE                      18
+#define SOFTWARE_SIZE                        20
+typedef struct
+{
+	uint8_t sn[SERIAL_NUM_SIZE];
+	uint8_t soft_ver[SOFTWARE_SIZE];
+	
+}BATTERY_DEV_INFO;
+
+typedef struct
+{
+	uint16_t dcsmxs;
+	uint32_t charge_times;
+	uint32_t charge_over_vol_times;
+	uint32_t discharge_under_vol_times;
+	uint32_t charge_over_cur_times;
+	uint32_t discharge_under_cur_times;
+	uint32_t short_times;
+	uint32_t charge_under_temp_times;
+	uint32_t discharge_under_temp_times;
+	uint32_t charge_over_temp_times;
+	uint32_t discharge_over_temp_times;
+}BATTERY_TIMES;
+
+#define CELL_NUM_MAX	   (15u)  
+typedef struct
+{
+	uint8_t cv_cell_num;
+	uint16_t cv_cell_vol[CELL_NUM_MAX];
+}CELL_VOL;
+
+#define THERMISTOR_NUM_MAX				(4u)
+typedef struct
+{
+	int8_t to_temp_num[THERMISTOR_NUM_MAX];
+	uint8_t to_fet;
+}TEMP_OTHER;
+#pragma pack(pop)
+
+typedef struct
+{
+	PACKET_COMMON packet_common;
+	BATTERY_DEV_INFO bat_dev_info;
+	BATTERY_TIMES bat_times;
+	CELL_VOL cell_vol;
+	TEMP_OTHER temp_other;
+	SUB_BMS_CMD sub_bms_cmd;
+	
+	uint8_t rs485_connect;
+	uint8_t rs485_time_out;
+}SUB_BMS_INFO;
+
+extern SUB_BMS_INFO sub_bms_info_1;
+extern SUB_BMS_INFO sub_bms_info_2;
+
+
+typedef struct
+{
+	uint8_t set;
+	uint16_t count;
+
+	uint8_t com_err_flag;
+	uint32_t com_err_count;
+}SUB_BMS_COM;
+extern SUB_BMS_COM sub_rs485_time_out_1;
+extern SUB_BMS_COM sub_rs485_time_out_2;
+
+extern uint8_t RS485_busy_1;
+extern uint8_t RS485_busy_2;
+
+#if 0
+_inline void Sub_BMS_1_RS485_Com_Time_Out(void)
+{
+	if(sub_rs485_time_out_1.set)
+	{
+		if(++sub_rs485_time_out_1.count >= RS485_COM_TIMEOUT)
+		{
+			
+			RS485_busy_1 = 0;
+			sub_rs485_time_out_1.set = 0;
+			sub_rs485_time_out_1.count = 0;
+			if(sub_rs485_time_out_1.com_err_flag == 0)
+			{
+				sub_rs485_time_out_1.com_err_flag = 1;
+				sub_rs485_time_out_1.com_err_count = 1;
+			}
+			else
+			{
+				if(++sub_rs485_time_out_1.com_err_count >= 5)
+				{
+					sub_rs485_time_out_1.com_err_count = 0;
+					g_event |= SUB_BMS_1_RS485_DISC_EVENT;
+				}
+			}
+		}
+	}
+}
+
+__inline void Sub_BMS_2_RS485_Com_Time_Out(void)
+{
+	if(sub_rs485_time_out_2.set)
+	{
+		if(++sub_rs485_time_out_2.count >= RS485_COM_TIMEOUT)
+		{
+			
+			RS485_busy_2 = 0;
+			sub_rs485_time_out_2.set = 0;
+			sub_rs485_time_out_2.count = 0;
+			if(sub_rs485_time_out_2.com_err_flag == 0)
+			{
+				sub_rs485_time_out_2.com_err_flag = 1;
+				sub_rs485_time_out_2.com_err_count = 1;
+			}
+			else
+			{
+				if(++sub_rs485_time_out_2.com_err_count >= 5)
+				{
+					sub_rs485_time_out_2.com_err_count = 0;
+					g_event |= SUB_BMS_2_RS485_DISC_EVENT;
+				}
+			}
+		}
+	}
+}
+#endif
+
+extern DELAY_COMMON send_delay;
+__inline void Send_Sub_BMS_CMD_Delay(void)
+{
+	if(send_delay.set)
+	{
+		++send_delay.count;
+		if(send_delay.count >= 400)
+		{
+			send_delay.count = 0;
+			g_event |= SUB_BMS_2_SEND_CMD_EVENT;
+		}
+		else if(send_delay.count == 200)
+		{
+			g_event |= SUB_BMS_1_SEND_CMD_EVENT;
+		}
+	}
+}
+
+
+extern uint8_t sub_bms_1_connect;
+extern uint8_t sub_bms_2_connect;
+
+enum
+{
+	SUB_BMS_INVALID_STATUS,
+	SUB_BMS_DISC_NO485,
+	SUB_BMS_DISC_HV485,
+	SUB_BMS_CONT_HV485,
+	SUB_BMS_CONT_NO485,
+};
+extern uint8_t sub_bms_1_lt_state;
+extern uint8_t sub_bms_2_lt_state;
+
+enum
+{
+	CW_NONE,
+	CW_CHONG_DIAN_ZUO,
+	CW_CHE_SHANG_CHARGER,
+	CW_CHE_SHANG_NO_CHARGER,
+	
+	CW_MAX
+};
+extern uint8_t cang_wei;
+
+extern uint16_t bms_1_work_status ;
+extern uint16_t bms_2_work_status ;
+extern uint8_t bms_1_test_define_error;
+extern uint8_t bms_2_test_define_error;
+
+void Check_Sub_BMS_1(void);
+
+void Check_Sub_BMS_2(void);
+
+int8_t Handle_RS485_1_Data(void);
+
+int8_t Handle_RS485_2_Data(void);
+
+void RS485_Communication_Time_Out_1(void);
+
+void RS485_Communication_Time_Out_2(void);
+
+void Send_Sub_BMS_1_CMD(void);
+
+void Send_Sub_BMS_2_CMD(void);
+
+void Sub_BMS_1_Initial(void);
+
+void Sub_BMS_2_Initial(void);
+
+void  Sub_BMS_1_lt_State(void);
+
+void  Sub_BMS_2_lt_State(void);
+
+uint8_t Is_Sub_BMS_1_Normal(void);
+
+uint8_t Is_Sub_BMS_2_Normal(void);
+
+int8_t Operate_Sub_BMS_1_CD(uint8_t on);
+
+int8_t Operate_Sub_BMS_2_CD(uint8_t on);
+
+uint8_t Sub_BMS_1_COM_Finish(void);
+
+uint8_t Sub_BMS_2_COM_Finish(void);
+
+uint8_t SUB_BMS_1_DEC(void);
+
+uint8_t SUB_BMS_2_DEC(void);
+
+int8_t Update_Sub_BMS_1_Software(uint8_t step);
+
+int8_t Update_Sub_BMS_2_Software(uint8_t step);
+
+extern void RS485_Print(uint8_t dest,uint8_t * dbuf,uint16_t dbuf_len);
+
+#endif
+

+ 642 - 0
Source/app_rs485_2.c

@@ -0,0 +1,642 @@
+#include "common.h"
+#include "drv_usart_2.h"
+#include "app_rs485_2.h"
+#include "app.h"
+#include "hardware_test.h"
+
+//uart2
+static uint8_t app_rs485_buf[TX_2_BUFFER_SIZE];
+
+static uint8_t bms_addr = SUB_BMS_ADDRESS_2;
+
+SUB_BMS_COM sub_rs485_time_out_2;
+
+SUB_BMS_INFO sub_bms_info_2;
+
+uint8_t RS485_busy_2 = 0;
+
+uint8_t sub_bms_2_lt_state = SUB_BMS_INVALID_STATUS;	
+
+uint8_t sub_bms_2_connect = 0;
+
+uint16_t bms_2_work_status = 0;
+
+uint8_t bms_2_test_define_error = 0;
+
+static int8_t Get_Check_Sum_2(uint16_t*value,uint8_t*data,uint16_t size)
+{
+	uint32_t checksum;
+	if((NULL==value)||(NULL==data)||(0==size))
+	{
+		return 0;
+	}
+//
+	checksum = 0;
+	while(size>1)
+	{
+		checksum += *(uint16_t*)data;
+		data += 2;
+		size -= 2;
+	}
+//
+	if(size>0)
+	{
+		checksum += *data;
+	}
+//
+	while(checksum>>16)
+	{
+		checksum = (checksum&0xFFFF)+(checksum>>16);
+	}	
+//
+	*value = (uint16_t)~checksum;
+	
+	return 1;
+}
+
+
+uint8_t SUB_BMS_2_DEC(void)
+{
+	return sub_bms_2_connect;
+}
+
+void RS485_Communication_Time_Out_2(void)
+{
+
+	if(sub_bms_info_2.rs485_connect)
+	{
+		sub_bms_2_lt_state = SUB_BMS_CONT_NO485;
+	}
+	else
+	{
+		sub_bms_2_lt_state = SUB_BMS_DISC_NO485;
+	}
+
+	
+	if(sub_bms_info_2.rs485_time_out)
+		return;
+	memset(&sub_bms_info_2.packet_common,0x00,sizeof(sub_bms_info_2.packet_common));
+	memset(&sub_bms_info_2.bat_dev_info,0x00,sizeof(sub_bms_info_2.bat_dev_info));
+	memset(&sub_bms_info_2.bat_times,0x00,sizeof(sub_bms_info_2.bat_times));
+	memset(&sub_bms_info_2.cell_vol,0x00,sizeof(sub_bms_info_2.cell_vol));
+	memset(&sub_bms_info_2.temp_other,0x00,sizeof(sub_bms_info_2.temp_other));
+	memset(&sub_bms_info_2.sub_bms_cmd,0x00,sizeof(sub_bms_info_2.sub_bms_cmd));
+	sub_bms_info_2.rs485_time_out = 1;
+	sub_bms_info_2.sub_bms_cmd.operate = OP_READ_INFO;
+	//
+	sub_bms_2_connect = 0;
+
+}
+
+
+
+static int8_t Handle_Sub_BMS_CMD_2(uint8_t *data)
+{
+	static uint8_t send_times = 0;
+	COMMAND_BODY *bms = (COMMAND_BODY *)data;
+	int8_t bStatus;
+	uint16_t count;
+	SUB_BMS_INFO *temp_bms;
+	
+	
+	do
+	{
+
+
+		if(bms->type != bms_addr || bms->dir != BMS_DIR || bms->bStatus == 0)
+			break;
+		
+		
+		memset(&sub_rs485_time_out_2,0x00,sizeof(sub_rs485_time_out_2));	
+		g_event &= ~SUB_BMS_2_RS485_DISC_EVENT;
+		temp_bms = &sub_bms_info_2;
+		temp_bms->rs485_time_out = 0;
+
+		//
+		sub_bms_2_connect = 1;
+		
+		RS485_busy_2 = 0;
+
+		if(sub_bms_info_2.rs485_connect)
+		{
+			sub_bms_2_lt_state = SUB_BMS_CONT_HV485;
+		}
+		else
+		{
+			sub_bms_2_lt_state = SUB_BMS_DISC_HV485;
+		}
+		
+		//CRC 
+		count = bms->checksum;
+		bms->checksum = 0;
+		bStatus = Get_Check_Sum_2((void*)&bms->checksum,data,bms->size);
+		if(1!=bStatus || count != bms->checksum)
+		{
+			break;
+		}
+
+		//handle frame
+		count = sizeof(COMMAND_BODY);
+		
+		memcpy(&temp_bms->packet_common,&data[count],sizeof(temp_bms->packet_common));
+		count += sizeof(temp_bms->packet_common);
+
+		//bang zi ce shi start
+		//temp_bms ->packet_common.m_percent /= 2;
+		//bang zi ce shi end
+		
+		if((temp_bms->packet_common.operate_result&0x01) != 0x01)
+			break;
+
+		switch((temp_bms->packet_common.operate_result&0xF0)>>4)
+		{
+			case OP_NONE:
+				
+				break;
+
+			case OP_BOND:
+				
+				break;
+				
+			case OP_WRITE_SN:	
+				
+				break;
+				
+			case OP_PAIR:
+				
+				break;
+			case OP_UPDATE_PAIR:
+				
+				break;
+			case OP_READ_INFO:
+				memcpy(&temp_bms->bat_dev_info,&data[count],sizeof(temp_bms->bat_dev_info));
+				count += sizeof(temp_bms->bat_dev_info);
+				break;
+			case OP_ALARM_TIMES:
+				memcpy(&temp_bms->bat_times,&data[count],sizeof(temp_bms->bat_times));
+				count += sizeof(temp_bms->bat_times);
+				break;	
+			case OP_CELL_VOL:
+				memcpy(&temp_bms->cell_vol,&data[count],sizeof(temp_bms->cell_vol));
+				count += sizeof(temp_bms->cell_vol);
+				break;
+			case OP_TEMP_OTHER:
+				memcpy(&temp_bms->temp_other,&data[count],sizeof(temp_bms->temp_other));
+				count += sizeof(temp_bms->temp_other);
+				break;
+
+			case OP_OPEN_FET:
+				
+				break;
+
+			case OP_CLEAR_PAIR:
+				break;
+
+			case OP_UPDATE_SOFTWARE_REQ:
+				break;
+			case OP_UPDATE_SOFTWARE:
+				break;
+			default:break;
+
+		}
+		if(((temp_bms->packet_common.operate_result&0xF0)>>4) == temp_bms->sub_bms_cmd.operate)
+		{
+			memset(&temp_bms->sub_bms_cmd,0x00,sizeof(temp_bms->sub_bms_cmd));
+			++send_times;
+			if(send_times > 90)
+			{
+				temp_bms->sub_bms_cmd.operate = OP_ALARM_TIMES;
+				send_times = 0;
+			}
+			else if(send_times > 60)
+			{
+				temp_bms->sub_bms_cmd.operate = OP_CELL_VOL;
+				
+			}
+			else if(send_times > 30)
+			{
+				temp_bms->sub_bms_cmd.operate = OP_TEMP_OTHER;
+				
+			}
+			else
+				temp_bms->sub_bms_cmd.operate = OP_NONE;
+		}
+		return 1;
+		
+	}while(0);
+
+	return 0;
+	
+}
+
+
+
+
+
+static int8_t Send_Sub_BMS_CMD_2(void)
+{
+	int8_t bStatus;// 默认需要回复
+	COMMAND_BODY*body = (COMMAND_BODY*)app_rs485_buf;
+	uint8_t *buf = app_rs485_buf;
+	SUB_BMS_INFO *temp_bms;
+	
+	
+	temp_bms = &sub_bms_info_2;	
+	
+	
+// 填帧头
+	body->size =  sizeof(COMMAND_BODY);
+	body->type = bms_addr;
+	body->protocol = 'B';
+	body->cmd = SET_COMMAND;
+	body->dir = BMS_DIR;
+	body->checksum = 0;
+	body->bStatus = 0;
+
+	// 填帧数据
+	//实时转速
+	buf[body->size++] = 0;
+
+	//本次电门打开已经行驶的里程
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+
+	//电门开关信号
+	buf[body->size++] = 0;
+
+	//操作
+	buf[body->size++] = temp_bms->sub_bms_cmd.operate;
+
+	//对码
+	buf[body->size++] = cang_wei;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	//更换对码,新对码
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+	buf[body->size++] = 0;
+
+	switch(temp_bms->sub_bms_cmd.operate)
+	{
+		case OP_NONE:
+			
+			break;
+
+		case OP_BOND:
+			
+			break;
+			
+		case OP_WRITE_SN:
+			switch(temp_bms->sub_bms_cmd.param)
+			{
+				case 3:
+					buf[body->size++] = (uint8_t)(temp_bms->sub_bms_cmd.param);
+					break;
+				case 4:
+					buf[body->size++] = (uint8_t)(temp_bms->sub_bms_cmd.param);
+
+					buf[body->size++] = (uint8_t)(update_bat.ub_total>>0);
+					buf[body->size++] = (uint8_t)(update_bat.ub_total>>8);
+					buf[body->size++] = 0;
+					buf[body->size++] = 0;
+					buf[body->size++] = (uint8_t)(update_bat.ub_sq>>0);
+					buf[body->size++] = (uint8_t)(update_bat.ub_sq>>8);
+					buf[body->size++] = 0;
+					buf[body->size++] = 0;
+					memcpy(&buf[body->size],update_bat.ub_data,update_bat.ub_len);
+					body->size += update_bat.ub_len;
+					break;
+			}
+			break;
+			
+		case OP_PAIR:
+			
+			break;
+		case OP_UPDATE_PAIR:
+			
+			break;
+		case OP_READ_INFO:
+			
+			break;
+		case OP_ALARM_TIMES:
+			
+			break;	
+		case OP_CELL_VOL:
+			
+			break;
+
+		case OP_OPEN_FET:
+			buf[body->size++] = (uint8_t)(temp_bms->sub_bms_cmd.param);
+			break;
+		case OP_UPDATE_SOFTWARE_REQ:
+			
+			break;
+		case OP_UPDATE_SOFTWARE:
+			
+			break;
+		case OP_CLEAR_PAIR:
+			break;
+		default:break;
+	}
+	
+	bStatus = Get_Check_Sum_2((void*)&body->checksum,(void*)body,body->size);
+	if(1!=bStatus)
+	{
+		return 0;
+	}
+
+	Send_Data_2_RS485(buf,body->size);
+
+	sub_rs485_time_out_2.set = 1;
+	sub_rs485_time_out_2.count = 0;		
+	
+	
+	RS485_busy_2 = 1;
+	
+	return 1;
+
+}
+
+
+
+void Send_Sub_BMS_2_CMD(void)
+{
+	
+	if(RS485_busy_2)
+		return;
+    Send_Sub_BMS_CMD_2();
+}
+
+
+
+void Check_Sub_BMS_2(void)
+{
+	
+
+	if(SUB_BMS_2_DEC())
+	{
+		if(sub_bms_info_2.rs485_connect == 0)
+		{
+			sub_bms_info_2.rs485_connect = 1;
+			sub_bms_info_2.sub_bms_cmd.operate = OP_READ_INFO;
+			
+		}
+	}
+	else
+	{
+		if(sub_bms_info_2.rs485_connect)
+		{
+			memset(&sub_bms_info_2,0x00,sizeof(sub_bms_info_2));
+			memset(&sub_rs485_time_out_2,0x00,sizeof(sub_rs485_time_out_2));
+			RS485_busy_2 = 0;
+			//sub_bms_2_lt_state = SUB_BMS_DISC_NO485;
+			sub_bms_info_2.sub_bms_cmd.operate = OP_READ_INFO;
+
+
+			if(cb_operate_state == CB_BAT2)
+			{
+				//Power_On_Normal(0);
+			}
+		}
+	}
+		
+}
+
+
+int8_t Handle_RS485_2_Data(void)
+{
+	uint16_t len = Get_RS485_2_Data(app_rs485_buf,sizeof(app_rs485_buf));
+	if(len != app_rs485_buf[0])
+	{
+		if(memcmp(app_rs485_buf,"zhengjiceshi",12) == 0 && ht_mode == 0)
+		{
+			Writer_HT_Flash(1);
+			__set_FAULTMASK(1);
+			NVIC_SystemReset();
+		}
+		//idra-test-start
+		RS485_Print(0x23,app_rs485_buf,len);
+		//idra-test-end
+		return 0;
+	}
+
+	if((app_rs485_buf[0] > sizeof(COMMAND_BODY)))
+	{
+
+		if(!Handle_Sub_BMS_CMD_2(app_rs485_buf))
+		{
+			//idra-test-start
+			RS485_Print(0x23,app_rs485_buf,len);
+			//idra-test-end
+			return 0;
+		}
+	}
+
+	return 1;
+	
+}
+
+void Sub_BMS_2_Initial(void)
+{
+	Usart2_Initial();
+
+	memset(&sub_rs485_time_out_2,0x00,sizeof(sub_rs485_time_out_2));
+	memset(&sub_bms_info_2,0x00,sizeof(sub_bms_info_2));
+	sub_bms_info_2.sub_bms_cmd.operate = OP_READ_INFO;
+}
+
+void  Sub_BMS_2_lt_State(void)
+{
+	switch(sub_bms_2_lt_state)
+	{
+		case SUB_BMS_INVALID_STATUS:
+			break;
+		case SUB_BMS_DISC_NO485:
+			break;
+		case SUB_BMS_DISC_HV485:
+			break;
+		case SUB_BMS_CONT_HV485:
+			break;
+		case SUB_BMS_CONT_NO485:
+			break;
+	}
+	
+}
+
+
+uint8_t Is_Sub_BMS_2_Normal(void)
+{
+	uint16_t work_sta = sub_bms_info_2.packet_common.work_status;
+
+	work_sta &= ~ST_CHRG_CUR;
+	work_sta &= ~ST_DISCHRG_CUR;
+	work_sta &= ~ST_OVRDISCHRG_CUR;
+	work_sta &= ~ST_SMALL_CURRENT_OVER;
+	if(IS_CHARGER_ON())
+	//if(IS_CHARGE_IN())
+	{
+		work_sta &= ~ST_OVRDISCHRG_VOL;
+		work_sta &= ~ST_PDOWN;
+		work_sta &= ~ST_UDR_TEMPE_DISCHRG;
+		work_sta &= ~ST_OVR_TEMPE_DISCHRG;
+	}
+	else
+	{
+		work_sta &= ~ST_OVRCHRG_VOL;
+		work_sta &= ~ST_OVR_TEMPE_CHRG;
+		work_sta &= ~ST_UDR_TEMPE_CHRG;
+	}
+
+	do
+	{
+
+		/*if(cb_operate_state != CB_BAT1_BAT2_PARRALLEL && cb_operate_state != CB_BAT_NO  )
+		{
+			if((BAT2_IS_OPEN() == 0))
+				break;
+		}*/
+
+		if(update_bat.ub_bat == UPDATE_BAT_2)
+			break;
+		
+		if(define_bms_2_error != D_BMS_ERROR_NO)
+			break;
+		
+		if((cb_operate_state == CB_BAT1_BAT2_SERIES)&&(BAT2_IS_OPEN() == 0))
+				break;
+		if(Is_Soak())
+			break;
+		
+		if(SUB_BMS_2_DEC() == 0)
+			break;
+		
+		if(work_sta)
+		{
+			bms_2_work_status = sub_bms_info_2.packet_common.work_status;
+			break;
+		}
+
+		if(sub_bms_2_lt_state != SUB_BMS_CONT_HV485)
+			break;
+
+		if(bms_2_test_define_error != 0)
+			break;
+		
+		return 1;
+	}while(0);
+
+	return 0;
+	
+}
+
+
+int8_t Operate_Sub_BMS_2_CD(uint8_t on)
+{
+	uint8_t cd_fet,rtn;
+	uint16_t i,timeout = RS485_COM_TIMEOUT;
+	
+	sub_bms_info_2.sub_bms_cmd.operate = OP_OPEN_FET;
+	switch(on)
+	{
+		case 1:
+			cd_fet = 0x03;
+			break;
+		case 0:
+			cd_fet = 0x00;
+			break;
+		case 2:
+			cd_fet = 0x04;
+			timeout = 2000;
+			break;
+		default:
+			cd_fet = 0x00;
+			break;
+			
+	}
+	sub_bms_info_2.sub_bms_cmd.param = cd_fet;
+	
+	g_event &= ~RS485_2_RECEIVE_END_EVENT;
+	Send_Sub_BMS_CMD_2();
+
+	cd_fet <<= 1;
+	rtn = 0;
+	for(i = 0; i < timeout/10;i++)
+	{
+		delay_1ms(10);
+		if(g_event & RS485_2_RECEIVE_END_EVENT)
+		{
+			g_event &= ~RS485_2_RECEIVE_END_EVENT;
+			Handle_RS485_2_Data();
+			if(on != 2)
+			{
+				if((sub_bms_info_2.packet_common.bms_status & cd_fet) == cd_fet)
+				{
+					rtn = 1;
+				}
+			}
+			else
+			{
+				rtn = 1;
+			}
+			break;
+		}
+		
+	}
+	
+	return rtn;
+	
+}
+
+
+
+int8_t Update_Sub_BMS_2_Software(uint8_t step)
+{
+	uint8_t rtn;
+	uint16_t i,timeout = RS485_COM_UPDATE_TIMEOUT;
+	
+	
+	switch(step)
+	{
+		case UPDATE_STEP_NO:
+			return 0;
+		case UPDATE_STEP_REQ:
+			sub_bms_info_2.sub_bms_cmd.operate = OP_UPDATE_SOFTWARE_REQ;
+			break;
+		case UPDATE_STEP_DATA:
+			sub_bms_info_2.sub_bms_cmd.operate = OP_UPDATE_SOFTWARE;			
+			break;
+		default:
+			return 0;
+			
+	}
+	
+	g_event &= ~RS485_2_RECEIVE_END_EVENT;
+	Send_Sub_BMS_CMD_2();
+
+	rtn = 0;
+	for(i = 0; i < timeout/10;i++)
+	{
+		delay_1ms(10);
+		if(g_event & RS485_2_RECEIVE_END_EVENT)
+		{
+			g_event &= ~RS485_2_RECEIVE_END_EVENT;
+			rtn = Handle_RS485_2_Data();
+			
+			break;
+		}
+		
+	}
+	
+	return rtn;
+	
+}
+
+uint8_t Sub_BMS_2_COM_Finish(void)
+{
+	return sub_bms_2_lt_state;
+}
+

+ 8 - 0
Source/app_rs485_2.h

@@ -0,0 +1,8 @@
+#ifndef APP_RS485_2_H
+#define APP_RS485_2_H
+
+#include "app_rs485_1.h"
+
+
+#endif
+

+ 114 - 0
Source/common.h

@@ -0,0 +1,114 @@
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <ctype.h>
+#include "gd32f10x.h"
+#include "gd32f10x_libopt.h"
+#include "delay.h"
+
+#define DEBUG_MODE    (1)
+ 
+#define CONFIG_CAN_IAP
+#define USART_BAUND    (38400)
+#define NVIC_OFFSET    (0x00)
+#define THER_NUM_CON		2u
+
+
+#define SN_FLASH_ADDRESS   (2048)
+#define SYLC_FLASH_ADDRESS   (SN_FLASH_ADDRESS + 1024)
+#define HARD_TEST_FLASH_ADDRESS   (SYLC_FLASH_ADDRESS + 1024)
+
+#define PS100_SERIAL_NUM_SIZE                      18
+#define PS100_SOFTWARE_SIZE                        20
+extern const uint8_t soft_version[];
+extern uint8_t sn[PS100_SERIAL_NUM_SIZE];
+
+typedef struct
+{
+	uint8_t set;
+	uint16_t count;
+}DELAY_COMMON;
+
+typedef struct
+{
+	uint8_t enable;
+	uint8_t set;
+	uint16_t count;
+}CTR_DELAY_COMMON;
+
+enum
+{
+	WS_BATTER_BING_LIAN,
+	WS_BATTER_CHUAN_LIAN,
+
+	
+	WS_BATTER_MAX
+};
+
+
+
+#define NO_EVENT                     0x00000000UL
+#define RS485_RECEIVE_END_EVENT      0x00000001UL
+#define EVENT_CAN_RECEIVE_FINISH	 0x00000002UL
+#define RS485_2_RECEIVE_END_EVENT    0x00000004UL
+#define SUB_BMS_1_RS485_DISC_EVENT   0x00000008UL
+#define SUB_BMS_2_RS485_DISC_EVENT   0x00000010UL
+#define MEASURE_TEMPERATURE_EVENT    0x00000020UL
+#define SUB_BMS_1_SEND_CMD_EVENT     0x00000040UL
+#define SUB_BMS_2_SEND_CMD_EVENT     0x00000080UL
+#define BMS_1_RESEND_CMD_EVENT       0x00000100UL
+#define BMS_2_RESEND_CMD_EVENT       0x00000200UL
+#define END_CTR_RESEND_CMD_EVENT     0x00000400UL
+#define ADAS_RESEND_CMD_EVENT        0x00000800UL
+#define BMS_1_SELF_TIMEOUT_EVENT     0x00001000UL
+#define BMS_2_SELF_TIMEOUT_EVENT     0x00002000UL
+#define END_CTR_SELF_TIMEOUT_EVENT   0x00004000UL
+#define ADAS_SELF_TIMEOUT_EVENT      0x00008000UL
+#define ADAS_PWM_1_TIMEOUT_EVENT     0x00010000UL
+#define ADAS_PWM_2_TIMEOUT_EVENT     0x00020000UL
+#define ADAS_MEAS_1_FINISH_EVENT     0x00040000UL
+#define ADAS_MEAS_2_FINISH_EVENT     0x00080000UL
+#define RE_INITIAL_CAN_EVENT         0x00100000UL
+#define ENTER_SLEEP_EVENT            0x00200000UL
+#define DEVICE_REBOOT_EVENT          0x00400000UL
+#define SAVE_PARAM_EVENT             0x00800000UL
+
+extern uint32_t g_event;
+
+
+
+#define ST_NORMAL						(0x0000u)
+#define ST_OVRCHRG_VOL					(0x0001u)
+#define ST_OVRDISCHRG_VOL				(0x0002u)
+#define ST_SMALL_CURRENT_OVER			(0x0004u)
+#define ST_SHORT_CUR					(0x0008u)
+
+#define ST_CHRG_CUR						(0x0010u)
+#define ST_DISCHRG_CUR					(0x0020u)
+#define ST_OVRCHRG_CUR					(0x0040u)
+#define ST_OVRDISCHRG_CUR				(0x0080u)
+
+#define ST_TOTAL_CHRG					(0x0100u)
+#define ST_CELLDIFF_CHRG				(0x0200u)
+#define ST_PSAVE						(0x0400u)
+#define ST_PDOWN						(0x0800u)
+
+#define ST_UDR_TEMPE_CHRG				(0x1000u)//Detect the charge inhibit temperature (high)
+#define ST_UDR_TEMPE_DISCHRG			(0x2000u)
+#define ST_OVR_TEMPE_CHRG				(0x4000u)
+#define ST_OVR_TEMPE_DISCHRG			(0x8000u)
+
+#define HAN_GUO_VERSION
+
+uint8_t Get_RS485_CRC(uint8_t *data,uint16_t size);
+
+void Writer_SN(uint8_t *data);
+
+
+#endif
+

+ 250 - 0
Source/delay.c

@@ -0,0 +1,250 @@
+#include "common.h"
+#include "delay.h"
+#include "drv_usart.h"
+#include "drv_usart_2.h"
+#include "drv_io.h"
+#include "drv_can.h"
+#include "measure_temprature.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "app.h"
+#include "app_can.h"
+#include "app_bms_1.h"
+#include "app_bms_2.h"
+#include "app_end_ctr.h"
+#include "app_adas.h"
+#include "low_power.h"
+#include "hardware_test.h"
+
+static uint32_t delay = 0;
+uint32_t utc_seconds = 1505216210;// 2017/9/12  19:37:50
+uint16_t s_ms ;
+
+void systick_close(void)
+{
+	//close tick
+	
+	SysTick->CTRL  &= ~SysTick_CTRL_TICKINT_Msk;
+	SysTick->CTRL  &= ~SysTick_CTRL_ENABLE_Msk;
+
+}
+
+void delay_1us(uint16_t cnt)
+{
+	uint32_t  count = 3*cnt;
+	while(count--); 
+}
+
+/*!
+    \brief      configure systick
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+
+void systick_config(void)
+{
+	if (SysTick_Config(SystemCoreClock / 1000))
+	{ 
+		/* Capture error */ 
+		while (1);
+	}
+    NVIC_SetPriority(SysTick_IRQn, 0x00U);
+
+	delay = 0;
+
+	s_ms = 0;
+}
+
+/*!
+    \brief      delay a time in milliseconds
+    \param[in]  count: count in milliseconds
+    \param[out] none
+    \retval     none
+*/
+void delay_1ms(uint32_t count)
+{
+    delay = count;
+
+    while(0 != delay);
+}
+
+#if 0
+/*!
+    \brief      delay decrement
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void delay_decrement(void)
+{
+    if (0 != delay){ 
+        delay--;
+    }
+}
+#endif
+
+void SysTick_Handler(void)
+{
+	//uint8_t i,j;
+	
+	if(++s_ms >= 1000)
+	{
+		utc_seconds++;
+		s_ms = 0;
+
+		Measure_Temprature_Delay();
+
+		Save_Param_Time_Out();

+	}
+		
+	if (0 != delay){ 
+        delay--;
+    }
+
+	ACC2_PWM();
+	
+	Uart1_Time_Out();
+
+	Uart2_Time_Out();
+
+	ACC12_OVER_Loader_Timeout();
+
+	if(sub_rs485_time_out_1.set)
+	{
+		if(++sub_rs485_time_out_1.count >= RS485_COM_TIMEOUT)
+		{
+			
+			RS485_busy_1 = 0;
+			sub_rs485_time_out_1.set = 0;
+			sub_rs485_time_out_1.count = 0;
+			if(sub_rs485_time_out_1.com_err_flag == 0)
+			{
+				sub_rs485_time_out_1.com_err_flag = 1;
+				sub_rs485_time_out_1.com_err_count = 1;
+			}
+			else
+			{
+				if(++sub_rs485_time_out_1.com_err_count >= RS485_COM_ERROR)
+				{
+					sub_rs485_time_out_1.com_err_count = 0;
+					g_event |= SUB_BMS_1_RS485_DISC_EVENT;
+				}
+			}
+		}
+	}
+	
+	if(sub_rs485_time_out_2.set)
+	{
+		if(++sub_rs485_time_out_2.count >= RS485_COM_TIMEOUT)
+		{
+			
+			RS485_busy_2 = 0;
+			sub_rs485_time_out_2.set = 0;
+			sub_rs485_time_out_2.count = 0;
+			if(sub_rs485_time_out_2.com_err_flag == 0)
+			{
+				sub_rs485_time_out_2.com_err_flag = 1;
+				sub_rs485_time_out_2.com_err_count = 1;
+			}
+			else
+			{
+				if(++sub_rs485_time_out_2.com_err_count >= RS485_COM_ERROR)
+				{
+					sub_rs485_time_out_2.com_err_count = 0;
+					g_event |= SUB_BMS_2_RS485_DISC_EVENT;
+				}
+			}
+		}
+	}
+
+#if 0
+	Send_Sub_BMS_CMD_Delay();
+#else
+if(send_delay.set)
+	{
+		++send_delay.count;
+		if(send_delay.count >= 400)
+		{
+			send_delay.count = 0;
+			if(update_bat.ub_bat != UPDATE_BAT_2)
+				g_event |= SUB_BMS_2_SEND_CMD_EVENT;
+		}
+		else if(send_delay.count == 200)
+		{
+			if(update_bat.ub_bat != UPDATE_BAT_1)
+				g_event |= SUB_BMS_1_SEND_CMD_EVENT;
+		}
+	}
+#endif
+	//Check_CB_Oper_Sta_Delay();
+	
+	if(side_stay_dec_delay.set)
+		side_stay_dec_delay.count++;
+	if(soak_dec_delay.set)
+		soak_dec_delay.count++;
+	if(sti_dec_delay.set)
+		sti_dec_delay.count++;
+	if(repair_dec_delay.set)
+		repair_dec_delay.count++;
+	if(qd_dec_delay.set)
+		qd_dec_delay.count++;
+	if(xl_dec_delay.set)
+		xl_dec_delay.count++;
+	if(acc2_dec_delay.set)
+		acc2_dec_delay.count++;
+	
+	
+	
+	if(left_light_delay.set)
+	{
+		++left_light_delay.count;
+		if(left_light_delay.count >= ZONG_TIME)
+		{
+			Left_Light_Enable(1);
+			left_light_delay.count = 0;
+		}
+		else if(left_light_delay.count >= LIANG_TIME)
+		{
+			Left_Light_Enable(0);
+		}
+	}
+	if(right_light_delay.set)
+	{
+		++right_light_delay.count;
+		if(right_light_delay.count >= ZONG_TIME)
+		{
+			Right_Light_Enable(1);
+			right_light_delay.count = 0;
+		}
+		else if(right_light_delay.count >= LIANG_TIME)
+		{
+			Right_Light_Enable(0);
+		}
+	}
+
+
+
+	Bms_1_Self_Send_Timeout();
+
+	Bms_2_Self_Send_Timeout();
+
+	End_Ctr_Self_Send_Timeout();
+
+	ADAS_Timeout();
+
+	Shield_XL_Timeout();
+
+	Check_Charger_Timeout();
+
+	Series_Delay_Timeout();
+
+	Enter_Sleep_Delay_Timeout();
+
+	HT_Reboot_Timeout();
+	
+}
+
+
+
+

+ 15 - 0
Source/delay.h

@@ -0,0 +1,15 @@
+#ifndef __DELAY_H
+#define __DELAY_H 			   
+
+extern uint32_t utc_seconds;
+
+
+void systick_close(void);
+void systick_config(void);
+void delay_1ms(uint32_t count);
+void delay_1us(uint16_t cnt);
+
+#endif
+
+
+

+ 213 - 0
Source/drv_adas.c

@@ -0,0 +1,213 @@
+#include "common.h"
+#include "drv_adas.h"
+
+void ADAS_Timer_Initial(void)
+{
+   
+    timer_parameter_struct timer_initpara;
+
+    rcu_periph_clock_enable(RCU_TIMER2);
+
+    timer_deinit(TIMER2);
+    /* initialize TIMER init parameter struct */
+    timer_struct_para_init(&timer_initpara);
+    /* TIMER1 configuration */
+    timer_initpara.prescaler         = 107;
+    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
+    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+    timer_initpara.period            = 400;
+    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
+	timer_initpara.repetitioncounter = 0;
+    timer_init(TIMER2, &timer_initpara);
+
+    timer_interrupt_enable(TIMER2, TIMER_INT_UP);
+    timer_disable(TIMER2);
+
+	nvic_irq_enable(TIMER2_IRQn, 1, 0);
+	
+}
+
+
+
+void TIMER2_IRQHandler(void)
+{
+	if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_UP))
+	{
+        /* clear channel 0 interrupt bit */
+        timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP);
+		
+		timer_disable(TIMER1);
+
+		timer_disable(TIMER2);
+
+		ADAS_PWM_IO_Reset();
+       
+    }
+	
+}
+
+/**
+    \brief      configure the GPIO ports
+    \param[in]  none
+    \param[out] none
+    \retval     none
+  */
+void ADAS_PWM_IO_Reset(void)
+{
+    rcu_periph_clock_enable(RCU_GPIOB);
+
+    /*Configure PA1 PA2 PA3(TIMER1 CH1 CH2 CH3) as alternate function*/
+	gpio_pin_remap_config(GPIO_TIMER1_PARTIAL_REMAP1,DISABLE);
+    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_10|GPIO_PIN_11);
+	gpio_bit_reset(GPIOB,GPIO_PIN_10);
+	gpio_bit_reset(GPIOB,GPIO_PIN_11);
+}
+
+/**
+    \brief      configure the TIMER peripheral
+    \param[in]  none
+    \param[out] none
+    \retval     none
+  */
+void ADAS_PWM_Initial(uint8_t pwm_no)
+{
+	uint16_t chno;
+	uint32_t pin;
+    /* -----------------------------------------------------------------------
+    TIMER1 configuration: generate 3 PWM signals with 3 different duty cycles:
+    TIMER1CLK = SystemCoreClock / 108 = 1MHz
+
+    TIMER1 channel1 duty cycle = (4000/ 16000)* 100  = 25%
+    TIMER1 channel2 duty cycle = (8000/ 16000)* 100  = 50%
+    TIMER1 channel3 duty cycle = (12000/ 16000)* 100 = 75%
+    ----------------------------------------------------------------------- */
+    timer_oc_parameter_struct timer_ocintpara;
+    timer_parameter_struct timer_initpara;
+
+
+	switch(pwm_no)
+	{
+		case ADAS_PWM_1:
+			chno = TIMER_CH_2;
+			pin = GPIO_PIN_10;
+			break;
+		case ADAS_PWM_2:
+			chno = TIMER_CH_3;
+			pin = GPIO_PIN_11;
+			break;
+		default:
+			return;
+	}
+
+	rcu_periph_clock_enable(RCU_GPIOB);
+    rcu_periph_clock_enable(RCU_AF);
+
+    /*Configure PA1 PA2 PA3(TIMER1 CH1 CH2 CH3) as alternate function*/
+    gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, pin);	
+	gpio_pin_remap_config(GPIO_TIMER1_PARTIAL_REMAP1,ENABLE);
+
+
+	
+    rcu_periph_clock_enable(RCU_TIMER1);
+
+    timer_deinit(TIMER1);
+
+    /* TIMER1 configuration 2M*/
+    timer_initpara.prescaler         = 53;
+    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
+    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+    timer_initpara.period            = 49;
+    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
+    timer_initpara.repetitioncounter = 0;
+    timer_init(TIMER1,&timer_initpara);
+
+    /* CH2 and CH3 configuration in PWM mode1 */
+    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
+    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
+    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
+    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
+    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
+    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
+
+
+    timer_channel_output_config(TIMER1,chno,&timer_ocintpara);
+
+
+
+    /* CH2 configuration in PWM mode1,duty cycle 50% */
+    timer_channel_output_pulse_value_config(TIMER1,chno,24);
+    timer_channel_output_mode_config(TIMER1,chno,TIMER_OC_MODE_PWM0);
+    timer_channel_output_shadow_config(TIMER1,chno,TIMER_OC_SHADOW_DISABLE);
+
+  
+    /* auto-reload preload enable */
+    timer_auto_reload_shadow_enable(TIMER1);
+    /* auto-reload preload enable */
+    timer_enable(TIMER1);
+	
+}
+
+
+
+
+//***********************************************************************************************************************//
+void ADAS_Receive_Timer_Initial(void)
+{
+   
+    timer_parameter_struct timer_initpara;
+
+    rcu_periph_clock_enable(RCU_TIMER0);
+
+    timer_deinit(TIMER0);
+    /* initialize TIMER init parameter struct */
+    timer_struct_para_init(&timer_initpara);
+    /* TIMER1 configuration */
+    timer_initpara.prescaler         = 107;
+    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
+    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
+    timer_initpara.period            = 0xFFFFFFFF;
+    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
+	timer_initpara.repetitioncounter = 0;
+    timer_init(TIMER0, &timer_initpara);
+
+    timer_interrupt_disable(TIMER0, TIMER_INT_UP);
+    timer_disable(TIMER0);
+
+	//nvic_irq_enable(TIMER7_IRQn, 1, 0);
+	
+}
+
+void ADAS_Drv_IO_Initial(void)
+{
+	rcu_periph_clock_enable(RCU_GPIOC);
+	
+	gpio_init(GPIOC,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8|GPIO_PIN_9);
+
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_8);
+	exti_init(EXTI_8, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+    exti_interrupt_flag_clear(EXTI_8);
+
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_9);
+	exti_init(EXTI_9, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+    exti_interrupt_flag_clear(EXTI_9);
+}
+/*!
+    \brief      main function
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void ADAS_Drv_Initial(void)
+{
+    ADAS_PWM_IO_Reset();
+	
+	ADAS_Timer_Initial();
+
+	ADAS_Receive_Timer_Initial();
+
+	ADAS_Drv_IO_Initial();
+}
+
+
+
+

+ 20 - 0
Source/drv_adas.h

@@ -0,0 +1,20 @@
+#ifndef  __DRV_ADAS_H__
+#define  __DRV_ADAS_H__
+
+
+
+enum
+{
+	ADAS_PWM_0,
+	ADAS_PWM_1,
+	ADAS_PWM_2	
+};
+
+void ADAS_Drv_Initial(void);
+
+void ADAS_PWM_Initial(uint8_t pwm_no);
+
+void ADAS_PWM_IO_Reset(void);
+
+#endif
+

+ 138 - 0
Source/drv_adc.c

@@ -0,0 +1,138 @@
+#include "common.h" 
+#include "drv_adc.h"
+
+
+int8_t Sample_ADC_Value(uint8_t channel,uint16_t *ADC1ConvertedValue)
+{
+
+	    /* reset ADC */
+    adc_deinit(ADC0);
+    /* ADC mode config */
+    adc_mode_config(ADC_MODE_FREE);
+
+	adc_special_function_config(ADC0,ADC_SCAN_MODE,ENABLE);
+    /* ADC data alignment config */
+    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
+    /* ADC channel length config */
+    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);
+ 
+    /* ADC regular channel config */
+    adc_regular_channel_config(ADC0, 0, channel, ADC_SAMPLETIME_55POINT5);
+  
+
+    /* ADC trigger config */
+    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE);
+    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);
+    
+    /* ADC discontinuous mode */
+    //adc_discontinuous_mode_config(ADC0, ADC_REGULAR_CHANNEL, 3);
+
+    /* enable ADC interface */
+    adc_enable(ADC0);
+    delay_1ms(1);
+    /* ADC calibration and reset calibration */
+    adc_calibration_enable(ADC0);
+	
+	adc_software_trigger_enable(ADC0,ADC_REGULAR_CHANNEL);
+    while(SET != adc_flag_get(ADC0,ADC_FLAG_EOC));
+    *ADC1ConvertedValue = adc_regular_data_read(ADC0);
+	adc_flag_clear(ADC0,ADC_FLAG_EOC);
+	//printf("adc:%d\r\n",*ADC1ConvertedValue);
+	return 1;
+}
+
+
+int8_t adc_getResult_6t(unsigned char chNo, unsigned short* result)
+{
+	unsigned char i;
+	unsigned short Vsample[ADC_GETRESULT_6TIMES];
+	unsigned short Vaverage;
+	unsigned char s_min, s_max;
+	int ret;
+
+
+	if(result==(void*)0)
+	{
+		return(ADC_R_ERR_NULL);
+	}
+
+	for(i=0u;i<ADC_GETRESULT_6TIMES;i++)
+	{
+		ret=Sample_ADC_Value(chNo, &Vsample[i]);
+		if(ret <= 0)
+		{
+			return ADC_R_ERR_CHNUM;
+		}
+	}
+	
+	s_min = 0u;
+	s_max = 0u;
+	for(i=1u;i<ADC_GETRESULT_6TIMES;i++)
+	{
+		if(Vsample[s_min] > Vsample[i]){
+			s_min = i;
+		}
+		if(Vsample[s_max] < Vsample[i]){
+			s_max = i;
+		}
+	}
+
+	if(s_min == s_max)
+	{
+		*result = Vsample[0];
+		return(1);
+	}
+	else
+	{
+		Vaverage = 0u;
+		for(i=0u;i<ADC_GETRESULT_6TIMES;i++)
+			{
+			if((i != s_min) &&(i != s_max))
+				{
+				Vaverage += (Vsample[i] >> 2);
+			}
+		}
+	}
+	*result = Vaverage;
+	
+	return (1);
+}
+
+
+//**************************************************Measure_Temprature********************************************************
+
+void _Measure_Temprature_Initial(void)
+{
+	rcu_periph_clock_enable(RCU_GPIOC);
+	gpio_init(GPIOC,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_3);
+
+	/* enable GPIOA clock */
+    rcu_periph_clock_enable(RCU_GPIOA);
+    /* enable ADC0 clock */
+    rcu_periph_clock_enable(RCU_ADC0);
+    /* config ADC clock */
+    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);
+
+	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_0|GPIO_PIN_1);
+
+}
+
+
+//**************************************************vbat********************************************************
+void _Measure_Vol_Initial(void)
+{
+	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
+}
+
+/*void test_adc(void)
+{
+	uint16_t ADC1ConvertedValue;
+	
+	ADC_SoftwareStartConvCmd(ADC1,ENABLE);
+	//while(ADC_GetSoftwareStartConvStatus(ADC1));
+	while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
+    	ADC1ConvertedValue = ADC_GetConversionValue(ADC1);
+	ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
+}
+*/
+

+ 37 - 0
Source/drv_adc.h

@@ -0,0 +1,37 @@
+#ifndef  __DRV_DAC_H__
+#define  __DRV_DAC_H__
+
+
+#define ADC_GETRESULT_6TIMES	(6u)
+/*=== Return value. ===*/
+#define ADC_R_ERR_TIMEOUT		( -1 )
+#define ADC_R_ERR_NULL			( -2 )
+#define ADC_R_ERR_CHNUM			( -3 )
+
+enum
+{
+	adc_temperatrue_0 = ADC_CHANNEL_0,
+	adc_temperatrue_1 = ADC_CHANNEL_1,
+	adc_vbat = ADC_CHANNEL_5,
+
+	adc_max
+};
+
+
+#define Mea_Temp_Enable(x)  gpio_bit_write(GPIOC,GPIO_PIN_3,(bit_status)(x))
+
+
+int8_t Sample_ADC_Value(uint8_t channel,uint16_t *ADC1ConvertedValue);
+
+int8_t adc_getResult_6t(unsigned char chNo, unsigned short* result);
+
+//**************************************************Measure_Temprature********************************************************
+void _Measure_Temprature_Initial(void);
+
+
+//**************************************************vbat********************************************************
+void _Measure_Vol_Initial(void);
+
+
+#endif
+

+ 496 - 0
Source/drv_can.c

@@ -0,0 +1,496 @@
+#include "common.h"
+#include "drv_can.h"
+#include "drv_io.h"
+
+extern uint8_t work_normal;
+//********************************************************CAN-START**********************************************************
+static uint8_t can_tx_buf[CAN_TX_BUF_MAX];
+static uint8_t can_rx_ctr_self_buf[CAN_RX_BUF_MAX];
+static uint8_t can_rx_ctr_bro_buf[CAN_RX_CTR_BRO_BUF_MAX];
+static uint8_t can_rx_test_bro_buf[CAN_RX_TEST_BRO_BUF_MAX];
+
+can_parameter_struct can_parameter;
+can_filter_parameter_struct can_filter;
+
+#define CAN_BAUDRATE  250
+uint32_t filter_ctr_self_id = (CTR_ID << 10)|(SELF_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA;
+uint32_t filter_ctr_bro_id = (CTR_ID << 10)|(BROCAST_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA;
+
+#ifdef CONFIG_CAN_IAP
+uint32_t filter_test_bro_id = (PRINTF_TER_ID << 10)|(SELF_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA;
+#else
+uint32_t filter_test_bro_id = (PRINTF_TER_ID << 10)|(BROCAST_ID << 3)|CAN_FF_EXTENDED|CAN_FT_DATA;
+#endif
+
+CAN_FRAME can_ctr_self;
+CAN_FRAME can_ctr_bro;
+CAN_FRAME can_test_bro;
+static CAN_FRAME can_tx_frame;
+
+static uint8_t can_busy = 0;
+
+void Can_Stop_Send(void)
+{
+	can_busy = 0;
+}
+void Check_Can_Poll(void)
+{
+	if(work_normal)
+	{
+		if(can_error_get(CAN0) != CAN_ERROR_NONE)
+		{
+			Can_Power_Enable(0);
+			can_deinit(CAN0);
+			CAN_Config_HW();
+			Can_Power_Enable(1);
+			can_busy = 0;
+		}
+	}
+}
+static void Reset_Can_Rx_Buffer(CAN_FRAME*can_frame)
+{
+	if(can_frame == NULL)
+        return;
+    memset(&can_frame->head,0x00,sizeof(can_frame->head));
+	can_frame->len = 0;
+}
+
+uint16_t Get_Data_Can(CAN_FRAME*app_can_frame)
+{
+	CAN_FRAME* cf_temp = NULL;
+	
+    if(app_can_frame == NULL)
+        return 0;
+
+	if(get_index_total_value(can_ctr_self.head.index) != 0 && can_ctr_self.head.index == can_ctr_self.head.total&&can_ctr_self.len)
+		cf_temp = &can_ctr_self;
+	else if(get_index_total_value(can_ctr_bro.head.index) != 0 && can_ctr_bro.head.index == can_ctr_bro.head.total&&can_ctr_bro.len)
+		cf_temp = &can_ctr_bro;
+	else if(get_index_total_value(can_test_bro.head.index) != 0 && can_test_bro.head.index == can_test_bro.head.total&&can_test_bro.len)
+		cf_temp = &can_test_bro;
+
+	if(cf_temp == NULL)
+		return 0;
+	
+    memcpy(&app_can_frame->head,&cf_temp->head,sizeof(cf_temp->head));
+	memcpy(app_can_frame->data,cf_temp->data,cf_temp->len);
+	app_can_frame->len = cf_temp->len;
+
+    Reset_Can_Rx_Buffer(cf_temp);
+
+    return app_can_frame->len;
+    
+}
+
+
+
+int8_t Send_Data_Can(CAN_FRAME*app_can_frame,uint8_t from)
+{
+	can_trasnmit_message_struct can_tr_m;
+	uint32_t exid = 0;
+	
+
+
+	if(app_can_frame == NULL || can_busy || work_normal == 0)
+	    return 0;
+	
+	//Silent_Enable(0);
+	//delay_1us(100);
+	
+	memcpy(&can_tx_frame.head,&app_can_frame->head,sizeof(can_tx_frame.head));
+	can_tx_frame.len = app_can_frame->len;
+	memcpy(can_tx_frame.data,app_can_frame->data,can_tx_frame.len);
+
+
+	
+	memset(&can_tr_m,0x00,sizeof(can_tr_m));
+	memcpy(&exid,&can_tx_frame.head,sizeof(exid));
+	can_tr_m.tx_efid = (exid>>3);
+	can_tr_m.tx_ff = CAN_FF_EXTENDED;
+	can_tr_m.tx_ft = CAN_FT_DATA;
+
+	if(can_tx_frame.len > 8)
+		can_tr_m.tx_dlen = 8;
+	else
+		can_tr_m.tx_dlen = can_tx_frame.len;
+
+	memcpy(can_tr_m.tx_data,can_tx_frame.data,can_tr_m.tx_dlen);
+
+	if(can_message_transmit(CAN0,&can_tr_m) == CAN_NOMAILBOX)
+		return 0;
+
+	if(can_tx_frame.head.total != 1)
+	{
+		can_busy = 1;
+		can_interrupt_enable(CAN0, CAN_INT_TME);
+	}
+	
+    return 1;
+    
+}
+static void Can_NVIC_Config(void)
+{
+	nvic_irq_enable(USBD_HP_CAN0_TX_IRQn,3,0);
+	
+	nvic_irq_enable(USBD_LP_CAN0_RX0_IRQn,3,0);
+}
+
+
+
+
+/**
+  * @brief  Configures the CAN.
+  * @param  None
+  * @retval None
+  */
+void CAN_Config_HW(void)
+{   
+
+
+	/* enable CAN clock */
+    rcu_periph_clock_enable(RCU_CAN0);
+    rcu_periph_clock_enable(RCU_GPIOB);
+    rcu_periph_clock_enable(RCU_AF);
+    
+    /* configure CAN0 GPIO */
+    gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8);
+    gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);
+    gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP,ENABLE);
+
+	rcu_periph_clock_enable(RCU_GPIOA);
+	gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
+	Silent_Enable(0);
+
+
+    can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
+    can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
+    /* initialize CAN register */
+    can_deinit(CAN0);
+
+    /* initialize CAN parameters */
+    can_parameter.time_triggered = DISABLE;
+    can_parameter.auto_bus_off_recovery = DISABLE;
+    can_parameter.auto_wake_up = DISABLE;
+    can_parameter.auto_retrans = DISABLE;
+    can_parameter.rec_fifo_overwrite = DISABLE;
+    can_parameter.trans_fifo_order = DISABLE;
+    can_parameter.working_mode = CAN_NORMAL_MODE;
+    can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
+    can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
+    can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
+    
+    /* 1MBps */
+#if CAN_BAUDRATE == 1000
+    can_parameter.prescaler = 6;
+    /* 500KBps */
+#elif CAN_BAUDRATE == 500
+    can_parameter.prescaler = 12;
+    /* 250KBps */
+#elif CAN_BAUDRATE == 250
+    can_parameter.prescaler = 24;
+    /* 125KBps */
+#elif CAN_BAUDRATE == 125
+    can_parameter.prescaler = 48;
+    /* 100KBps */
+#elif  CAN_BAUDRATE == 100
+    can_parameter.prescaler = 60;
+    /* 50KBps */
+#elif  CAN_BAUDRATE == 50
+    can_parameter.prescaler = 120;
+    /* 20KBps */
+#elif  CAN_BAUDRATE == 20
+    can_parameter.prescaler = 300;
+#else
+    #error "please select list can baudrate in private defines in drv_can.c "
+#endif  
+    /* initialize CAN */
+    can_init(CAN0, &can_parameter);
+
+    
+    /* initialize filter */ 
+    can_filter.filter_number=0;
+    can_filter.filter_mode = CAN_FILTERMODE_MASK;
+    can_filter.filter_bits = CAN_FILTERBITS_32BIT;
+#if 1	
+    can_filter.filter_list_high = (uint16_t)(filter_ctr_self_id >> 16);
+    can_filter.filter_list_low = (uint16_t)(filter_ctr_self_id >> 0);
+    can_filter.filter_mask_high = 0x0001;
+    can_filter.filter_mask_low = 0xFFFF;
+#else
+	can_filter.filter_list_high = 0x0000;
+    can_filter.filter_list_low = 0x0000;
+    can_filter.filter_mask_high = 0x0000;
+    can_filter.filter_mask_low = 0x0000;
+#endif
+    can_filter.filter_fifo_number = CAN_FIFO0;
+    can_filter.filter_enable = ENABLE;
+    can_filter_init(&can_filter);
+    
+    /* CAN1 filter number */
+#if 1
+    can_filter.filter_number = 1;
+	can_filter.filter_list_high = (uint16_t)(filter_ctr_bro_id >> 16);
+    can_filter.filter_list_low = (uint16_t)(filter_ctr_bro_id >> 0);
+    can_filter_init(&can_filter);
+
+	can_filter.filter_number = 2;
+	can_filter.filter_list_high = (uint16_t)(filter_test_bro_id >> 16);
+    can_filter.filter_list_low = (uint16_t)(filter_test_bro_id >> 0);
+    can_filter_init(&can_filter);
+#endif
+
+    Can_NVIC_Config();
+
+   	can_interrupt_enable(CAN0, CAN_INT_RFNE0);
+    
+    
+}
+
+/**
+  * @brief  Configures the CAN.
+  * @param  None
+  * @retval None
+  */
+void CAN_Config(void)
+{   
+
+	memcpy(&can_ctr_self.head,&filter_ctr_self_id,sizeof(filter_ctr_self_id));
+	memcpy(&can_ctr_bro.head,&filter_ctr_bro_id,sizeof(filter_ctr_bro_id));
+	memcpy(&can_test_bro.head,&filter_test_bro_id,sizeof(filter_test_bro_id));
+	can_ctr_self.data = can_rx_ctr_self_buf;
+	can_ctr_bro.data = can_rx_ctr_bro_buf;
+	can_test_bro.data = can_rx_test_bro_buf;
+
+	memset(&can_tx_frame,0x00,sizeof(can_tx_frame));
+	memset(can_tx_buf,0x00,sizeof(can_tx_buf));
+	can_tx_frame.data = can_tx_buf;
+	
+	
+	/* enable CAN clock */
+    rcu_periph_clock_enable(RCU_CAN0);
+    rcu_periph_clock_enable(RCU_GPIOB);
+    rcu_periph_clock_enable(RCU_AF);
+    
+    /* configure CAN0 GPIO */
+    gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_8);
+    gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);
+    gpio_pin_remap_config(GPIO_CAN_PARTIAL_REMAP,ENABLE);
+
+	rcu_periph_clock_enable(RCU_GPIOA);
+	gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
+	//Silent_Enable(1);
+	Silent_Enable(0);
+
+    can_struct_para_init(CAN_INIT_STRUCT, &can_parameter);
+    can_struct_para_init(CAN_INIT_STRUCT, &can_filter);
+    /* initialize CAN register */
+    can_deinit(CAN0);
+
+    /* initialize CAN parameters */
+    can_parameter.time_triggered = DISABLE;
+    can_parameter.auto_bus_off_recovery = DISABLE;
+    can_parameter.auto_wake_up = DISABLE;
+    can_parameter.auto_retrans = DISABLE;
+    can_parameter.rec_fifo_overwrite = DISABLE;
+    can_parameter.trans_fifo_order = DISABLE;
+    can_parameter.working_mode = CAN_NORMAL_MODE;
+    can_parameter.resync_jump_width = CAN_BT_SJW_1TQ;
+    can_parameter.time_segment_1 = CAN_BT_BS1_5TQ;
+    can_parameter.time_segment_2 = CAN_BT_BS2_3TQ;
+    
+    /* 1MBps */
+#if CAN_BAUDRATE == 1000
+    can_parameter.prescaler = 6;
+    /* 500KBps */
+#elif CAN_BAUDRATE == 500
+    can_parameter.prescaler = 12;
+    /* 250KBps */
+#elif CAN_BAUDRATE == 250
+    can_parameter.prescaler = 24;
+    /* 125KBps */
+#elif CAN_BAUDRATE == 125
+    can_parameter.prescaler = 48;
+    /* 100KBps */
+#elif  CAN_BAUDRATE == 100
+    can_parameter.prescaler = 60;
+    /* 50KBps */
+#elif  CAN_BAUDRATE == 50
+    can_parameter.prescaler = 120;
+    /* 20KBps */
+#elif  CAN_BAUDRATE == 20
+    can_parameter.prescaler = 300;
+#else
+    #error "please select list can baudrate in private defines in drv_can.c "
+#endif  
+    /* initialize CAN */
+    can_init(CAN0, &can_parameter);
+
+    
+    /* initialize filter */ 
+    can_filter.filter_number=0;
+    can_filter.filter_mode = CAN_FILTERMODE_MASK;
+    can_filter.filter_bits = CAN_FILTERBITS_32BIT;
+#if 1	
+    can_filter.filter_list_high = (uint16_t)(filter_ctr_self_id >> 16);
+    can_filter.filter_list_low = (uint16_t)(filter_ctr_self_id >> 0);
+    can_filter.filter_mask_high = 0x0001;
+    can_filter.filter_mask_low = 0xFFFF;
+#else
+	can_filter.filter_list_high = 0x0000;
+    can_filter.filter_list_low = 0x0000;
+    can_filter.filter_mask_high = 0x0000;
+    can_filter.filter_mask_low = 0x0000;
+#endif
+    can_filter.filter_fifo_number = CAN_FIFO0;
+    can_filter.filter_enable = ENABLE;
+    can_filter_init(&can_filter);
+    
+    /* CAN1 filter number */
+#if 1
+    can_filter.filter_number = 1;
+	can_filter.filter_list_high = (uint16_t)(filter_ctr_bro_id >> 16);
+    can_filter.filter_list_low = (uint16_t)(filter_ctr_bro_id >> 0);
+    can_filter_init(&can_filter);
+
+	can_filter.filter_number = 2;
+	can_filter.filter_list_high = (uint16_t)(filter_test_bro_id >> 16);
+    can_filter.filter_list_low = (uint16_t)(filter_test_bro_id >> 0);
+    can_filter_init(&can_filter);
+#endif
+
+    Can_NVIC_Config();
+
+   	can_interrupt_enable(CAN0, CAN_INT_RFNE0);
+    
+    
+}
+
+
+void USBD_HP_CAN0_TX_IRQHandler(void)
+{
+	can_trasnmit_message_struct can_tr_m;
+	uint32_t exid = 0;
+	
+	if(can_tx_frame.head.index != can_tx_frame.head.total)
+	{
+		can_tx_frame.head.index++;
+		
+		memset(&can_tr_m,0x00,sizeof(can_tr_m));
+		memcpy(&exid,&can_tx_frame.head,sizeof(exid));
+		can_tr_m.tx_efid = (exid>>3);
+		can_tr_m.tx_ff = CAN_FF_EXTENDED;
+		can_tr_m.tx_ft = CAN_FT_DATA;
+		exid = get_index_total_value(can_tx_frame.head.index) -1;
+		exid <<= 3;
+		
+		if(can_tx_frame.head.index != can_tx_frame.head.total)
+			can_tr_m.tx_dlen = 8;
+		else
+			can_tr_m.tx_dlen = can_tx_frame.len - exid;
+
+		memcpy(can_tr_m.tx_data,&can_tx_frame.data[exid],can_tr_m.tx_dlen);
+
+		can_message_transmit(CAN0,&can_tr_m);
+	}
+	else
+	{
+		can_busy = 0;
+		can_interrupt_disable(CAN0, CAN_INT_TME);
+		//Silent_Enable(1);
+	}
+	
+}
+
+void USBD_LP_CAN0_RX0_IRQHandler(void)
+{
+	can_receive_message_struct Rxmessage;
+	CAN_FRAME* cf_temp;
+	uint32_t head,buf_max;
+	
+	can_message_receive(CAN0, CAN_FIFO0, &Rxmessage);
+
+	switch(Rxmessage.rx_fi)
+	{
+		case 0:
+			cf_temp = &can_ctr_self;
+			buf_max = sizeof(can_rx_ctr_self_buf);
+			break;
+		case 1:
+			cf_temp = &can_ctr_bro;
+			buf_max = sizeof(can_rx_ctr_bro_buf);
+			break;
+		case 2:
+			cf_temp = &can_test_bro;
+			buf_max = sizeof(can_rx_test_bro_buf);	
+			break;
+		default:return;
+	}
+	head = (Rxmessage.rx_efid << 3)|(Rxmessage.rx_ff)|(Rxmessage.rx_ft);
+	memcpy(&cf_temp->head,&head,sizeof(head));
+
+
+	if(get_index_total_value(cf_temp->head.index) > get_index_total_value(cf_temp->head.total))
+		return;
+	
+	head = get_index_total_value(cf_temp->head.total)*8UL;
+	if(head > buf_max)
+		return;
+
+	head = get_index_total_value(cf_temp->head.index) - 1;
+
+	memcpy(&cf_temp->data[head<<3],Rxmessage.rx_data,Rxmessage.rx_dlen);
+	if(get_index_total_value(cf_temp->head.index) == get_index_total_value(cf_temp->head.total))
+	{
+		cf_temp->len = (head << 3) + Rxmessage.rx_dlen;
+		//g_event |= EVENT_CAN_RECEIVE_FINISH;
+	}
+
+	
+}
+
+
+
+#if 1
+
+// 
+//ÓÃÓÚϵͳµ÷ÓÃprintf
+//
+#ifdef __GNUC__
+  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
+     set to 'Yes') calls __io_putchar() */
+#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
+#else
+#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
+#endif /* __GNUC__ */
+
+PUTCHAR_PROTOTYPE
+{
+	if(work_normal)
+	{
+		can_trasnmit_message_struct can_tr_m;
+
+		memset(&can_tr_m,0x00,sizeof(can_tr_m));
+
+		can_tr_m.tx_efid = (SELF_ID << 7)|(PRINTF_TER_ID << 0);
+		can_tr_m.tx_ff = CAN_FF_EXTENDED;
+		can_tr_m.tx_ft = CAN_FT_DATA;
+		can_tr_m.tx_dlen = 1;
+		can_tr_m.tx_data[0] = (uint8_t)ch;
+
+		can_message_transmit(CAN0,&can_tr_m);
+
+		delay_1us(500);
+	}
+	
+	return ch;
+}
+
+#endif
+//********************************************************CAN-END**********************************************************
+
+
+
+
+
+
+

+ 102 - 0
Source/drv_can.h

@@ -0,0 +1,102 @@
+#ifndef DRV_CAN_H
+#define DRV_CAN_H
+
+#define FRAME_PRO_0 (0)
+#define FRAME_PRO_1 (1)
+#define FRAME_PRO_2 (2)
+#define FRAME_PRO_3 (3)
+#define FRAME_PRO_4 (4)
+#define FRAME_PRO_5 (5)
+#define FRAME_PRO_6 (6)
+#define FRAME_PRO_7 (7)
+#define FRAME_PRO_D (FRAME_PRO_0)
+
+#define FRAME_PT_NEED_RSP  (1)
+#define FRAME_PT_RSP       (2)
+#define FRAME_PT_NO_RSP    (3)
+
+
+#define PRINTF_TER_ID  (0x45UL)
+#define SELF_ID  (0x42UL)
+#define CTR_ID   (0x43UL)
+#define BROCAST_ID   (0x7FUL)
+
+#define CAN_TX_BUF_MAX    (256)
+#define CAN_RX_BUF_MAX    (256)
+#define CAN_RX_CTR_BRO_BUF_MAX  (256)
+#define CAN_RX_TEST_BRO_BUF_MAX (256)
+
+
+#define get_index_total_value(x) ((x)?(x):(32))
+#define Silent_Enable(x) gpio_bit_write(GPIOA,GPIO_PIN_7,(bit_status)(x))
+
+
+#pragma  pack (push,1)  
+typedef struct
+{
+	uint32_t other:3;
+	uint32_t dest:7;
+	uint32_t sour:7;
+	uint32_t index:5;
+	uint32_t total:5;
+	uint32_t rsp:2;
+	uint32_t pro:3;
+}HEAD;
+typedef struct
+{
+	HEAD head;
+	uint8_t* data;
+	uint16_t len;
+}CAN_FRAME;
+#pragma pack(pop)
+
+extern CAN_FRAME can_ctr_self;
+extern CAN_FRAME can_ctr_bro;
+extern CAN_FRAME can_test_bro;
+
+enum
+{
+	BMS_1_SELF,
+	BMS_1_CUR_VOL_SELF,
+	BMS_1_RSP,
+	BMS_1_RESEND,
+	TIMEOUT_BMS_1_RESEND,
+	
+	BMS_2_SELF,
+	BMS_2_CUR_VOL_SELF,
+	BMS_2_RSP,
+	BMS_2_RESEND,
+	TIMEOUT_BMS_2_RESEND,
+
+	CTR_SELF,
+	CTR_RSP,
+	CTR_RESEND,
+	TIMEOUT_CTR_RESEND,
+
+	ADAS_SELF,
+	ADAS_RSP,
+	ADAS_RESEND,
+	TIMEOUT_ADAS_RESEND,
+
+	
+	OTHER_SEND,
+
+
+	CAN_TEST
+};
+
+void CAN_Config_HW(void);
+
+void CAN_Config(void);
+
+uint16_t Get_Data_Can(CAN_FRAME*app_can_frame);
+
+int8_t Send_Data_Can(CAN_FRAME*app_can_frame,uint8_t from);
+
+void Check_Can_Poll(void);
+
+void Can_Stop_Send(void);
+
+#endif
+
+

+ 495 - 0
Source/drv_io.c

@@ -0,0 +1,495 @@
+#include "common.h" 
+#include "drv_io.h"
+#include "hardware_test.h"
+#include "app_rs485_1.h"
+
+CHECK_CHARGER check_charger;
+DELAY_COMMON side_stay_dec_delay;
+DELAY_COMMON sti_dec_delay;
+DELAY_COMMON repair_dec_delay;
+DELAY_COMMON qd_dec_delay;
+DELAY_COMMON xl_dec_delay;
+DELAY_COMMON acc2_dec_delay;
+DELAY_COMMON acc2_delay;
+
+DELAY_COMMON left_light_delay;
+DELAY_COMMON right_light_delay;
+
+DELAY_COMMON shield_xl;
+
+DELAY_COMMON charge_delay;
+
+CTR_DELAY_COMMON soak_dec_delay;
+
+uint32_t xl_count = 0;
+
+#define ACC2_USE_PWM (1)
+
+uint8_t battery_charged_full = 0;
+uint8_t QD_switch_from = 0;
+
+
+extern void S11_FL_On(uint8_t on);
+extern uint8_t S11_May_Operate(void);
+
+void Check_S11_May_Operate(void)
+{
+	if(QD_Dect() == 0 && ACC2_Is_On() == 0 && S11_May_Operate())
+		S11_FL_On(0);
+}
+void Check_S11(uint8_t on,uint8_t from)
+{
+	if(on)
+	{
+		if(S11_May_Operate())
+			S11_FL_On(1);
+			
+	}
+	else
+	{
+		if(S11_May_Operate())
+		{
+			switch(from)
+			{
+				case FROM_QD:
+					if(ACC2_Is_On() == 0)
+						S11_FL_On(0);	
+					break;
+				case FROM_ACC12:
+					if(QD_Dect() == 0)
+						S11_FL_On(0);	
+					break;
+				default:
+					return;
+			} 
+		}
+	}
+}
+void QD_Enable_From(uint8_t on,uint8_t from)
+{
+	Check_S11(on,FROM_QD);
+	QD_Enable(on);
+	QD_switch_from = from;
+}
+
+uint8_t ACC2_Is_On(void)
+{
+	if(acc2_delay.set == 0&&(gpio_output_bit_get(GPIOC,GPIO_PIN_15) == 0|ACC2_Over_Loader_Dect()== 0))
+		return 0;
+	else
+		return 1;
+
+}
+
+void ACC2_PWM(void)
+{
+	if(acc2_delay.set)
+	{
+		++acc2_delay.count;
+		if(acc2_delay.count >= ACC2_ENABLE_TIMEOUT)
+		{
+			gpio_bit_write(GPIOC,GPIO_PIN_15,(bit_status)0x01);
+			memset(&acc2_delay,0x00,sizeof(acc2_delay));
+		}
+		else
+			gpio_bit_write(GPIOC,GPIO_PIN_15,(bit_status)(acc2_delay.count&0x01));
+	}
+	
+}
+void ACC2_Enable(uint8_t on)
+{
+#if ACC2_USE_PWM
+	Check_S11(on,FROM_ACC12);
+	
+	if(on)
+	{
+		acc2_delay.set = 1;
+		acc2_delay.count = 0;
+		FL_Enable(1);
+	}
+	else
+	{
+		memset(&acc2_delay,0x00,sizeof(acc2_delay));
+		gpio_bit_write(GPIOC,GPIO_PIN_15,(bit_status)0x00);
+	}
+#else
+	gpio_bit_write(GPIOC,GPIO_PIN_15,(bit_status)(on));
+#endif
+}
+void E_CTR_Dec_IRQ_Initial(void)
+{
+	rcu_periph_clock_enable(RCU_AF);
+	
+	nvic_irq_enable(EXTI10_15_IRQn,1,0);
+	
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_10);
+	exti_init(EXTI_10, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+    exti_interrupt_flag_clear(EXTI_10);
+	
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_11);
+	exti_init(EXTI_11, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+    exti_interrupt_flag_clear(EXTI_11);
+	
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_12);
+	exti_init(EXTI_12, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+    exti_interrupt_flag_clear(EXTI_12);
+
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_14);
+	exti_init(EXTI_14, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
+	exti_interrupt_flag_clear(EXTI_14);
+
+	//QD
+	nvic_irq_enable(EXTI5_9_IRQn,1,0);
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_6);
+	exti_init(EXTI_6, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+    exti_interrupt_flag_clear(EXTI_6);
+
+	//ACC2
+	nvic_irq_enable(EXTI0_IRQn,1,0);
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOD, GPIO_PIN_SOURCE_0);
+	exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+    exti_interrupt_flag_clear(EXTI_0);
+
+	//XL
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_7);
+	exti_init(EXTI_7, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
+    exti_interrupt_flag_clear(EXTI_7);
+
+	
+}
+void E_CTR_Initial(void)
+{
+	/* enable the clock of peripherals */
+    rcu_periph_clock_enable(RCU_GPIOC);
+	gpio_init(GPIOC,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_15);
+	ACC2_Enable(0);
+	
+	gpio_init(GPIOC,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_14);
+
+	rcu_periph_clock_enable(RCU_GPIOD);
+	rcu_periph_clock_enable(RCU_AF);
+	gpio_pin_remap_config(GPIO_PD01_REMAP,ENABLE);
+	gpio_init(GPIOD,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
+	//
+	gpio_init(GPIOC,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_6|GPIO_PIN_7);
+	Left_Light_Enable(0);
+	Right_Light_Enable(0);
+
+	rcu_periph_clock_enable(RCU_GPIOB);
+	gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0|GPIO_PIN_1);
+	Tail_Light_Enable(0);
+	Carpet_Light_Enable(0);
+
+	//
+	gpio_init(GPIOC,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13);
+
+	//
+	rcu_periph_clock_enable(RCU_GPIOB);
+	//gpio_pin_remap_config(GPIO_SWJ_NONJTRST_REMAP,ENABLE);
+	gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_5|GPIO_PIN_4);
+	Lock_Enable(0);
+	//QD_Enable(0);
+	QD_Enable_From(0,5);
+	gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_6|GPIO_PIN_7);
+
+	E_CTR_Dec_IRQ_Initial();
+
+	side_stay_dec_delay.set = 1;
+	side_stay_dec_delay.count = SIDE_STAY_DEC_TIMEOUT;
+	soak_dec_delay.enable = 1;
+	soak_dec_delay.set = 1;
+	soak_dec_delay.count = SOAK_DEC_TIMEOUT;
+	sti_dec_delay.set = 1;
+	sti_dec_delay.count = STI_DEC_TIMEOUT;
+	repair_dec_delay.set = 1;
+	repair_dec_delay.count = REPAIR_DEC_TIMEOUT;
+	qd_dec_delay.set = 1;
+	qd_dec_delay.count = QD_DEC_TIMEOUT;
+	xl_dec_delay.set = 1;
+	xl_dec_delay.count = XL_DEC_TIMEOUT;
+	acc2_dec_delay.set = 1;
+	acc2_dec_delay.count = ACC2_DEC_TIMEOUT;
+	
+
+	memset(&left_light_delay,0x00,sizeof(DELAY_COMMON));
+	memset(&right_light_delay,0x00,sizeof(DELAY_COMMON));
+
+	memset(&shield_xl,0x00,sizeof(DELAY_COMMON));
+	
+}
+
+void _CB_Operate_Initial(void)
+{
+	rcu_periph_clock_enable(RCU_GPIOB);
+	gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_15|GPIO_PIN_13|GPIO_PIN_14);
+	
+}
+
+void Charge_Dec_IRQ_Initial(void)
+{
+	rcu_periph_clock_enable(RCU_AF);
+	
+	nvic_irq_enable(EXTI4_IRQn,1,0);
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_4);
+	exti_init(EXTI_4, EXTI_INTERRUPT, EXTI_TRIG_BOTH);
+    exti_interrupt_flag_clear(EXTI_4);
+	
+}
+void GPIO_Initial(void)
+{
+	rcu_periph_clock_enable(RCU_GPIOA);
+	rcu_periph_clock_enable(RCU_GPIOB);
+	rcu_periph_clock_enable(RCU_GPIOC);
+	rcu_periph_clock_enable(RCU_AF);
+	
+	gpio_init(GPIOC,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
+	gpio_init(GPIOC,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_1|GPIO_PIN_2);
+
+	//
+	gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_12);
+
+#if 0
+#if 1
+	gpio_bit_reset(GPIOA,GPIO_PIN_12);
+	gpio_bit_reset(GPIOA,GPIO_PIN_8);
+
+#else	
+	gpio_bit_set(GPIOA,GPIO_PIN_12);
+	gpio_bit_set(GPIOA,GPIO_PIN_8);
+#endif
+#else
+	//test-start
+	Can_Power_Enable(0);
+	//test-end
+#endif
+
+	
+	//
+	gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP,ENABLE);
+	gpio_init(GPIOA,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_15);
+	gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_3);
+	Enable_12V(0);
+	
+	//CHARGER
+	
+	gpio_init(GPIOC,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_4);
+	
+	gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_12);
+
+	Charge_Dec_IRQ_Initial();
+
+
+
+	//
+	gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_2);
+	FL_Enable(0);
+	
+	
+}
+
+void Set_Charger_In(uint8_t value)
+{
+	if(battery_charged_full == 0)
+	{
+		check_charger.cc_is_charger_in = value;
+		if(value)
+			cang_wei = CW_CHE_SHANG_CHARGER;
+		else
+			cang_wei = CW_CHE_SHANG_NO_CHARGER;
+	}
+}
+uint8_t IS_CHARGE_IN(void)
+{
+	return check_charger.cc_is_charger_in;
+}
+
+void Check_Charger_Timeout(void)
+{
+#if 0
+	if(check_charger.cc_set)
+	{
+		if(++check_charger.cc_time_count >= CC_TIME_OUT_COUNT)
+		{
+			if(check_charger.cc_pulse_count >= CC_PULSE_MIN_COUNT)
+			{
+				check_charger.cc_is_charger_in = 1;	
+			}
+			else if(check_charger.cc_pull_out_set == 0)
+			{
+				check_charger.cc_is_charger_in = 1;	
+			}
+			else 
+			{
+				check_charger.cc_is_charger_in = 0;	
+			}
+			check_charger.cc_set = 0;
+			check_charger.cc_time_count = 0;
+			check_charger.cc_pulse_count = 0;
+		}
+	}
+#endif
+
+	if(charge_delay.set)
+		charge_delay.count++;
+	
+#if 0
+	if(check_charger.cc_pull_out_set)
+	{
+		if(++check_charger.cc_pull_out_time_count >= CC_PULL_OUT_TIME_OUT_COUNT)
+		{
+			memset(&check_charger, 0x00,sizeof(check_charger));	
+		}
+	}
+#endif
+}
+
+void EXTI0_IRQHandler(void)
+{
+	if (RESET != exti_interrupt_flag_get(EXTI_0))
+	{  
+        exti_interrupt_flag_clear(EXTI_0);
+		acc2_dec_delay.set = 1;
+		acc2_dec_delay.count = 0;
+    }
+}
+void EXTI1_IRQHandler(void)
+{
+
+	if (RESET != exti_interrupt_flag_get(EXTI_1))
+	{  
+        exti_interrupt_flag_clear(EXTI_1);
+    }
+}
+void EXTI3_IRQHandler(void)
+{
+	if (RESET != exti_interrupt_flag_get(EXTI_3))
+	{  
+        exti_interrupt_flag_clear(EXTI_3);
+    }
+}
+void EXTI4_IRQHandler(void)
+{
+	if (RESET != exti_interrupt_flag_get(EXTI_4))
+	{  
+        exti_interrupt_flag_clear(EXTI_4);
+
+		if(gpio_input_bit_get(GPIOC,GPIO_PIN_4) == 0)
+		{
+#if 0
+			if( check_charger.cc_is_charger_in)
+				return;
+			
+			if(check_charger.cc_set == 0)
+			{
+				check_charger.cc_set = 1;
+				check_charger.cc_time_count = 0;
+				check_charger.cc_pulse_count = 0;
+			}
+			
+			check_charger.cc_pulse_count++;
+#else
+		Set_Charger_In(1);
+#endif
+		}
+#if 0
+		else
+		{
+			if( check_charger.cc_is_charger_in == 0)
+				return;
+
+			check_charger.cc_pull_out_set = 1;
+			check_charger.cc_pull_out_time_count = 0;
+		}
+#endif		
+    }
+}
+
+void EXTI5_9_IRQHandler(void)
+{
+	if (RESET != exti_interrupt_flag_get(EXTI_5))
+	{  
+        exti_interrupt_flag_clear(EXTI_5);
+    }
+
+	if (RESET != exti_interrupt_flag_get(EXTI_6))
+	{  
+        exti_interrupt_flag_clear(EXTI_6);
+		qd_dec_delay.set = 1;
+		qd_dec_delay.count = 0;
+    }
+
+	if (RESET != exti_interrupt_flag_get(EXTI_7))
+	{  
+        exti_interrupt_flag_clear(EXTI_7);
+		if(shield_xl.set == 0)
+			++xl_count;
+		else
+			xl_count = 0;
+    }
+	
+	if (RESET != exti_interrupt_flag_get(EXTI_8))
+	{  
+        exti_interrupt_flag_clear(EXTI_8);
+		extern void ADAS_Measure_Ju_Li_1(void);
+		ADAS_Measure_Ju_Li_1();
+    }
+	if (RESET != exti_interrupt_flag_get(EXTI_9))
+	{  
+        exti_interrupt_flag_clear(EXTI_9);
+		extern void ADAS_Measure_Ju_Li_2(void);
+		ADAS_Measure_Ju_Li_2();
+    }
+
+	
+}
+
+void EXTI10_15_IRQHandler(void)
+{
+	if (RESET != exti_interrupt_flag_get(EXTI_10))
+	{  
+        exti_interrupt_flag_clear(EXTI_10);
+		side_stay_dec_delay.set = 1;
+		side_stay_dec_delay.count = 0;
+    }
+	if (RESET != exti_interrupt_flag_get(EXTI_11))
+	{  
+        exti_interrupt_flag_clear(EXTI_11);
+		if(soak_dec_delay.enable)
+		{
+			soak_dec_delay.set = 1;
+			soak_dec_delay.count = 0;
+		}
+    }
+	if (RESET != exti_interrupt_flag_get(EXTI_12))
+	{  
+        exti_interrupt_flag_clear(EXTI_12);
+		sti_dec_delay.set = 1;
+		sti_dec_delay.count = 0;
+    }
+
+	if (RESET != exti_interrupt_flag_get(EXTI_13))
+	{  
+        exti_interrupt_flag_clear(EXTI_13);
+		
+    }
+	
+	if (RESET != exti_interrupt_flag_get(EXTI_14))
+	{  
+        exti_interrupt_flag_clear(EXTI_14);
+
+		if(ht_mode)
+		{
+			over_12V = 1;
+			return;
+		}
+		extern void ACC12_OVER_Loader_Interrupt(void);
+		ACC12_OVER_Loader_Interrupt();
+	
+		
+    }
+	if (RESET != exti_interrupt_flag_get(EXTI_15))
+	{  
+        exti_interrupt_flag_clear(EXTI_15);
+    }
+}
+

+ 109 - 0
Source/drv_io.h

@@ -0,0 +1,109 @@
+#ifndef  __GPIO_Init_H__
+#define  __GPIO_Init_H__
+
+
+#define Can_Power_Enable(on) gpio_bit_write(GPIOA,GPIO_PIN_12,(bit_status)(!on))
+#define FL_Enable(on) gpio_bit_write(GPIOB,GPIO_PIN_2,(bit_status)(!on))
+
+#define Lock_Enable(on) gpio_bit_write(GPIOB,GPIO_PIN_4,(bit_status)(on))
+#define QD_Enable(on) gpio_bit_write(GPIOB,GPIO_PIN_5,(bit_status)(on))
+//#define ACC2_Enable(on) gpio_bit_write(GPIOC,GPIO_PIN_15,(bit_status)(on))
+#define Left_Light_Enable(on) gpio_bit_write(GPIOC,GPIO_PIN_6,(bit_status)(on))
+#define Right_Light_Enable(on) gpio_bit_write(GPIOC,GPIO_PIN_7,(bit_status)(on))
+#define Tail_Light_Enable(on) gpio_bit_write(GPIOB,GPIO_PIN_0,(bit_status)(on))
+#define Carpet_Light_Enable(on) gpio_bit_write(GPIOB,GPIO_PIN_1,(bit_status)(on))
+
+#define Side_Stay_Dect() gpio_input_bit_get(GPIOC,GPIO_PIN_10)
+#define Soak_Dect() !gpio_input_bit_get(GPIOC,GPIO_PIN_11)
+#define Sitting_Dect() gpio_input_bit_get(GPIOC,GPIO_PIN_12)
+#define Repair_Key_Dect() gpio_input_bit_get(GPIOC,GPIO_PIN_13)
+#define QD_Dect() (!gpio_input_bit_get(GPIOB,GPIO_PIN_6))
+#define XL_Dect() gpio_input_bit_get(GPIOB,GPIO_PIN_7)
+#define ACC2_Dect() (!gpio_input_bit_get(GPIOD,GPIO_PIN_0))
+#define ACC2_Over_Loader_Dect() gpio_input_bit_get(GPIOC,GPIO_PIN_14)
+
+#define Lock_Dect() gpio_output_bit_get(GPIOB,GPIO_PIN_4)
+#define Carpet_Dect() gpio_output_bit_get(GPIOB,GPIO_PIN_1)
+#define Tail_Dect() gpio_output_bit_get(GPIOB,GPIO_PIN_0)
+#define Enable_12V(on) gpio_bit_write(GPIOB,GPIO_PIN_3,(bit_status)(on))
+#define V12_On_Dect() (!gpio_input_bit_get(GPIOA,GPIO_PIN_15))
+
+#define CHARGE_DEC_TIMEOUT  (100)
+#define SIDE_STAY_DEC_TIMEOUT  (100)
+#define SOAK_DEC_TIMEOUT  (2000)
+#define STI_DEC_TIMEOUT  (100)
+#define REPAIR_DEC_TIMEOUT  (100)
+#define QD_DEC_TIMEOUT  (100)
+#define XL_DEC_TIMEOUT  (100)
+#define ACC2_DEC_TIMEOUT  (100)
+#define ACC2_ENABLE_TIMEOUT  (100)
+#define CC_PULSE_MIN_COUNT   (2)
+#define CC_TIME_OUT_COUNT   (3000)
+#define CC_PULL_OUT_TIME_OUT_COUNT   (3000)
+typedef struct
+{
+	uint8_t cc_set;
+	uint16_t cc_time_count;
+	uint8_t cc_is_charger_in;
+	uint32_t cc_pulse_count;
+
+	uint8_t cc_pull_out_set;
+	uint16_t cc_pull_out_time_count;
+	
+}CHECK_CHARGER;
+
+extern CHECK_CHARGER check_charger;
+extern DELAY_COMMON side_stay_dec_delay;
+extern CTR_DELAY_COMMON soak_dec_delay;
+extern DELAY_COMMON sti_dec_delay;
+extern DELAY_COMMON repair_dec_delay;
+extern DELAY_COMMON qd_dec_delay;
+extern DELAY_COMMON xl_dec_delay;
+extern DELAY_COMMON acc2_dec_delay;
+extern DELAY_COMMON acc2_delay;
+extern DELAY_COMMON left_light_delay;
+extern DELAY_COMMON right_light_delay;
+
+extern DELAY_COMMON shield_xl;
+
+extern uint32_t xl_count;
+extern DELAY_COMMON charge_delay;
+extern uint8_t battery_charged_full;
+extern uint8_t QD_switch_from;
+
+enum
+{
+	FROM_QD,
+	FROM_ACC12,
+	
+
+	FROM_MAX
+};
+
+
+void _CB_Operate_Initial(void);
+
+void GPIO_Initial(void);
+
+void E_CTR_Initial(void);
+
+void ACC2_PWM(void);
+
+void ACC2_Enable(uint8_t on);
+
+void Check_Charger_Timeout(void);
+
+uint8_t IS_CHARGE_IN(void);
+
+void Set_Charger_In(uint8_t value);
+
+void QD_Enable_From(uint8_t on,uint8_t from);
+
+uint8_t IS_CHARGE_IN(void);
+
+uint8_t ACC2_Is_On(void);
+
+void Check_S11_May_Operate(void);
+
+#endif
+

+ 187 - 0
Source/drv_usart.c

@@ -0,0 +1,187 @@
+#include "common.h" 
+#include "drv_usart.h"
+
+ /* transmit buffer and receive buffer */
+static uint8_t tx_buffer[TX_BUFFER_SIZE];
+static uint8_t rx_buffer[RX_BUFFER_SIZE];
+/* counter of transmit buffer and receive buffer */
+static uint16_t tx_count = 0, rx_count = 0;
+/* size of transmit buffer and receive buffer */
+static uint32_t /*rx_buffer_size ,*/ tx_buffer_size;
+
+DELAY_COMMON uart1_tout;
+
+
+void Enable_Uart1_Timer(uint8_t enable,uint16_t timeout)
+{
+	if(enable)
+	{
+		uart1_tout.set = 1;
+		uart1_tout.count = timeout;
+	}
+	else
+	memset(&uart1_tout,0x00,sizeof(uart1_tout));
+	
+}
+
+static void Reset_RX_Buffer(void)
+{
+	memset(rx_buffer,0x00,sizeof(rx_buffer));
+	rx_count = 0;
+}
+
+uint16_t Get_RS485_Data(uint8_t * dbuf,uint16_t dbuf_len)
+{
+	if(dbuf == NULL || dbuf_len < rx_count)
+		return 0;
+
+	memcpy(dbuf,rx_buffer,rx_count);
+	dbuf_len = rx_count;
+	Reset_RX_Buffer();
+	
+	return dbuf_len;
+}
+
+
+
+int8_t Send_Data_RS485(uint8_t*data,uint16_t size)
+{
+	if(data == NULL || size == 0 || size > sizeof(tx_buffer))
+		return 0;
+
+	
+	memcpy(tx_buffer,data,size);
+	tx_count = 0;
+	tx_buffer_size = size;
+	
+	//
+#if 0
+
+	do
+	{
+		while(RESET == usart_flag_get(USART0, USART_FLAG_TC));
+		usart_data_transmit(USART0,tx_buffer[tx_count++]);
+	}while(tx_count < tx_buffer_size);
+#else
+	//while(RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC));
+	//USART_SendData(USART1,tx_buffer[tx_count++]);
+	usart_interrupt_enable(USART0, USART_INT_TC);
+	usart_interrupt_flag_get(USART0, USART_INT_TC);
+#endif	
+	return 1;
+}
+
+
+
+/*
+ * 函数名:USART1_Config
+ * 描述  :USART1 GPIO 配置,工作模式配置。9600 8-N-1
+ * 输入  :无
+ * 输出  : 无
+ * 调用  :外部调用
+ */
+void Usart1_Initial(void)
+{
+
+	
+	/* enable GPIO clock */
+    rcu_periph_clock_enable(RCU_GPIOA);
+	rcu_periph_clock_enable(RCU_AF);
+	rcu_periph_clock_enable(RCU_USART0);
+    /* connect port to USARTx_Tx */
+    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
+
+    /* connect port to USARTx_Rx */
+    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
+
+    /* USART configure */
+	/* enable USART clock */
+    
+    usart_deinit(USART0);
+    usart_baudrate_set(USART0, USART_0_BAUND);
+    usart_word_length_set(USART0, USART_WL_8BIT);
+    usart_stop_bit_set(USART0, USART_STB_1BIT);
+    usart_parity_config(USART0, USART_PM_NONE);
+    usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
+    usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
+    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
+    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
+	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
+	nvic_irq_enable(USART0_IRQn, 1, 0);
+	usart_interrupt_enable(USART0, USART_INT_RBNE);
+
+#if UART_0_IDAR
+	/*USART_ClockInitTypeDef  USART_ClockInitStruct; 
+
+	USART_ClockInitStruct.USART_Clock = USART_Clock_Disable;
+	USART_ClockInitStruct.USART_CPOL = USART_CPOL_Low;
+	USART_ClockInitStruct.USART_CPHA = USART_CPHA_2Edge;
+	USART_ClockInitStruct.USART_LastBit = USART_LastBit_Disable;
+	
+	USART_ClockInit(USART1,  &USART_ClockInitStruct);*/
+
+	
+	usart_enable(USART0); 
+
+	usart_prescaler_config(USART0, 0x01);
+	usart_irda_lowpower_config(USART0, USART_IRLP_NORMAL);
+	usart_irda_mode_enable(USART0);
+#else
+	usart_enable(USART0);
+#endif
+    
+	
+	
+	
+}
+
+
+
+/*******************************************************************************
+* Function Name  : USART1_IRQHandler
+* Description    : This function handles USART1 global interrupt request.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void USART0_IRQHandler(void)
+{
+	uint8_t c;
+	
+	/* 串口接收 */
+	//if(usart_interrupt_flag_get(USART0, USART_FLAG_RBNE) == SET)
+	if(usart_flag_get(USART0, USART_FLAG_RBNE) == SET)	
+	{
+		c = usart_data_receive(USART0);
+		if (rx_count >= sizeof(rx_buffer))
+		{
+		    return;
+		}
+		//USART_ReceiverTimeOutCmd(USART1,DISABLE);
+		Enable_Uart1_Timer(0,0);
+		/* Read one byte from the receive data register */
+		rx_buffer[rx_count++] = c;
+				
+		Enable_Uart1_Timer(1,5);
+	}
+	/* 发送 */
+	//if(usart_interrupt_flag_get(USART0, USART_FLAG_TC) == SET)
+	if(usart_flag_get(USART0, USART_FLAG_TC) == SET)
+	{
+		//USART_ClearFlag(USART1, USART_FLAG_TC);
+		if (tx_count >= tx_buffer_size)
+		{
+			 /* Disable the EVAL_COM1 Transmit interrupt */
+		  	usart_interrupt_disable(USART0,USART_INT_TC);
+			//USART_ClearFlag(USART1, USART_FLAG_TC);
+			return;
+		}
+		/* Write one byte to the transmit data register */
+		usart_data_transmit(USART0,tx_buffer[tx_count++]);
+	}
+
+}
+
+
+
+

+ 40 - 0
Source/drv_usart.h

@@ -0,0 +1,40 @@
+#ifndef DRV_USART1_H
+#define DRV_USART1_H
+
+#define TX_BUFFER_SIZE 256//128
+#define RX_BUFFER_SIZE 256//128
+
+#define UART_0_IDAR   (0)
+#define USART_0_BAUND    (USART_BAUND)
+extern DELAY_COMMON uart1_tout;
+
+
+__inline void Uart1_Time_Out(void)
+{
+	//uart1
+	if(uart1_tout.set)
+	{
+		if(uart1_tout.count)
+			uart1_tout.count--;
+		else
+		{
+			g_event |= RS485_RECEIVE_END_EVENT;
+			uart1_tout.set = 0;
+			uart1_tout.count = 0;
+		}
+	}
+}
+
+unsigned char CheckSum(unsigned char *dat, unsigned char num);
+
+void Usart1_Initial(void);
+
+int8_t Send_Data_RS485(uint8_t*data,uint16_t size);
+
+
+uint16_t Get_RS485_Data(uint8_t * dbuf,uint16_t dbuf_len);
+
+
+
+#endif
+

+ 209 - 0
Source/drv_usart_2.c

@@ -0,0 +1,209 @@
+#include "common.h" 
+#include "drv_usart_2.h"
+
+ /* transmit buffer and receive buffer */
+static uint8_t tx_buffer[TX_2_BUFFER_SIZE];
+static uint8_t rx_buffer[RX_2_BUFFER_SIZE];
+/* counter of transmit buffer and receive buffer */
+static uint16_t tx_count = 0, rx_count = 0;
+/* size of transmit buffer and receive buffer */
+static uint32_t /*rx_buffer_size ,*/ tx_buffer_size;
+
+DELAY_COMMON uart2_tout;
+
+void Enable_Uart2_Timer(uint8_t enable,uint16_t timeout)
+{
+	if(enable)
+	{
+		uart2_tout.set = 1;
+		uart2_tout.count = timeout;
+	}
+	else
+	memset(&uart2_tout,0x00,sizeof(uart2_tout));
+	
+}
+
+static void Reset_RX_Buffer(void)
+{
+	memset(rx_buffer,0x00,sizeof(rx_buffer));
+	rx_count = 0;
+}
+
+uint16_t Get_RS485_2_Data(uint8_t * dbuf,uint16_t dbuf_len)
+{
+	if(dbuf == NULL || dbuf_len < rx_count)
+		return 0;
+
+	memcpy(dbuf,rx_buffer,rx_count);
+	dbuf_len = rx_count;
+	Reset_RX_Buffer();
+	
+	return dbuf_len;
+}
+
+
+
+int8_t Send_Data_2_RS485(uint8_t*data,uint16_t size)
+{
+	if(data == NULL || size == 0 || size > sizeof(tx_buffer))
+		return 0;
+
+
+	memcpy(tx_buffer,data,size);
+	tx_count = 0;
+	tx_buffer_size = size;
+	
+	//
+#if 0
+	do
+	{
+		while(RESET == usart_flag_get(USART1, USART_FLAG_TC));
+		usart_data_transmit(USART1,tx_buffer[tx_count++]);
+	}while(tx_count < tx_buffer_size);
+#else
+	//while(RESET == USART_GetFlagStatus(USART2, USART_FLAG_TC));
+	//USART_SendData(USART2,tx_buffer[tx_count++]);
+
+	usart_interrupt_enable(USART1, USART_INT_TC);
+#endif	
+	return 1;
+}
+
+
+
+/*
+ * 函数名:USART2_Config
+ * 描述  :USART2 GPIO 配置,工作模式配置。9600 8-N-1
+ * 输入  :无
+ * 输出  : 无
+ * 调用  :外部调用
+ */
+void Usart2_Initial(void)
+{
+
+	
+	/* enable GPIO clock */
+    rcu_periph_clock_enable(RCU_GPIOA);
+	rcu_periph_clock_enable(RCU_AF);
+
+    /* connect port to USARTx_Tx */
+    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
+
+    /* connect port to USARTx_Rx */
+    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3);
+
+    /* USART configure */
+	/* enable USART clock */
+    rcu_periph_clock_enable(RCU_USART1);
+    usart_deinit(USART1);
+    usart_baudrate_set(USART1, USART_1_BAUND);
+    usart_word_length_set(USART1, USART_WL_8BIT);
+    usart_stop_bit_set(USART1, USART_STB_1BIT);
+    usart_parity_config(USART1, USART_PM_NONE);
+    usart_hardware_flow_rts_config(USART1, USART_RTS_DISABLE);
+    usart_hardware_flow_cts_config(USART1, USART_CTS_DISABLE);
+    usart_receive_config(USART1, USART_RECEIVE_ENABLE);
+    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);
+	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
+	nvic_irq_enable(USART1_IRQn, 1, 0);
+	usart_interrupt_enable(USART1, USART_INT_RBNE);
+
+	
+#if UART_1_IDAR
+	/*USART_ClockInitTypeDef  USART_ClockInitStruct; 
+
+	USART_ClockInitStruct.USART_Clock = USART_Clock_Disable;
+	USART_ClockInitStruct.USART_CPOL = USART_CPOL_Low;
+	USART_ClockInitStruct.USART_CPHA = USART_CPHA_2Edge;
+	USART_ClockInitStruct.USART_LastBit = USART_LastBit_Disable;
+	
+	USART_ClockInit(USART1,  &USART_ClockInitStruct);*/
+
+	
+	usart_enable(USART1); 
+
+	usart_prescaler_config(USART1, 0x01);
+	usart_irda_lowpower_config(USART1, USART_IRLP_NORMAL);
+	usart_irda_mode_enable(USART1);
+#else
+	usart_enable(USART1);
+#endif
+
+
+}
+
+
+
+/*******************************************************************************
+* Function Name  : USART2_IRQHandler
+* Description    : This function handles USART2 global interrupt request.
+* Input          : None
+* Output         : None
+* Return         : None
+*******************************************************************************/
+void USART1_IRQHandler(void)
+{
+	uint8_t c;
+	
+	/* 串口接收 */
+	if(usart_flag_get(USART1, USART_FLAG_RBNE) == SET)
+	{
+		c = usart_data_receive(USART1);
+		if (rx_count >= sizeof(rx_buffer))
+		{
+		    return;
+		}
+		//USART_ReceiverTimeOutCmd(USART2,DISABLE);
+		Enable_Uart2_Timer(0,0);
+		/* Read one byte from the receive data register */
+		rx_buffer[rx_count++] = c;
+				
+		Enable_Uart2_Timer(1,5);
+	}
+	/* 发送 */
+	if(usart_flag_get(USART1, USART_FLAG_TC) == SET)
+	{
+		//USART_ClearFlag(USART1, USART_FLAG_TC);
+		if (tx_count >= tx_buffer_size)
+		{
+			 /* Disable the EVAL_COM1 Transmit interrupt */
+		  	usart_interrupt_disable(USART1,USART_INT_TC);
+			
+			//USART_ClearFlag(USART1, USART_FLAG_TC);
+			return;
+		}
+		/* Write one byte to the transmit data register */
+		usart_data_transmit(USART1,tx_buffer[tx_count++]);
+	}
+	
+}
+
+#if 0
+// 
+//用于系统调用printf
+//
+#ifdef __GNUC__
+  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
+     set to 'Yes') calls __io_putchar() */
+#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
+#else
+#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
+#endif /* __GNUC__ */
+
+PUTCHAR_PROTOTYPE
+{
+	// RS485发送使能
+	gpio_bit_set(GPIOA, GPIO_PIN_4);
+	
+	usart_data_transmit(USART1,(uint8_t) ch);
+	while(!(usart_flag_get(USART1, USART_FLAG_TC) == SET));
+	// RS485接收使能
+
+	gpio_bit_reset(GPIOA, GPIO_PIN_4);
+	
+	return ch;
+}
+#endif
+
+
+

+ 41 - 0
Source/drv_usart_2.h

@@ -0,0 +1,41 @@
+#ifndef DRV_USART2_H
+#define DRV_USART2_H
+
+#define TX_2_BUFFER_SIZE 256//128
+#define RX_2_BUFFER_SIZE 256//128
+
+#define UART_1_IDAR   (0)
+#define USART_1_BAUND    (USART_BAUND)
+extern DELAY_COMMON uart2_tout;
+
+
+__inline void Uart2_Time_Out(void)
+{
+	//uart2
+	if(uart2_tout.set)
+	{
+		if(uart2_tout.count)
+			uart2_tout.count--;
+		else
+		{
+			g_event |= RS485_2_RECEIVE_END_EVENT;
+			uart2_tout.set = 0;
+			uart2_tout.count = 0;
+		}
+	}
+}
+
+
+
+
+
+void Usart2_Initial(void);
+
+int8_t Send_Data_2_RS485(uint8_t*data,uint16_t size);
+
+uint16_t Get_RS485_2_Data(uint8_t * dbuf,uint16_t dbuf_len);
+
+
+
+#endif
+

+ 22 - 0
Source/drv_watch_dog.c

@@ -0,0 +1,22 @@
+#include "common.h" 
+#include "drv_watch_dog.h"
+
+
+void Watch_Dog_Initial(void)
+{
+	 /* enable IRC40K */
+    rcu_osci_on(RCU_IRC40K);
+    
+    /* wait till IRC40K is ready */
+    while(SUCCESS != rcu_osci_stab_wait(RCU_IRC40K)){
+    }  
+
+    /* confiure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
+    fwdgt_config(4*625, FWDGT_PSC_DIV64);  
+    /* after 4 seconds to generate a reset */
+    fwdgt_enable();
+}
+
+
+
+

+ 11 - 0
Source/drv_watch_dog.h

@@ -0,0 +1,11 @@
+#ifndef  __DRV_WATCH_DOG_H__
+#define  __DRV_WATCH_DOG_H__
+
+#define Feed_Watch_Dog() fwdgt_counter_reload()
+
+
+void Watch_Dog_Initial(void);
+
+
+#endif
+

+ 151 - 0
Source/gd32f10x_it.c

@@ -0,0 +1,151 @@
+/*!
+    \file    gd32f10x_it.c
+    \brief   interrupt service routines
+
+    \version 2014-12-26, V1.0.0, firmware for GD32F10x
+    \version 2017-06-20, V2.0.0, firmware for GD32F10x
+    \version 2018-07-31, V2.1.0, firmware for GD32F10x
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#include "gd32f10x_it.h"
+#include "common.h"
+#include "delay.h"
+
+/*!
+    \brief      this function handles NMI exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void NMI_Handler(void)
+{
+}
+
+/*!
+    \brief      this function handles HardFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void HardFault_Handler(void)
+{
+#if DEBUG_MODE == 0
+	NVIC_SystemReset();
+#else
+    /* if Hard Fault exception occurs, go to infinite loop */
+    while(1){
+    }
+#endif
+
+}
+
+/*!
+    \brief      this function handles MemManage exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void MemManage_Handler(void)
+{
+#if DEBUG_MODE == 0
+	NVIC_SystemReset();
+#else
+    /* if Memory Manage exception occurs, go to infinite loop */
+    while(1){
+    }
+#endif
+}
+
+/*!
+    \brief      this function handles BusFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void BusFault_Handler(void)
+{
+#if DEBUG_MODE == 0
+	NVIC_SystemReset();
+#else
+    /* if Bus Fault exception occurs, go to infinite loop */
+    while(1){
+    }
+#endif
+}
+
+/*!
+    \brief      this function handles UsageFault exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void UsageFault_Handler(void)
+{
+#if DEBUG_MODE == 0
+	NVIC_SystemReset();
+#else
+    /* if Usage Fault exception occurs, go to infinite loop */
+    while(1){
+    }
+#endif
+}
+
+/*!
+    \brief      this function handles SVC exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void SVC_Handler(void)
+{
+}
+
+/*!
+    \brief      this function handles DebugMon exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void DebugMon_Handler(void)
+{
+}
+
+/*!
+    \brief      this function handles PendSV exception
+    \param[in]  none
+    \param[out] none
+    \retval     none
+*/
+void PendSV_Handler(void)
+{
+}
+

+ 64 - 0
Source/gd32f10x_it.h

@@ -0,0 +1,64 @@
+/*!
+    \file    gd32f10x_it.h
+    \brief   the header file of the ISR
+
+    \version 2014-12-26, V1.0.0, firmware for GD32F10x
+    \version 2017-06-20, V2.0.0, firmware for GD32F10x
+    \version 2018-07-31, V2.1.0, firmware for GD32F10x
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32F10X_IT_H
+#define GD32F10X_IT_H
+
+#include "gd32f10x.h"
+
+/* function declarations */
+/* this function handles NMI exception */
+void NMI_Handler(void);
+/* this function handles HardFault exception */
+void HardFault_Handler(void);
+/* this function handles MemManage exception */
+void MemManage_Handler(void);
+/* this function handles BusFault exception */
+void BusFault_Handler(void);
+/* this function handles UsageFault exception */
+void UsageFault_Handler(void);
+/* this function handles SVC exception */
+void SVC_Handler(void);
+/* this function handles DebugMon exception */
+void DebugMon_Handler(void);
+/* this function handles PendSV exception */
+void PendSV_Handler(void);
+/* this function handles SysTick exception */
+void SysTick_Handler(void);
+
+#endif /* GD32F10X_IT_H */

+ 66 - 0
Source/gd32f10x_libopt.h

@@ -0,0 +1,66 @@
+/*!
+    \file    gd32f10x_libopt.h
+    \brief   library optional for gd32f10x
+
+    \version 2014-12-26, V1.0.0, firmware for GD32F10x
+    \version 2017-06-20, V2.0.0, firmware for GD32F10x
+    \version 2018-07-31, V2.1.0, firmware for GD32F10x
+*/
+
+/*
+    Copyright (c) 2018, GigaDevice Semiconductor Inc.
+
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    1. Redistributions of source code must retain the above copyright notice, this 
+       list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright notice, 
+       this list of conditions and the following disclaimer in the documentation 
+       and/or other materials provided with the distribution.
+    3. Neither the name of the copyright holder nor the names of its contributors 
+       may be used to endorse or promote products derived from this software without 
+       specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+OF SUCH DAMAGE.
+*/
+
+#ifndef GD32F10X_LIBOPT_H
+#define GD32F10X_LIBOPT_H
+
+#include "gd32f10x_fmc.h"
+#include "gd32f10x_pmu.h"
+#include "gd32f10x_bkp.h"
+#include "gd32f10x_rcu.h"
+#include "gd32f10x_exti.h"
+#include "gd32f10x_gpio.h"
+#include "gd32f10x_crc.h"
+#include "gd32f10x_dma.h"
+#include "gd32f10x_dbg.h"
+#include "gd32f10x_adc.h"
+#include "gd32f10x_dac.h"
+#include "gd32f10x_fwdgt.h"
+#include "gd32f10x_wwdgt.h"
+#include "gd32f10x_rtc.h"
+#include "gd32f10x_timer.h"
+#include "gd32f10x_usart.h"
+#include "gd32f10x_i2c.h"
+#include "gd32f10x_spi.h"
+#include "gd32f10x_sdio.h"
+#include "gd32f10x_exmc.h"
+#include "gd32f10x_can.h"
+#include "gd32f10x_enet.h"
+#include "gd32f10x_misc.h"
+
+#endif /* GD32F10X_LIBOPT_H */

+ 687 - 0
Source/hardware_test.c

@@ -0,0 +1,687 @@
+#include"common.h"
+#include "drv_io.h"
+#include "drv_usart.h"
+#include "drv_usart_2.h"
+#include "app.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "drv_can.h"
+#include "app_adas.h"
+#include "measure_vol.h"
+#include "app_can.h"
+#include "hardware_test.h"
+#include "measure_temprature.h"
+#include "app_end_ctr.h"
+
+static uint8_t app_rs485_buf[TX_BUFFER_SIZE];
+uint8_t ht_mode = 0;
+uint8_t where_from = FROM_USART_1;
+uint8_t over_12V = 0;
+const uint16_t ht_flash = 0x2323;
+//#define ht_flash  (0x2323)
+DELAY_COMMON  HT_Reboot;
+
+extern uint8_t work_normal;
+
+#ifdef CONFIG_CAN_IAP
+extern void qws_iap_write_magic(uint32_t magic);
+#endif
+
+void HT_Reboot_Timeout(void)
+{
+	if(HT_Reboot.set)
+	{
+		if(++HT_Reboot.count > 3000)
+		{
+			memset(&HT_Reboot,0x00,sizeof(HT_Reboot));
+			g_event |= DEVICE_REBOOT_EVENT;
+		}
+	}
+}
+
+void HT_Flash_flag_clear(void)
+{
+	fmc_flag_clear(FMC_FLAG_BANK0_PGERR | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_END);
+}
+uint8_t Check_HT_Flash(void)
+{
+	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	uint32_t address = 0x08000000 + (capacity - HARD_TEST_FLASH_ADDRESS);
+	uint16_t flag = REG16(address);
+
+	if (REG16(address) == ht_flash) 
+		return 1;
+	else
+		return 0;
+}
+
+void Writer_HT_Flash(uint8_t flag)
+{
+	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	uint32_t address = 0x08000000 + (capacity - HARD_TEST_FLASH_ADDRESS);
+	
+	uint16_t df_value ;
+
+	if(flag)
+	{
+		df_value = ht_flash;
+		HT_Reboot.set = 1;
+		HT_Reboot.count = 0;
+	}
+	else
+		df_value = 0xFFFF;
+	
+	fmc_unlock();
+
+	HT_Flash_flag_clear();
+	fmc_page_erase(address);
+
+	
+	HT_Flash_flag_clear();
+	fmc_halfword_program(address,df_value);
+	HT_Flash_flag_clear();
+	
+	fmc_lock();
+
+	
+}
+
+uint8_t HT_Frame_CRC(uint8_t*data,uint8_t len)
+{
+	uint8_t i,crc = 0;
+
+	for(i = 0;i<len;i++)
+		crc += data[i];
+
+	return crc;
+}
+
+int8_t HT_Handle_CMD( uint8_t *data)
+{
+	HT_FRAME * ht_frame = (HT_FRAME *)data;
+	uint8_t temp;
+
+	do
+	{
+		if(NULL == data)
+		{
+			return 0;
+		}
+
+		
+		if(ht_frame->ht_dir != 1)
+			break;
+
+		//CRC 
+		temp = ht_frame->ht_crc;
+		ht_frame->ht_crc = 0;
+		if(temp != HT_Frame_CRC(data,ht_frame->ht_len))
+		{
+			break;
+		}
+
+		temp = sizeof(HT_FRAME);
+	
+		//handle frame
+		switch(ht_frame->ht_cmd)
+		{
+			case HT_IDRA:
+				S21_ENABLE(1);
+				break;
+				
+			case HT_12V:
+				if(data[temp] == 1)
+					Enable_12V(1);
+				else if(data[temp] == 2)
+					Enable_12V(0);
+				else
+					return 0;
+				break;
+				
+			case HT_CAN:
+				if(data[temp] == 1)
+				{
+					Can_Power_Enable(1);
+					work_normal = 1;
+				}
+				else if(data[temp] == 2)
+				{
+					Can_Power_Enable(0);
+					work_normal = 0;
+				}
+				else
+					return 0;
+				break;
+				
+			case HT_QD:
+				if(data[temp] == 1)
+					QD_Enable(1);
+					//QD_Enable_From(1,6);
+				else if(data[temp] == 2)
+					QD_Enable(0);
+					//QD_Enable_From(0,7);
+				else
+					return 0;
+				break;
+				
+			case HT_ACC:
+				break;
+
+
+			case HT_S_P:
+				break;
+
+			case HT_LIGHT:
+				break;
+
+			case HT_INPUT:
+				break;
+
+			case HT_LOCK:
+				break;
+				
+			case HT_XL:
+				break;
+
+			case HT_CHARGER:
+				break;
+				
+			case HT_TEMP:
+				break;
+
+			case HT_ADAS:
+				break;
+				
+			default:return 0;
+		}
+
+		
+		return 1;
+		
+	}while(0);
+
+	return 0;
+	
+}
+
+int8_t HT_Rsp_CMD(uint8_t *buf)
+{
+	HT_FRAME * ht_frame = (HT_FRAME *)buf;
+	uint8_t len;
+	
+	if(NULL == buf)
+	{
+		return 0;
+	}
+
+	switch(ht_frame->ht_cmd)
+	{
+		case HT_IDRA:
+			len = sizeof(HT_FRAME);
+			buf[len++] = 0; 
+			break; 
+		case HT_12V:
+			len = sizeof(HT_FRAME);
+			buf[len++] = 0; 
+			break; 
+		case HT_CAN:
+			len = sizeof(HT_FRAME);
+			buf[len++] = 0; 
+			break; 
+
+		case HT_QD:
+			len = sizeof(HT_FRAME);
+			buf[len++] = !QD_Dect(); 
+			break;
+
+		case HT_ACC:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				FL_Enable(1);
+				buf[len++] = 0; 
+			}
+			else if(buf[len] == 2)
+			{
+				over_12V = 0;
+				gpio_bit_write(GPIOC,GPIO_PIN_15,SET);
+				buf[len++] = gpio_input_bit_get(GPIOD,GPIO_PIN_0);
+			}
+			else if(buf[len] == 3)
+			{
+				buf[len++] = over_12V;
+				over_12V = 0;
+			}
+			else if(buf[len] == 4)
+			{
+				gpio_bit_write(GPIOC,GPIO_PIN_15,RESET);
+				buf[len++] = gpio_input_bit_get(GPIOD,GPIO_PIN_0);
+			}
+			else if(buf[len] == 5)
+			{
+				FL_Enable(0);
+				buf[len++] = 0; 
+			}
+			else
+				return 0;
+			break;
+
+		case HT_S_P:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				S11_ENABLE(0);
+				S21_ENABLE(0);
+				SS__ENABLE(0);
+				delay_1ms(100);
+				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_1);
+				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_2);
+				uint32_t vol = Measure_Vol();
+				buf[len++] = (uint8_t)(vol >> 0);
+				buf[len++] = (uint8_t)(vol >> 8);
+				buf[len++] = (uint8_t)(vol >> 16);
+				buf[len++] = (uint8_t)(vol >> 24);
+			}
+			else if(buf[len] == 2)
+			{
+				if(buf[len + 1] == 1)
+				{
+					S21_ENABLE(1);
+					buf[len++] = 0;
+				}
+				else if(buf[len + 1] == 2)
+				{
+					delay_1ms(100);
+					uint32_t vol = Measure_Vol();
+					buf[len++] = (uint8_t)(vol >> 0);
+					buf[len++] = (uint8_t)(vol >> 8);
+					buf[len++] = (uint8_t)(vol >> 16);
+					buf[len++] = (uint8_t)(vol >> 24);
+				}
+				else if(buf[len + 1] == 3)
+				{
+					S21_ENABLE(0);
+					buf[len++] = 0;
+				}
+
+				
+			}
+			else if(buf[len] == 3)
+			{
+				delay_1ms(100);
+				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_1);
+				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_2);
+				uint32_t vol = Measure_Vol();
+				buf[len++] = (uint8_t)(vol >> 0);
+				buf[len++] = (uint8_t)(vol >> 8);
+				buf[len++] = (uint8_t)(vol >> 16);
+				buf[len++] = (uint8_t)(vol >> 24);
+			}
+			else if(buf[len] == 4)
+			{
+				if(buf[len + 1] == 1)
+				{
+					FL_Enable(1);
+					delay_1ms(10);
+					S11_ENABLE(1);
+					buf[len++] = 0;
+				}
+				else if(buf[len + 1] == 2)
+				{
+					delay_1ms(100);
+					uint32_t vol = Measure_Vol();
+					buf[len++] = (uint8_t)(vol >> 0);
+					buf[len++] = (uint8_t)(vol >> 8);
+					buf[len++] = (uint8_t)(vol >> 16);
+					buf[len++] = (uint8_t)(vol >> 24);
+				}
+				else if(buf[len + 1] == 3)
+				{
+					FL_Enable(0);
+					S11_ENABLE(0);
+					buf[len++] = 0;
+				}
+				
+			}
+			else if(buf[len] == 5)
+			{
+				delay_1ms(100);
+				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_1);
+				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_2);
+				uint32_t vol = Measure_Vol();
+				buf[len++] = (uint8_t)(vol >> 0);
+				buf[len++] = (uint8_t)(vol >> 8);
+				buf[len++] = (uint8_t)(vol >> 16);
+				buf[len++] = (uint8_t)(vol >> 24);
+			}
+			else if(buf[len] == 6)
+			{
+				if(buf[len + 1] == 1)
+				{
+					SS__ENABLE(1);
+					buf[len++] = 0;
+				}
+				else if(buf[len + 1] == 2)
+				{
+					delay_1ms(100);
+					uint32_t vol = Measure_Vol();
+					buf[len++] = (uint8_t)(vol >> 0);
+					buf[len++] = (uint8_t)(vol >> 8);
+					buf[len++] = (uint8_t)(vol >> 16);
+					buf[len++] = (uint8_t)(vol >> 24);
+				}
+				else if(buf[len + 1] == 3)
+				{
+					SS__ENABLE(0);
+					buf[len++] = 0;
+				}
+				
+			}
+			else if(buf[len] == 7)
+			{
+				FL_Enable(1);
+				delay_1ms(10);
+				S11_ENABLE(1);
+				S21_ENABLE(1);
+				SS__ENABLE(1);
+				
+				buf[len++] = 0;
+			}
+			else if(buf[len] == 8)
+			{
+				
+				SS__ENABLE(0);
+				
+				buf[len++] = 0;
+			}
+			else if(buf[len] == 9)
+			{
+				
+				S21_ENABLE(0);
+				
+				buf[len++] = 0;
+			}
+			else
+				return 0;
+			break;
+
+		case HT_LIGHT:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				Right_Light_Enable(0);
+				Tail_Light_Enable(0);
+				Left_Light_Enable(1);
+				Carpet_Light_Enable(1);
+				buf[len++] = 0; 
+			}
+			else if(buf[len] == 2)
+			{
+				Left_Light_Enable(0);
+				Carpet_Light_Enable(0);
+				Right_Light_Enable(1);
+				Tail_Light_Enable(1);
+				buf[len++] = 0;
+			}
+			else if(buf[len] == 3)
+			{
+				Right_Light_Enable(0);
+				Tail_Light_Enable(0);
+				Left_Light_Enable(0);
+				Carpet_Light_Enable(0);
+				buf[len++] = 0;
+			}
+			else
+				return 0;
+			break;
+
+		case HT_INPUT:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				buf[len++] = Side_Stay_Dect();
+				buf[len++] = !Soak_Dect();
+				buf[len++] = Sitting_Dect(); 
+			}
+			else if(buf[len] == 2)
+			{
+			
+				buf[len++] = Side_Stay_Dect();
+				buf[len++] = !Soak_Dect();
+				buf[len++] = Sitting_Dect(); 
+			}
+			else
+				return 0;
+			break;
+
+		case HT_LOCK:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				Lock_Enable(1);
+				buf[len++] = 0;
+			}
+			else if(buf[len] == 2)
+			{
+				Lock_Enable(0);
+				buf[len++] = 0;
+			}
+			else
+				return 0;
+			break;
+
+		case HT_XL:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				xl_count = 0;
+				delay_1ms(100);
+				if(xl_count)
+					buf[len++] = 1;
+				else
+					buf[len++] = 0;
+			}
+			else if(buf[len] == 2)
+			{
+				xl_count = 0;
+				delay_1ms(100);
+				if(xl_count)
+					buf[len++] = 1;
+				else
+					buf[len++] = 0;
+			}
+			else
+				return 0;
+			break;
+
+		case HT_CHARGER:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				CHARG_PROTECT_OPEN(1);
+				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_4);
+			}
+			else if(buf[len] == 2)
+			{
+				CHARG_PROTECT_OPEN(0);
+				buf[len++] = gpio_input_bit_get(GPIOC,GPIO_PIN_4);
+			}
+			else
+				return 0;
+			break;
+
+		case HT_TEMP:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				getTemperature();
+				buf[len++] = (uint8_t)(ctr_temperature[0]);
+				buf[len++] = (uint8_t)(ctr_temperature[1]);
+			}
+			else
+				return 0;
+			break;
+
+		case HT_ADAS:
+			len = sizeof(HT_FRAME);
+			if(buf[len] == 1)
+			{
+				ADAS_Enable(1);
+				
+				buf[len++] = 0;
+			
+			}
+			else if(buf[len] == 2)
+			{
+				buf[len++] = (uint8_t)(ju_li_1 >> 0);
+				buf[len++] = (uint8_t)(ju_li_1 >> 8);
+				buf[len++] = (uint8_t)(ju_li_2 >> 0);
+				buf[len++] = (uint8_t)(ju_li_2 >> 8);
+			}
+			else
+				return 0;
+			break;
+			
+		default:break;
+	}
+
+	// ÌîÖ¡Í·
+	ht_frame->ht_len = len;
+	ht_frame->ht_dir = 0;
+	ht_frame->ht_crc = 0;
+	ht_frame->ht_crc = HT_Frame_CRC(buf,ht_frame->ht_len);
+	
+	return 1;
+
+}
+
+int8_t HT_Handle_RS485_Data(uint8_t from)
+{
+	uint8_t len ;
+	
+	if(from == FROM_USART_1)
+	{
+		len = Get_RS485_Data(app_rs485_buf,sizeof(app_rs485_buf));
+	}
+	else if(from == FROM_USART_2)
+	{
+		len = Get_RS485_2_Data(app_rs485_buf,sizeof(app_rs485_buf));
+	}
+	else
+		return 0;
+	
+	where_from = from;
+	if(len != app_rs485_buf[0])
+	{
+		return 0;
+
+	}
+
+	if(!HT_Handle_CMD(app_rs485_buf))
+		return 0;
+
+	if(!HT_Rsp_CMD(app_rs485_buf))
+		return 0;
+
+	if(from == FROM_USART_1)
+	{
+		if(!Send_Data_RS485(app_rs485_buf,app_rs485_buf[0]))
+			return 0;
+	}
+	else if(from == FROM_USART_2)
+	{
+		if(!Send_Data_2_RS485(app_rs485_buf,app_rs485_buf[0]))
+			return 0;
+	}
+
+	return 1;
+}
+
+
+
+void HT_Main(void)
+{
+	if(Repair_Key_Dect() && !Check_HT_Flash())
+		return;
+
+#ifdef CONFIG_CAN_IAP
+	qws_iap_write_magic(0x11223344);
+#endif
+
+	Writer_HT_Flash(0);
+
+	ht_mode = 1;
+
+	memset(&send_delay,0x00,sizeof(send_delay));
+	
+	
+	for(;;)
+	{
+		Check_Can_Poll();
+		
+		Handle_Can_Data();
+
+		if(g_event & RS485_RECEIVE_END_EVENT)
+		{
+			
+			if(HT_Handle_RS485_Data(FROM_USART_1) == 0)
+			{
+				// output fail
+				
+				;
+			}
+			g_event &= ~RS485_RECEIVE_END_EVENT;
+		}
+	
+		if(g_event & RS485_2_RECEIVE_END_EVENT)
+		{
+			
+			if(HT_Handle_RS485_Data(FROM_USART_2) == 0)
+			{
+				// output fail
+				
+				;
+			}
+			g_event &= ~RS485_2_RECEIVE_END_EVENT;
+		}
+
+
+		if(g_event & ADAS_PWM_1_TIMEOUT_EVENT)
+		{
+			ADAS_PWM_1_Enable();
+			
+			g_event &= ~ADAS_PWM_1_TIMEOUT_EVENT;
+			
+		}
+
+		if(g_event & ADAS_PWM_2_TIMEOUT_EVENT)
+		{
+			ADAS_PWM_2_Enable();
+			
+			g_event &= ~ADAS_PWM_2_TIMEOUT_EVENT;
+			
+		}
+
+		if(g_event & ADAS_MEAS_1_FINISH_EVENT)
+		{
+			ADAS_Measure_Finish_Ju_Li_1();
+
+			ADAS_Self_Send_Up();
+			
+			g_event &= ~ADAS_MEAS_1_FINISH_EVENT;
+			
+		}
+
+		if(g_event & ADAS_MEAS_2_FINISH_EVENT)
+		{
+			ADAS_Measure_Finish_Ju_Li_2();
+			
+			g_event &= ~ADAS_MEAS_2_FINISH_EVENT;
+			
+		}
+
+
+		
+	}
+}
+

+ 51 - 0
Source/hardware_test.h

@@ -0,0 +1,51 @@
+#ifndef HARDWARE_TEST_H
+#define HARDWARE_TEST_H
+
+enum
+{
+	FROM_USART_1,
+	FROM_USART_2
+};
+
+enum
+{
+	HT_IDRA,
+	HT_12V,
+	HT_CAN,
+	HT_QD,
+	HT_ACC,
+	HT_S_P,
+	HT_LIGHT,
+	HT_INPUT,
+	HT_LOCK,
+	HT_XL,
+	HT_CHARGER,
+	HT_TEMP,
+	HT_ADAS,
+	
+	HT_MAX
+};
+
+
+#pragma  pack (push,1)  
+typedef struct
+{
+	uint8_t ht_len;
+	uint8_t ht_cmd;
+	uint8_t ht_dir;
+	uint8_t ht_crc;
+	//uint8_t *ht_buf;
+	
+}HT_FRAME;
+#pragma pack(pop)
+
+extern uint8_t ht_mode;
+extern uint8_t over_12V;
+void HT_Main(void);
+
+void Writer_HT_Flash(uint8_t flag);
+
+void HT_Reboot_Timeout(void);
+
+#endif
+

+ 203 - 0
Source/low_power.c

@@ -0,0 +1,203 @@
+#include"common.h"
+#include "drv_io.h"
+#include "drv_usart.h"
+#include "drv_usart_2.h"
+#include "app.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "drv_can.h"
+#include "app_adas.h"
+#include "measure_vol.h"
+#include "app_can.h"
+#include "low_power.h"
+#include "measure_temprature.h"
+
+DELAY_COMMON enter_sleep_delay;
+
+void LP_Measure_Vol_Initial(void)
+{
+	/* enable GPIOA clock */
+    rcu_periph_clock_enable(RCU_GPIOA);
+
+	rcu_periph_clock_enable(RCU_AF);
+    /* enable ADC0 clock */
+    rcu_periph_clock_enable(RCU_ADC0);
+    /* config ADC clock */
+    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);
+
+	gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_5);
+	
+}
+
+void Set_Enter_Sleep_Delay(void)
+{
+	enter_sleep_delay.set = 1;
+	enter_sleep_delay.count = 0;
+}
+
+void Reset_Enter_Sleep_Delay(void)
+{
+	enter_sleep_delay.set = 0;
+	enter_sleep_delay.count = 0;
+}
+
+void Enter_Sleep_Delay_Timeout(void)
+{
+	if(enter_sleep_delay.set)
+	{
+		if(++enter_sleep_delay.count >= 15000)
+		{
+			memset(&enter_sleep_delay,0x00,sizeof(enter_sleep_delay));
+			g_event |= ENTER_SLEEP_EVENT;
+		}
+	}
+}
+
+
+void RTC_Open(void)
+{
+
+	nvic_irq_enable(RTC_IRQn,1,0);
+	
+    /* enable PMU and BKPI clocks */
+    rcu_periph_clock_enable(RCU_BKPI);
+    rcu_periph_clock_enable(RCU_PMU);
+    /* allow access to BKP domain */
+    pmu_backup_write_enable();
+
+    /* reset backup domain */
+    bkp_deinit();
+
+	exti_init(EXTI_17, EXTI_INTERRUPT, EXTI_TRIG_RISING);
+    exti_interrupt_flag_clear(EXTI_17);
+	exti_interrupt_enable(EXTI_17);
+	
+    /* enable LXTAL */
+    rcu_osci_on(RCU_IRC40K);
+    /* wait till LXTAL is ready */
+    rcu_osci_stab_wait(RCU_IRC40K);
+    
+    /* select RCU_LXTAL as RTC clock source */
+    rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
+
+    /* enable RTC Clock */
+    rcu_periph_clock_enable(RCU_RTC);
+
+    /* wait for RTC registers synchronization */
+    rtc_register_sync_wait();
+
+    /* wait until last write operation on RTC registers has finished */
+    rtc_lwoff_wait();
+
+    /* enable the RTC second interrupt*/
+    rtc_interrupt_enable(RTC_INT_ALARM);
+
+    /* wait until last write operation on RTC registers has finished */
+    rtc_lwoff_wait();
+
+    /* set RTC prescaler: set RTC period to 1s */
+    rtc_prescaler_set(40);
+
+    /* wait until last write operation on RTC registers has finished */
+    rtc_lwoff_wait();
+
+	rtc_lwoff_wait();
+	rtc_alarm_config(1000);
+	rtc_lwoff_wait();
+	
+}
+void Enter_Sleep(void)
+{
+	uint32_t temp;
+	
+#if DEBUG_MODE == 0
+	Feed_Watch_Dog();
+#endif
+
+	systick_close();
+	
+	usart_deinit(USART0);
+
+	usart_deinit(USART1);
+
+	can_deinit(CAN0);
+
+
+
+	RTC_Open();
+
+	
+	
+
+	//while(1);
+	
+SLEEP:
+	rcu_periph_clock_enable(RCU_PMU);
+	pmu_to_deepsleepmode(PMU_LDO_LOWPOWER, WFI_CMD);
+
+#if 1
+	SystemInit();
+
+	systick_config();
+
+	LP_Measure_Vol_Initial();
+
+	temp = Measure_Vol();
+
+	systick_close();
+	
+	if(temp > 20000 && temp < 120000)
+	{
+		
+		__set_FAULTMASK(1);
+		NVIC_SystemReset();
+	}
+	else
+	{
+#if DEBUG_MODE == 0
+		Feed_Watch_Dog();
+#endif
+		goto SLEEP;
+	}
+#else
+	SystemInit();
+
+	__set_FAULTMASK(1);
+	NVIC_SystemReset();
+	
+#endif
+
+
+}
+
+void Wake_Up(void)
+{
+	
+}
+
+void Low_Power_Initial(void)
+{
+	Set_Enter_Sleep_Delay();
+}
+
+void RTC_IRQHandler(void)
+{
+    if (rtc_flag_get(RTC_FLAG_SECOND) != RESET)
+	{
+        /* clear the RTC second interrupt flag*/
+        rtc_flag_clear(RTC_FLAG_SECOND);
+        
+    }
+
+	if (rtc_flag_get(RTC_FLAG_ALARM) != RESET)
+	{
+        /* clear the RTC second interrupt flag*/
+        rtc_flag_clear(RTC_FLAG_ALARM);
+		exti_interrupt_flag_clear(EXTI_17);
+        //rtc_alarm_config(5000);
+        rtc_lwoff_wait();
+		rtc_counter_set(0x00);
+		rtc_lwoff_wait();
+    }
+}
+

+ 17 - 0
Source/low_power.h

@@ -0,0 +1,17 @@
+#ifndef LOW_POWER_H
+#define LOW_POWER_H
+
+void Reset_Enter_Sleep_Delay(void);
+
+void Set_Enter_Sleep_Delay(void);
+
+void Enter_Sleep_Delay_Timeout(void);
+
+void Enter_Sleep(void);
+
+void Wake_Up(void);
+
+void Low_Power_Initial(void);
+
+#endif
+

+ 465 - 0
Source/main.c

@@ -0,0 +1,465 @@
+#include <common.h>
+#include "drv_io.h"
+#include "drv_can.h"
+#include "drv_watch_dog.h"
+#include "app.h"
+#include "app_rs485_1.h"
+#include "app_rs485_2.h"
+#include "app_can.h"
+#include "measure_temprature.h"
+#include "measure_vol.h"
+#include "app_bms_1.h"
+#include "app_bms_2.h"
+#include "app_end_ctr.h"
+#include "app_adas.h"
+#include "hardware_test.h"
+#include "low_power.h"
+#include "sw_build_info.h"
+
+
+#ifdef CONFIG_CAN_IAP
+extern void qws_iap_write_magic(uint32_t magic);
+const uint8_t iap_board_name[] __attribute__((at(0x8002800))) = "PS100";
+const uint8_t soft_version[] __attribute__((at(0x8002A00))) = CONFIG_VERSION;
+const uint8_t iap_volume[] __attribute__((at(0x8002C00))) = "App";
+#else
+const uint8_t soft_version[] = CONFIG_VERSION;
+#endif
+
+
+
+uint8_t sn[PS100_SERIAL_NUM_SIZE];
+
+
+uint32_t g_event = NO_EVENT;
+
+
+
+void Flash_flag_clear(void)
+{
+	fmc_flag_clear(FMC_FLAG_BANK0_PGERR | FMC_FLAG_BANK0_WPERR | FMC_FLAG_BANK0_END);
+}
+void Check_SN(void)
+{
+	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	uint32_t address = 0x08000000 + (capacity - SN_FLASH_ADDRESS);
+	uint8_t i = 0;
+	uint16_t df_value = 0x3030;
+
+	if (REG32(address) < 0xFFFFFFFF) 
+	{
+		memcpy(sn,(uint8_t*)address,sizeof(sn));
+		return;
+	}
+	
+
+	fmc_unlock();
+
+	Flash_flag_clear();
+	fmc_page_erase(address);
+
+	i = 0;
+	while(i<PS100_SERIAL_NUM_SIZE)
+	{
+		Flash_flag_clear();
+		fmc_halfword_program(address + i, df_value);
+		i+= 2;
+	}
+	fmc_lock();
+
+	address = 0x08000000 + (capacity - SN_FLASH_ADDRESS);
+	memcpy(sn,(uint8_t*)address,sizeof(sn));
+	
+}
+
+void Writer_SN(uint8_t *data)
+{
+	uint32_t capacity = (REG32(0x1FFFF7E0) & 0xFFFF) << 10;
+	uint32_t address = 0x08000000 + (capacity - SN_FLASH_ADDRESS);
+	uint8_t i = 0;
+	uint16_t df_value = 0xFFFF;
+	
+	fmc_unlock();
+
+	Flash_flag_clear();
+	fmc_page_erase(address);
+
+	i = 0;
+	while(i<PS100_SERIAL_NUM_SIZE)
+	{
+		Flash_flag_clear();
+		df_value = data[i+1];
+		df_value <<= 8;
+		df_value |= data[i];
+		fmc_halfword_program(address + i,df_value);
+		i+= 2;
+	}
+	fmc_lock();
+
+	address = 0x08000000 + (capacity - SN_FLASH_ADDRESS);
+	memcpy(sn,(uint8_t*)address,sizeof(sn));
+	
+}
+
+void init_NVIC(uint32_t NVoffset)
+{
+	//ÉèÖÃÖжÏ
+
+	nvic_vector_table_set(NVIC_VECTTAB_FLASH,NVoffset);
+	
+	//nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
+	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
+	
+}
+
+void test_Initial(void)
+{
+
+	rcu_periph_clock_enable(RCU_GPIOB);
+	rcu_periph_clock_enable(RCU_GPIOD);
+	gpio_init(GPIOB,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_14);
+	gpio_init(GPIOD,GPIO_MODE_IPU,GPIO_OSPEED_50MHZ,GPIO_PIN_14);
+
+
+	rcu_periph_clock_enable(RCU_AF);
+	
+	nvic_irq_enable(EXTI10_15_IRQn,1,0);
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB, GPIO_PIN_SOURCE_14);
+	exti_init(EXTI_14, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
+    exti_interrupt_flag_clear(EXTI_14);
+
+
+#if 1
+	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOD, GPIO_PIN_SOURCE_14);
+	exti_init(EXTI_14, EXTI_INTERRUPT, EXTI_TRIG_FALLING);
+    exti_interrupt_flag_clear(EXTI_14);
+#endif
+
+
+}
+
+int main(void)
+{	
+
+#ifdef CONFIG_CAN_IAP
+#else
+	init_NVIC(NVIC_OFFSET);
+#endif
+
+	systick_config();
+
+	Misc_Initial();
+
+	Sub_BMS_1_Initial();
+
+	Sub_BMS_2_Initial();
+	
+	Can_Com_Initial();
+
+	Measure_Temprature_Initial();
+	
+	Measure_Vol_Initial();
+
+	CB_Operate_Initial();
+
+	End_Ctr_Initial();
+
+	ADAS_Initial();
+
+	HT_Main();
+	
+	App_Initial();
+	
+	//printf("PS100 Initial!\r\n");
+	Check_SN();
+
+	Low_Power_Initial();
+	
+#if DEBUG_MODE == 0
+	Watch_Dog_Initial();
+#endif
+#ifdef CONFIG_CAN_IAP
+		qws_iap_write_magic(0x11223344);
+#endif
+	/*extern void test_io(void);
+	for(;;)
+	{
+
+		test_io();
+	}*/
+	for(;;)
+	{
+#if DEBUG_MODE == 0
+		Feed_Watch_Dog();
+#endif
+
+		Check_Can_Poll();
+
+		Check_CB_Operate_State();
+
+		Intelligent_Management_Battery();
+
+		//Check_Battery_Small_Current();
+		
+		Check_Charge_In();
+			
+		Sub_BMS_1_lt_State();
+		
+		Sub_BMS_2_lt_State();
+	
+		Check_Sub_BMS_1();
+
+		Check_Sub_BMS_2();
+
+		Check_End_Ctr_Status();
+		
+		Check_Can_Self_Send_Status();
+
+		Cal_Sheng_Yu_Li_Cheng();
+
+		Check_S11_May_Operate();
+		
+		if(g_event & SUB_BMS_1_SEND_CMD_EVENT)
+		{
+			if(update_bat.ub_bat != UPDATE_BAT_1)
+				Send_Sub_BMS_1_CMD();
+			
+			g_event &= ~SUB_BMS_1_SEND_CMD_EVENT;
+		}
+
+		if(g_event & SUB_BMS_2_SEND_CMD_EVENT)
+		{
+			if(update_bat.ub_bat != UPDATE_BAT_2)
+				Send_Sub_BMS_2_CMD();
+			
+			g_event &= ~SUB_BMS_2_SEND_CMD_EVENT;
+		}
+
+		
+		if(g_event & BMS_1_RESEND_CMD_EVENT)
+		{
+			if(Resend_can_bms_1_frame())
+			{
+				g_event &= ~BMS_1_RESEND_CMD_EVENT;
+			}
+		}
+
+		if(g_event & BMS_2_RESEND_CMD_EVENT)
+		{
+			if(Resend_can_bms_2_frame())
+			{
+				g_event &= ~BMS_2_RESEND_CMD_EVENT;
+			}
+		}
+
+		if(g_event & END_CTR_RESEND_CMD_EVENT)
+		{
+			if(Resend_can_ctr_frame())
+			{
+				g_event &= ~END_CTR_RESEND_CMD_EVENT;
+			}
+		}
+
+		if(g_event & ADAS_RESEND_CMD_EVENT)
+		{
+			if(Resend_can_adas_frame())
+			{
+				g_event &= ~ADAS_RESEND_CMD_EVENT;
+			}
+		}
+		
+		//if(g_event & EVENT_CAN_RECEIVE_FINISH)
+		{
+			if(Handle_Can_Data() == 1)
+			{
+				// output fail
+				
+				;
+			}
+			
+			//g_event &= ~EVENT_CAN_RECEIVE_FINISH;
+		}
+
+		if(g_event & MEASURE_TEMPERATURE_EVENT)
+		{
+			
+			getTemperature();
+			
+			g_event &= ~MEASURE_TEMPERATURE_EVENT;
+		}
+
+		if(g_event & SUB_BMS_1_RS485_DISC_EVENT)
+		{
+			
+			RS485_Communication_Time_Out_1();
+			
+			g_event &= ~SUB_BMS_1_RS485_DISC_EVENT;
+		}
+		
+		if(g_event & SUB_BMS_2_RS485_DISC_EVENT)
+		{
+			
+			RS485_Communication_Time_Out_2();
+			
+			g_event &= ~SUB_BMS_2_RS485_DISC_EVENT;
+		}
+		
+		
+		if(g_event & RS485_RECEIVE_END_EVENT)
+		{
+			
+			if(Handle_RS485_1_Data() == 1)
+			{
+				// output fail
+				
+				;
+			}
+			g_event &= ~RS485_RECEIVE_END_EVENT;
+		}
+	
+		if(g_event & RS485_2_RECEIVE_END_EVENT)
+		{
+			
+			if(Handle_RS485_2_Data() == 1)
+			{
+				// output fail
+				
+				;
+			}
+			g_event &= ~RS485_2_RECEIVE_END_EVENT;
+		}
+
+		
+		if(g_event & BMS_1_SELF_TIMEOUT_EVENT)
+		{
+			Timeout_Resend_can_bms_1_frame();
+			
+			g_event &= ~BMS_1_SELF_TIMEOUT_EVENT;
+			
+		}
+
+		if(g_event & BMS_2_SELF_TIMEOUT_EVENT)
+		{
+			Timeout_Resend_can_bms_2_frame();
+		
+			g_event &= ~BMS_2_SELF_TIMEOUT_EVENT;
+			
+		}
+
+		if(g_event & END_CTR_SELF_TIMEOUT_EVENT)
+		{
+			Timeout_Resend_can_ctr_frame();
+			
+			g_event &= ~END_CTR_SELF_TIMEOUT_EVENT;
+			
+		}
+
+		if(g_event & ADAS_SELF_TIMEOUT_EVENT)
+		{
+			Timeout_Resend_can_adas_frame();
+			
+			g_event &= ~ADAS_SELF_TIMEOUT_EVENT;
+			
+		}
+
+		if(g_event & ADAS_PWM_1_TIMEOUT_EVENT)
+		{
+			ADAS_PWM_1_Enable();
+			
+			g_event &= ~ADAS_PWM_1_TIMEOUT_EVENT;
+			
+		}
+
+		if(g_event & ADAS_PWM_2_TIMEOUT_EVENT)
+		{
+			ADAS_PWM_2_Enable();
+			
+			g_event &= ~ADAS_PWM_2_TIMEOUT_EVENT;
+			
+		}
+
+		if(g_event & ADAS_MEAS_1_FINISH_EVENT)
+		{
+			ADAS_Measure_Finish_Ju_Li_1();
+
+			ADAS_Self_Send_Up();
+			
+			g_event &= ~ADAS_MEAS_1_FINISH_EVENT;
+			
+		}
+
+		if(g_event & ADAS_MEAS_2_FINISH_EVENT)
+		{
+			ADAS_Measure_Finish_Ju_Li_2();
+			
+			g_event &= ~ADAS_MEAS_2_FINISH_EVENT;
+			
+		}
+
+		if(g_event & ENTER_SLEEP_EVENT)
+		{
+			
+		    Enter_Sleep();
+			
+			g_event &= ~ENTER_SLEEP_EVENT;
+			
+		}
+		
+		if(g_event & RE_INITIAL_CAN_EVENT)
+		{
+			
+		  //Can_Com_Initial();
+			
+			g_event &= ~RE_INITIAL_CAN_EVENT;
+			
+		}
+		
+		if(g_event & DEVICE_REBOOT_EVENT)
+		{	
+			g_event &= ~DEVICE_REBOOT_EVENT;
+		  	__set_FAULTMASK(1);
+			NVIC_SystemReset();
+		}
+
+		if(g_event & SAVE_PARAM_EVENT)
+		{	
+			g_event &= ~SAVE_PARAM_EVENT;
+		  	Save_Param();
+		}
+		
+	}
+	
+	//return (1);
+
+}
+
+
+
+
+	
+#ifdef  USE_FULL_ASSERT
+
+/**
+  * @brief  Reports the name of the source file and the source line number
+  *   where the assert_param error has occurred.
+  * @param  file: pointer to the source file name
+  * @param  line: assert_param error line source number
+  * @retval None
+  */
+void assert_failed(u8_t* file, uint32_t line)
+{ 
+  /* User can add his own implementation to report the file name and line number,
+     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+
+  /* Infinite loop */
+  while (1)
+  {
+  }
+}
+#endif
+
+/*********************************************************************************************************
+      END FILE
+*********************************************************************************************************/
+
+

+ 350 - 0
Source/measure_temprature.c

@@ -0,0 +1,350 @@
+#include"common.h"
+#include "drv_adc.h"
+#include "measure_temprature.h"
+
+// 温度作为索引
+#define T_END							(85u+40u+1u)//Maximum number of elements in the temperature table
+#define B_VALUE
+#ifndef B_VALUE
+static const unsigned short T_PCB_Table[T_END] = 
+{
+	0xF30B,		//-40[degrees C]
+	0xF25C,		//-39[degrees C]
+	0xF1A4,		//-38[degrees C]
+	0xF0E6,		//-37[degrees C]
+	0xF021,		//-36[degrees C]
+	0xEF54,		//-35[degrees C]
+	0xEE7E,		//-34[degrees C]
+	0xEDA1,		//-33[degrees C]
+	0xECBD,		//-32[degrees C]
+	0xEBCD,		//-31[degrees C]
+	0xEAD7,		//-30[degrees C]
+	0xE9D1,		//-29[degrees C]
+	0xE8C7,		//-28[degrees C]
+	0xE7AF,		//-27[degrees C]
+	0xE68F,		//-26[degrees C]
+	0xE565,		//-25[degrees C]
+	0xE432,		//-24[degrees C]
+	0xE2F6,		//-23[degrees C]
+	0xE1B0,		//-22[degrees C]
+	0xE061,		//-21[degrees C]
+	0xDF07,		//-20[degrees C]
+	0xDD9E,		//-19[degrees C]
+	0xDC29,		//-18[degrees C]
+	0xDAAC,		//-17[degrees C]
+	0xD924,		//-16[degrees C]
+	0xD793,		//-15[degrees C]
+	0xD5F7,		//-14[degrees C]
+	0xD452,		//-13[degrees C]
+	0xD2A4,		//-12[degrees C]
+	0xD0EB,		//-11[degrees C]
+	0xCF29,		//-10[degrees C]
+	0xCD54,		//-9[degrees C]
+	0xCB76,		//-8[degrees C]
+	0xC98D,		//-7[degrees C]
+	0xC79D,		//-6[degrees C]
+	0xC5A3,		//-5[degrees C]
+	0xC3A2,		//-4[degrees C]
+	0xC197,		//-3[degrees C]
+	0xBF85,		//-2[degrees C]
+	0xBD6D,		//-1[degrees C]
+	0xBB49,		//0[degrees C]
+	0xB919,		//1[degrees C]
+	0xB6E0,		//2[degrees C]
+	0xB4A4,		//3[degrees C]
+	0xB261,		//4[degrees C]
+	0xB015,		//5[degrees C]
+	0xADC6,		//6[degrees C]
+	0xAB78,		//7[degrees C]
+	0xA91F,		//8[degrees C]
+	0xA6C3,		//9[degrees C]
+	0xA467,		//10[degrees C]
+	0xA1FB,		//11[degrees C]
+	0x9F93,		//12[degrees C]
+	0x9D1F,		//13[degrees C]
+	0x9AB2,		//14[degrees C]
+	0x9847,		//15[degrees C]
+	0x95D4,		//16[degrees C]
+	0x9366,		//17[degrees C]
+	0x90F3,		//18[degrees C]
+	0x8E7D,		//19[degrees C]
+	0x8C14,		//20[degrees C]
+	0x899D,		//21[degrees C]
+	0x8736,		//22[degrees C]
+	0x84C6,		//23[degrees C]
+	0x825B,		//24[degrees C]
+	0x7FF8,		//25[degrees C]
+	0x7D92,		//26[degrees C]
+	0x7B32,		//27[degrees C]
+	0x78D6,		//28[degrees C]
+	0x7680,		//29[degrees C]
+	0x742E,		//30[degrees C]
+	0x71DC,		//31[degrees C]
+	0x6F92,		//32[degrees C]
+	0x6D4D,		//33[degrees C]
+	0x6B11,		//34[degrees C]
+	0x68DA,		//35[degrees C]
+	0x66AC,		//36[degrees C]
+	0x6483,		//37[degrees C]
+	0x6264,		//38[degrees C]
+	0x604C,		//39[degrees C]
+	0x5E3A,		//40[degrees C]
+	0x5C2E,		//41[degrees C]
+	0x5A27,		//42[degrees C]
+	0x582A,		//43[degrees C]
+	0x5638,		//44[degrees C]
+	0x544B,		//45[degrees C]
+	0x5269,		//46[degrees C]
+	0x508E,		//47[degrees C]
+	0x4EBB,		//48[degrees C]
+	0x4CF3,		//49[degrees C]
+	0x4B31,		//50[degrees C]
+	0x4977,		//51[degrees C]
+	0x47C2,		//52[degrees C]
+	0x4616,		//53[degrees C]
+	0x4474,		//54[degrees C]
+	0x42DC,		//55[degrees C]
+	0x414C,		//56[degrees C]
+	0x3FC3,		//57[degrees C]
+	0x3E44,		//58[degrees C]
+	0x3CCE,		//59[degrees C]
+	0x3B5D,		//60[degrees C]
+	0x39F3,		//61[degrees C]
+	0x3894,		//62[degrees C]
+	0x3738,		//63[degrees C]
+	0x35E7,		//64[degrees C]
+	0x349E,		//65[degrees C]
+	0x335E,		//66[degrees C]
+	0x3222,		//67[degrees C]
+	0x30EF,		//68[degrees C]
+	0x2FC6,		//69[degrees C]
+	0x2EA2,		//70[degrees C]
+	0x2D84,		//71[degrees C]
+	0x2C6B,		//72[degrees C]
+	0x2B59,		//73[degrees C]
+	0x2A4D,		//74[degrees C]
+	0x294C,		//75[degrees C]
+	0x284D,		//76[degrees C]
+	0x2756,		//77[degrees C]
+	0x2665,		//78[degrees C]
+	0x257C,		//79[degrees C]
+	0x2496,		//80[degrees C]
+	0x23B8,		//81[degrees C]
+	0x22DD,		//82[degrees C]
+	0x2205,		//83[degrees C]
+	0x213A,		//84[degrees C]
+	0x206E		//85[degrees C]
+};
+#else
+static const unsigned short T_PCB_Table[T_END] = 
+{
+	0xF620,		//-40[degrees C]
+	0xF582,		//-39[degrees C]
+	0xF4DC,		//-38[degrees C]
+	0xF42E,		//-37[degrees C]
+	0xF378,		//-36[degrees C]
+	0xF2B9,		//-35[degrees C]
+	0xF1F1,		//-34[degrees C]
+	0xF120,		//-33[degrees C]
+	0xF045,		//-32[degrees C]
+	0xEF61,		//-31[degrees C]
+	0xEE73,		//-30[degrees C]
+	0xED7A,		//-29[degrees C]
+	0xEC77,		//-28[degrees C]
+	0xEB69,		//-27[degrees C]
+	0xEA51,		//-26[degrees C]
+	0xE92D,		//-25[degrees C]
+	0xE7FE,		//-24[degrees C]
+	0xE6C4,		//-23[degrees C]
+	0xE57E,		//-22[degrees C]
+	0xE42C,		//-21[degrees C]
+	0xE2CF,		//-20[degrees C]
+	0xE166,		//-19[degrees C]
+	0xDFF0,		//-18[degrees C]
+	0xDE6F,		//-17[degrees C]
+	0xDCE2,		//-16[degrees C]
+	0xDB48,		//-15[degrees C]
+	0xD9A3,		//-14[degrees C]
+	0xD7F1,		//-13[degrees C]
+	0xD634,		//-12[degrees C]
+	0xD46A,		//-11[degrees C]
+	0xD295,		//-10[degrees C]
+	0xD0B4,		//-9[degrees C]
+	0xCEC8,		//-8[degrees C]
+	0xCCD1,		//-7[degrees C]
+	0xCACF,		//-6[degrees C]
+	0xC8C1,		//-5[degrees C]
+	0xC6AA,		//-4[degrees C]
+	0xC488,		//-3[degrees C]
+	0xC25D,		//-2[degrees C]
+	0xC028,		//-1[degrees C]
+	0xBDE9,		//0[degrees C]
+	0xBBA3,		//1[degrees C]
+	0xB954,		//2[degrees C]
+	0xB6FD,		//3[degrees C]
+	0xB49F,		//4[degrees C]
+	0xB23A,		//5[degrees C]
+	0xAFCF,		//6[degrees C]
+	0xAD5E,		//7[degrees C]
+	0xAAE8,		//8[degrees C]
+	0xA86D,		//9[degrees C]
+	0xA5EE,		//10[degrees C]
+	0xA36B,		//11[degrees C]
+	0xA0E5,		//12[degrees C]
+	0x9E5D,		//13[degrees C]
+	0x9BD3,		//14[degrees C]
+	0x9947,		//15[degrees C]
+	0x96BB,		//16[degrees C]
+	0x942E,		//17[degrees C]
+	0x91A2,		//18[degrees C]
+	0x8F17,		//19[degrees C]
+	0x8C8C,		//20[degrees C]
+	0x8A04,		//21[degrees C]
+	0x877E,		//22[degrees C]
+	0x84FB,		//23[degrees C]
+	0x827C,		//24[degrees C]
+	0x8000,		//25[degrees C]
+	0x7D88,		//26[degrees C]
+	0x7B16,		//27[degrees C]
+	0x78A8,		//28[degrees C]
+	0x763F,		//29[degrees C]
+	0x73DD,		//30[degrees C]
+	0x7181,		//31[degrees C]
+	0x6F2B,		//32[degrees C]
+	0x6CDC,		//33[degrees C]
+	0x6A94,		//34[degrees C]
+	0x6853,		//35[degrees C]
+	0x661A,		//36[degrees C]
+	0x63E8,		//37[degrees C]
+	0x61BF,		//38[degrees C]
+	0x5F9E,		//39[degrees C]
+	0x5D85,		//40[degrees C]
+	0x5B74,		//41[degrees C]
+	0x596C,		//42[degrees C]
+	0x576D,		//43[degrees C]
+	0x5576,		//44[degrees C]
+	0x5389,		//45[degrees C]
+	0x51A4,		//46[degrees C]
+	0x4FC8,		//47[degrees C]
+	0x4DF4,		//48[degrees C]
+	0x4C2A,		//49[degrees C]
+	0x4A69,		//50[degrees C]
+	0x48B0,		//51[degrees C]
+	0x4701,		//52[degrees C]
+	0x455A,		//53[degrees C]
+	0x43BC,		//54[degrees C]
+	0x4227,		//55[degrees C]
+	0x409A,		//56[degrees C]
+	0x3F16,		//57[degrees C]
+	0x3D9A,		//58[degrees C]
+	0x3C27,		//59[degrees C]
+	0x3ABC,		//60[degrees C]
+	0x3959,		//61[degrees C]
+	0x37FE,		//62[degrees C]
+	0x36AC,		//63[degrees C]
+	0x3561,		//64[degrees C]
+	0x341D,		//65[degrees C]
+	0x32E2,		//66[degrees C]
+	0x31AD,		//67[degrees C]
+	0x3080,		//68[degrees C]
+	0x2F5B,		//69[degrees C]
+	0x2E3C,		//70[degrees C]
+	0x2D24,		//71[degrees C]
+	0x2C13,		//72[degrees C]
+	0x2B09,		//73[degrees C]
+	0x2A05,		//74[degrees C]
+	0x2908,		//75[degrees C]
+	0x2811,		//76[degrees C]
+	0x2720,		//77[degrees C]
+	0x2635,		//78[degrees C]
+	0x2550,		//79[degrees C]
+	0x2471,		//80[degrees C]
+	0x2397,		//81[degrees C]
+	0x22C2,		//82[degrees C]
+	0x21F4,		//83[degrees C]
+	0x212A,		//84[degrees C]
+	0x2065		//85[degrees C]
+};
+#endif
+
+DELAY_COMMON measure_temp;
+
+int8_t ctr_temperature[THER_NUM_CON];
+
+//const static unsigned char p_TempeNum= THER_NUM_CON;
+uint8_t temp_index = 0;
+
+void getTemperature(void)
+{
+	unsigned short count,adc_temp = 0;
+	uint8_t ch_no = 0;
+	
+	Mea_Temp_Enable(1);
+	temp_index = (++temp_index)%THER_NUM_CON;
+	switch(temp_index)
+	{
+		case 0:
+			ch_no = adc_temperatrue_0;
+			break;
+		case 1:
+			ch_no = adc_temperatrue_1;
+			break;
+		default:
+			temp_index = 0;
+			ch_no = adc_temperatrue_0;
+			break;	
+	}
+
+	
+	// get adc value
+	if(adc_getResult_6t(ch_no, &adc_temp) != 1)
+	{
+		goto error;
+	}
+
+	Mea_Temp_Enable(0);
+	adc_temp <<= 4;
+
+	// find 温度通过adc值查表
+	for(count=(T_END-1u);count>0u;count--)
+	{
+		if(adc_temp <= T_PCB_Table[count] )
+		{
+			ctr_temperature[temp_index] = (int8_t)count - (int8_t)40;
+
+			//adjust-start
+			//if(thNo == 0)
+			//res->Tadr -= 2;
+			//adjust-end
+				
+			
+			return;
+		}
+	}
+	
+error:	
+	ctr_temperature[temp_index] = 0u;	
+	
+	return;
+	
+}
+void Measure_Temprature_Initial(void)
+{
+	
+	_Measure_Temprature_Initial();
+	
+	//
+	measure_temp.set = 1;
+	measure_temp.count = 0;
+
+	memset(&ctr_temperature,0x00,sizeof(ctr_temperature));
+
+
+	for(uint8_t i = 0; i < THER_NUM_CON;i++)
+		getTemperature();
+}
+
+
+
+
+

+ 26 - 0
Source/measure_temprature.h

@@ -0,0 +1,26 @@
+#ifndef _MEASURE_TEMP_H
+#define _MEASURE_TEMP_H
+
+
+extern int8_t ctr_temperature[THER_NUM_CON] ;
+
+extern DELAY_COMMON measure_temp;
+
+__inline void Measure_Temprature_Delay(void)
+{
+	if(measure_temp.set)
+	{
+		if(++measure_temp.count >= 1)
+		{
+			measure_temp.count = 0;
+			g_event |= MEASURE_TEMPERATURE_EVENT;
+		}
+	}
+}
+//**********************************************temperature********************************************
+void getTemperature(void);
+
+void Measure_Temprature_Initial(void);
+
+#endif
+

+ 38 - 0
Source/measure_vol.c

@@ -0,0 +1,38 @@
+#include"common.h"
+#include "drv_adc.h"
+#include "measure_vol.h"
+
+ 
+
+uint32_t Measure_Vol(void)
+{
+	unsigned short adc_temp = 0;
+	uint32_t Batter_Vol = 0xFFFFFFFF;
+	
+	// get adc value
+	if(adc_getResult_6t(adc_vbat, &adc_temp) != 1)
+	{
+		goto error;
+	}
+	
+	//
+	Batter_Vol = adc_temp*3300UL*101/4095;
+	
+error:	
+	
+	return Batter_Vol;
+}
+
+void Measure_Vol_Initial(void)
+{
+	
+	_Measure_Vol_Initial();
+	
+	//
+
+}
+
+
+
+
+

+ 11 - 0
Source/measure_vol.h

@@ -0,0 +1,11 @@
+#ifndef _MEASURE_VOL_H
+#define _MEASURE_VOL_H
+
+
+//**********************************************vol********************************************
+uint32_t Measure_Vol(void);
+
+void Measure_Vol_Initial(void);
+
+#endif
+

+ 3 - 0
Source/sw_build_info.h

@@ -0,0 +1,3 @@
+#pragma once
+
+#define CONFIG_VERSION "PS100XX_V01_0C020915"