在线时间57 小时
UID3095278
注册时间2015-8-6
NXP金币0
该用户从未签到
中级会员
 
- 积分
- 355
- 最后登录
- 2019-1-28
|

楼主 |
发表于 2016-6-17 16:31:43
|
显示全部楼层
这是代码,我写的有些乱,您多指点。//地址及命令打包函数
uint8 *Instruction_Package(uint8 i)
{
uint8 Current_Sdmu_Num;
Current_Sdmu_Num=i;
Command_Pack[0]=0x30|bms;
Command_Pack[1]=Current_Sdmu_Num;
return Command_Pack;
}
//超时处理函数
void Timer_Out_Handle()
{
Overtime_Flag=1; //超时处理标志位置位
Overtime_Counter++; //串口超时计数器加一
if(Overtime_Counter<TIME_OUT) //判断超时处理次数是否达到上限
{
index=0;
}
else
{
Connection_Exception=1; //连接异常标志位置位
}
}
//数据读取函数
void Read_Sdmu(void)
{
uint8 i;
uint8 j;
uint8 k,l;
uint8 *command=NULL;
uint8 Overtime_2=0; //表示第二种情况的超时
uint8 Read_Bms_Success=0; //一帧数据读取成功
for(i=1;i<=Sdmu_Num;i++)
{
Overtime_2=0;
for(bms=1;bms<5;bms++)
{
if(Overtime_2)
{
break;
}
Read_Bms_Success=0;
RS485_SEND; //rs485切换为发送状态
DrvUART_SendNBytes(UART1, Start_Bit, 1);//发送一字节起始位
delay_1ms(1); //延时1ms,等待数据发送完成
while(!Send_Flag); //等待发送完成标志位置1
Send_Flag=0; //发送完成标志位清零
RS485_RECEIVE; //rs485切换为接收状态
Receive_State_Flag=1; //接收状态标志位,表示此时接收到的为响应码
Timer_Counter=10000;
if(Overtime_Counter<TIME_OUT)
{
while(1)
{
if(Read_Bms_Success)
{
break;
}
else if(!Timer_Counter) //如果发生超时,则进行超时处理
{
Timer_Out_Handle(); //调用超时处理函数
if(Overtime_Counter<TIME_OUT)
{
bms--;
}
break;//跳出超时循环,重发起始码
}
else if((index==1)|(index==Data_Num))
{
if((Receive_State_Flag==1)&(Data_Cache[0]==0x56))
{
index=0; //数据缓存数组元素个数计数器清零
Overtime_Flag=0; //超时标志位清零
Data_Cache[0]=0x00; //缓存数组清零
Receive_State_Flag=0; //数据接收状态标志清零
RS485_SEND; //rs485切换为发送状态
command = Instruction_Package(i); //调用命令和地址打包函数
DrvUART_SendNBytes(UART1,command, 2); //发送命令码和地址码
delay_1ms(1); //延时1ms,等待数据发送完成
while(!Send_Flag); //等待发送完成标志位置1
Send_Flag=0; //发送完成标志位清零
RS485_RECEIVE; //rs485切换为接收状态
Receive_State_Flag=2; //接收状态标志位,表示此时接收到的为数据帧
Timer_Counter=10000; //给定时计数器赋值,设置超时时间
if(Overtime_Counter<2)
{
while(1)
{
if(!Timer_Counter) //如果发生超时,则进行超时处理
{
Timer_Out_Handle(); //调用超时处理函数
index=1;
Data_Cache[0]=0x56;
Receive_State_Flag=1;
break;//此处应跳转到发送指令和地址的函数部分
}
else if((index==1)|(index==Data_Num))
{
if((Receive_State_Flag==2)&(index==Data_Num))
{
index=0; //数据缓存数组元素个数计数器清零
Overtime_Flag=0; //超时标志位清零
Overtime_Counter=0; //超时计数器清零
Receive_State_Flag=0; //数据接收状态标志清零
RS485_SEND; //rs485切换为发送状态
DrvUART_SendNBytes(UART1, End_Bit, 1); //发送一字节结束码
delay_1ms(1); //延时1ms,等待数据发送完成
while(!Send_Flag); //等待发送标志位置1
Send_Flag=0; //发送标志位清零
Crc_Result=CRC_Cal_16(0xffff,Data_Cache,Data_Num);//调用CRC校验函数进行CRC硬件校验
if(Crc_Error_Counter<CHECK_ERROR)
{
if(Crc_Result==0)
{
k=bms;
l=i;
l=4*(l-1)+k-1;
Sdmu_Bms[l][0]=(i<<4)|bms;
for(j=0;j<Data_Num;j++)
{
Sdmu_Bms[l][j]=Data_Cache[j];
printf("%2x ",Sdmu_Bms[l][j]);
}
Read_Bms_Success=1;//bms数据读取成功标志位置一
break;//跳转到bms循环层,读取下一路bms的数据
}
else
{
Crc_Failed_Handle(); //调用CRC校验错误处理函数
index=1; //缓存数组元素个数计数器变量置一
Data_Cache[0]=0x56; //缓存数组第一个元素值设为0x56
Receive_State_Flag=1;//接收状态标志位置一
break; //如果校验错误,应跳转到重发地址和指令的函数,重新进行该路bms数据的读取
}
}
else
{
index=1; //缓存数组元素个数计数器变量置一
Crc_Error_Flag=0; //CRC校验错误标志位清零
Data_Cache[0]=0x56; //缓存数组第一个元素值设为0x56
Crc_Error_Counter=0; //CRC校验计数器清零
Receive_State_Flag=1;//接收状态标志位置一
break;//如果校验失败次数超过三次,则跳转到bms循环层,读取下一路bms的数据
}
}
}
}
}
else
{
Overtime_2=1;
Overtime_Counter=0; //超时计数器清零
Overtime_Flag=0; //超时标志位置零
break; //跳出超时判断的循环体,进入bms循环体
}
}
}
}
}
else
{
Overtime_Counter=0; //超时计数器清零
Overtime_Flag=0; //超时标志位置零
break; //跳出bms的循环体,进入SDMU循环体
}
}
}
}
|
|