解析了新桑塔纳,解析到了方向盘角度,油门踏板深度,4门状态,左右转向灯、倒车灯,远近光等等。
1、首先配置can
void CAN_init(void)
{
CAN_InitTypeDef CAN_InitStructure; //结构定义
CAN_InitStructure.CAN_Enable = ENABLE; //CAN功能使能 ENABLE或DISABLE
CAN_InitStructure.CAN_IMR = CAN_ALLIM; //CAN中断寄存器 CAN_DOIM,CAN_BEIM,CAN_TIM,CAN_RIM,CAN_EPIM,CAN_EWIM,CAN_ALIM,CAN_ALLIM,DISABLE
CAN_InitStructure.CAN_SJW = 0; //重新同步跳跃宽度 0~3
CAN_InitStructure.CAN_SAM = 0; //总线电平采样次数 0:采样1次; 1:采样3次
//CAN总线波特率=Fclk/((1+(TSG1+1)+(TSG2+1))*(BRP+1)*2)
CAN_InitStructure.CAN_TSG1 = 2; //同步采样段1 0~15
CAN_InitStructure.CAN_TSG2 = 1; //同步采样段2 1~7 (TSG2 不能设置为0)
CAN_InitStructure.CAN_BRP = 3; //波特率分频系数 0~63
//24000000/((1+3+2)*4*2)=500KHz
CAN_InitStructure.CAN_ListenOnly = DISABLE; //Listen Only模式 ENABLE,DISABLE
CAN_InitStructure.CAN_Filter = DUAL_FILTER;//滤波选择 DUAL_FILTER(双滤波),SINGLE_FILTER(单滤波)
CAN_InitStructure.CAN_ACR0 = 0x00; //总线验收代码寄存器 0~0xFF
CAN_InitStructure.CAN_ACR1 = 0x00;
CAN_InitStructure.CAN_ACR2 = 0x00;
CAN_InitStructure.CAN_ACR3 = 0x00;
CAN_InitStructure.CAN_AMR0 = 0xff; //总线验收屏蔽寄存器 0~0xFF
CAN_InitStructure.CAN_AMR1 = 0xff;
CAN_InitStructure.CAN_AMR2 = 0xff;
CAN_InitStructure.CAN_AMR3 = 0xff;
CAN_Inilize(CAN2,&CAN_InitStructure); //CAN2 初始化
NVIC_CAN_Init(CAN2,ENABLE,Priority_1); //中断使能, CAN1/CAN2; ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
CAN2_SW(CAN2_P72_P73); //CAN2_P02_P03,CAN2_P52_P53,CAN2_P46_P47,CAN2_P72_P73
CAN2_Tx.FF = STANDARD_FRAME; //标准帧
CAN2_Tx.RTR = 0; //0:数据帧,1:远程帧
CAN2_Tx.DLC = 0x08; //数据长度
CAN2_Tx.ID = 0x07DF; //CAN ID
CAN2_Tx.DataBuffer[0] = 0x02; //ISO 15765协议 表数据长度
CAN2_Tx.DataBuffer[1] = 0x01; //发动机
CAN2_Tx.DataBuffer[2] = 0x0C; //转速
CAN2_Tx.DataBuffer[3] = 0x00;
CAN2_Tx.DataBuffer[4] = 0x00;
CAN2_Tx.DataBuffer[5] = 0x00;
CAN2_Tx.DataBuffer[6] = 0x00;
CAN2_Tx.DataBuffer[7] = 0x00;
}
2、然后初始化串口1,用来输出接收到的obd数据。
3、把接收到的can数据从串口输出,方便在电脑上分析
void Sample_CAN(void)
{
u8 n,i,j;
if(B_Can2Read)
{
B_Can2Read = 0;
CANSEL = CAN2; //选择CAN2模块
n = CanReadMsg(CAN2_Rx); //读取接收内容
if(n>0)
{
for(i=0;i<n;i++)
{
printf("CAN2 ID=0x%08lX DLC=%d FF=%d RTR=%d ",CAN2_Rx[i].ID,CAN2_Rx[i].DLC,CAN2_Rx[i].FF,CAN2_Rx[i].RTR);
for(j=0;j<CAN2_Rx[i].DLC;j++)
{
printf("0x%02X ",CAN2_Rx[i].DataBuffer[j]); //从串口输出收到的数据
}
printf("\r\n");
}
}
}
}
4、保存一段收到的报文数据,把pid去重
5、在上位机软件或单片机上过滤,每个筛选出来找信号。
6、这是我找到的部分信号
void OBD_process(u8 i)
{
switch (CAN2_Rx[i].ID)
{
case 0x0390:
handle_CAN_RX(CAN2_Rx[i].DataBuffer[0] & 0x40, &OBD_Data.KGL_data[20]); //位置灯
handle_CAN_RX(CAN2_Rx[i].DataBuffer[4] & 0x04, &OBD_Data.KGL_data[18]); //zz
handle_CAN_RX(CAN2_Rx[i].DataBuffer[4] & 0x08, &OBD_Data.KGL_data[19]); //yz
handle_CAN_RX(CAN2_Rx[i].DataBuffer[2] & 0x01, &OBD_Data.KGL_data[0]); //主门
handle_CAN_RX(CAN2_Rx[i].DataBuffer[5] & 0x02, &OBD_Data.KGL_data[1]); //副驾门
handle_CAN_RX(CAN2_Rx[i].DataBuffer[3] & 0x04, &OBD_Data.KGL_data[2]); //左后门
handle_CAN_RX(CAN2_Rx[i].DataBuffer[3] & 0x08, &OBD_Data.KGL_data[3]); //右后门
handle_CAN_RX(CAN2_Rx[i].DataBuffer[3] & 0x10, &OBD_Data.KGL_data[9]); //倒挡灯
handle_CAN_RX(CAN2_Rx[i].DataBuffer[7] & 0x08, &OBD_Data.KGL_data[17]); //刹车
handle_CAN_RX(CAN2_Rx[i].DataBuffer[6] & 0x01, &OBD_Data.KGL_data[21]); //近光
handle_CAN_RX(CAN2_Rx[i].DataBuffer[4] & 0x20, &OBD_Data.KGL_data[22]); //远光
handle_CAN_RX(CAN2_Rx[i].DataBuffer[6] & 0x80, &OBD_Data.KGL_data[10]); //双闪
break;
case 0x0380: //油门深度
OBD_Data.ym = CAN2_Rx[i].DataBuffer[2];
break;
case 0x0000c2: //方向盘角度
OBD_Data.wheel[0] = CAN2_Rx[i].DataBuffer[0];
OBD_Data.wheel[1] = CAN2_Rx[i].DataBuffer[1];
break;
case 0x0050:
handle_CAN_RX(CAN2_Rx[i].DataBuffer[1] & 0x10, &OBD_Data.KGL_data[11]); //主驾安全带
handle_CAN_RX(CAN2_Rx[i].DataBuffer[1] & 0x40, &OBD_Data.KGL_data[12]); //副驾安全带
break;
case 0x0280:
handle_CAN_RX(~CAN2_Rx[i].DataBuffer[0] & 0x08, &OBD_Data.KGL_data[13]); //离合 ,具体bit3位
break;
case 0x0320:
handle_CAN_RX(CAN2_Rx[i].DataBuffer[1] & 0x02, &OBD_Data.KGL_data[16]); //手刹
break;
case 0x0570:
if(CAN2_Rx[i].DataBuffer[0] == 0x00) OBD_Data.keyStateStrings = "OFF";
if(CAN2_Rx[i].DataBuffer[0] == 0x01) OBD_Data.keyStateStrings = "OFF";
else if(CAN2_Rx[i].DataBuffer[0] & 0x04) OBD_Data.keyStateStrings = "ON";
else if(CAN2_Rx[i].DataBuffer[0] & 0x08) OBD_Data.keyStateStrings = "START";
break;
default:
break;
}
}