<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/product/STM32F105_2CAN/index.html" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
<iframe frameborder="0" height="1500" name="ifd" scrolling="auto" src="https://mnifdv.cn/resource/cnblogs/product/STM32F105_2CAN/index.html" width="100%"></iframe>
说明
这节是把设备从CAN总线接收的数据发送到TCP服务器, 设备从TCP服务器接收的数据通过CAN总线输出;
测试
1,打开工程
2,根据自己的设备设置CAN波特率
3,默认连接这边的服务器进行测试,用户如果要测试需要修改为连接自己的服务器
4,设备日志打印如下说明连接成功
5,我在我的服务器上打开调试助手进行测试
6,接上CAN总线设备
7,如果设备接收到CAN数据,将会发送到TCP调试助手上
数据格式说明: 01 00 00 01 02 55 55 55 55 55 55 55 55
最前面一位是0x01; 最前面的0代表这个数据是数据帧,后面的1代表第一路CAN数据,;
中间 00 00 01 02 四位是帧 ID; 最后 55 55 55 55 55 55 55 55 8位是数据
数据格式说明: 11 00 00 01 02 00 00 00 00 00 00 00 00
最前面一位是0x11; 最前面的1代表这个数据是遥控帧,后面的1代表第一路CAN数据,;
中间 00 00 01 02 四位是帧 ID; 最后 00 00 00 00 00 00 00 00 8位是数据
如果是第二路:
7,通过TCP调试助手发送数据给设备
由于网络通信接收数据有可能出现数据分包和粘包,所以数据格式改了下
测试1:
假设给第一路CAN发送一个数据帧, 然后ID是 0x1234 数据是 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
实际发送的数据: 55 AA 00 0E 01 00 00 12 34 00 01 02 03 04 05 06 07 70
55 AA为固定头; 00 0E代表后面的数据个数; 01 00 00 12 34 00 01 02 03 04 05 06 07 是实际数据; 最后的70是前面所有数据累加和 然后%256
实际数据和上面的格式是一样的, 最前面的 01 代表第一路; 00 00 12 34 是ID; 00 01 02 03 04 05 06 07 是CAN数据
这边用了CAN分析仪监测的设备数据
测试2:
假设给第一路CAN发送一个遥控帧, 然后ID是 0x1234
实际发送的数据为: 55 AA 00 0E 11 00 00 12 34 00 01 02 03 04 05 06 07 80
测试3:
假设给第二路CAN发送一个数据帧, 然后ID是 0x1234 数据是 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
实际发送的数据: 55 AA 00 0E 02 00 00 12 34 00 01 02 03 04 05 06 07 71
测试4:
假设给第二路CAN发送一个遥控帧, 然后ID是 0x1234 ,后面的数据随意
实际发送的数据为: 55 AA 00 0E 12 00 00 12 34 00 01 02 03 04 05 06 07 81
程序说明
1,串口2接收模组数据的时候,单独使用一个缓存,缓存了TCP/IP接收的数据
2,连接TCP服务器
3,CAN接收的数据是存储到了环形队列
4,把接收的CAN数据发送到TCP服务器
5.从TCP服务器收到的消息通过CAN总线输出
int tcp_client_read_data_timeout=0; uint8_t tcp_client_read_data_switch=0; uint8_t tcp_client_read_data[1460]; uint16_t tcp_client_read_data_len=0; /** * @brief 设备接收数据(高速处理模式,可以处理分包和粘包) * @param None * @retval None * @warning None * @example **/ void tcp_client_data_while(void) { int len=0,i=0,sum=0; uint32_t CAN_IDE=0; if(tcp_client_read_data_switch==0) { len = rbCanRead(&rb_t_net_read);//获取模组返回的TCP数据 if(len>0) { memset(tcp_client_read_data,0,sizeof(tcp_client_read_data)); rbRead(&rb_t_net_read, &tcp_client_read_data[0], 1); if(tcp_client_read_data[0]==0x55) { tcp_client_read_data_switch=1; tcp_client_read_data_timeout=0; } } } else if(tcp_client_read_data_switch==1) { len = rbCanRead(&rb_t_net_read);//获取模组返回的TCP数据 if(len>0) { rbRead(&rb_t_net_read, &tcp_client_read_data[1], 1); if(tcp_client_read_data[1]==0xAA) { tcp_client_read_data_switch=2; } else { if(tcp_client_read_data[1]==0x55) { tcp_client_read_data_switch=1; } else { tcp_client_read_data_switch=0; } } tcp_client_read_data_timeout=0; } else { if(tcp_client_read_data_timeout>=5000) { tcp_client_read_data_timeout=0; tcp_client_read_data_switch=0; } } } else if(tcp_client_read_data_switch==2) { len = rbCanRead(&rb_t_net_read);//获取模组返回的TCP数据 if(len>1) { rbRead(&rb_t_net_read, &tcp_client_read_data[2], 2); tcp_client_read_data_len = tcp_client_read_data[2]; tcp_client_read_data_len = tcp_client_read_data_len<<8; tcp_client_read_data_len = tcp_client_read_data_len+tcp_client_read_data[3]; tcp_client_read_data_switch=3; tcp_client_read_data_timeout=0; } else { if(tcp_client_read_data_timeout>=5000) { tcp_client_read_data_timeout=0; tcp_client_read_data_switch=0; } } } else if(tcp_client_read_data_switch==3) { len = rbCanRead(&rb_t_net_read);//获取模组返回的TCP数据 if(len>=tcp_client_read_data_len) { rbRead(&rb_t_net_read, &tcp_client_read_data[4], tcp_client_read_data_len); sum=0; for(i=0;i<(tcp_client_read_data_len+3);i++) { sum = sum+tcp_client_read_data[i]; } sum = sum%256; if(sum == tcp_client_read_data[tcp_client_read_data_len+3]) { memset(tcp_client_buff,0,sizeof(tcp_client_buff)); memcpy(tcp_client_buff, &tcp_client_read_data[4], tcp_client_read_data_len-1); debug_printf("\r\ncan data:"); for(i=0;i<len;i++) { debug_printf("%02x,",tcp_client_buff[i]); } debug_printf("\r\n"); CAN_IDE = tcp_client_buff[1]; CAN_IDE = CAN_IDE<<8; CAN_IDE = CAN_IDE + tcp_client_buff[2]; CAN_IDE = CAN_IDE<<8; CAN_IDE = CAN_IDE + tcp_client_buff[3]; CAN_IDE = CAN_IDE<<8; CAN_IDE = CAN_IDE + tcp_client_buff[4];//ID if(CAN_IDE>0x7FF)//扩展帧 { CanTxMsgValue.IDE = CAN_ID_EXT; CanTxMsgValue.ExtId = CAN_IDE; debug_printf("CAN_ID_EXT\r\n"); } else//标准帧 { CanTxMsgValue.IDE = CAN_ID_STD; CanTxMsgValue.StdId = CAN_IDE; debug_printf("CAN_ID_STD\r\n"); } CanTxMsgValue.RTR=CAN_RTR_DATA; if((tcp_client_buff[0]&0x10) == 0x10)//遥控帧 { CanTxMsgValue.RTR = CAN_RTR_REMOTE; debug_printf("CAN_RTR_REMOTE\r\n"); } CanTxMsgValue.DLC = 8; memcpy(CanTxMsgValue.Data, &tcp_client_buff[5], 8);//拷贝数据 if((tcp_client_buff[0]&0x01) == 0x01)//发送给CAN1口 { debug_printf("CAN_SendData(CAN1, &CanTxMsgValue)\r\n"); CAN_SendData(CAN1, &CanTxMsgValue);//发送CAN数据 } else if((tcp_client_buff[0]&0x02) == 0x02)//发送给CAN2口 { debug_printf("CAN_SendData(CAN2, &CanTxMsgValue)\r\n"); CAN_SendData(CAN2, &CanTxMsgValue);//发送CAN数据 } tcp_client_read_data_switch=0; } else { tcp_client_read_data_switch=0; } } else { if(tcp_client_read_data_timeout>=5000) { tcp_client_read_data_timeout=0; tcp_client_read_data_switch=0; } } } } /** * @brief 设备接收数据 * @param None * @retval None * @warning None * @example **/ void tcp_client_into_data(char *data, int length) { int len = length; uint32_t CAN_IDE=0; int i=0; debug_printf("\r\ntcp read:"); for(i=0;i<len;i++) { debug_printf("%02x,",data[i]); } debug_printf("\r\n"); memset(tcp_client_buff,0,sizeof(tcp_client_buff)); if(len> sizeof(tcp_client_buff)) { len = sizeof(tcp_client_buff); memcpy(tcp_client_buff, data, sizeof(tcp_client_buff)); } else{ memcpy(tcp_client_buff, data, len); } if(length==13) { CAN_IDE = tcp_client_buff[1]; CAN_IDE = CAN_IDE<<8; CAN_IDE = CAN_IDE + tcp_client_buff[2]; CAN_IDE = CAN_IDE<<8; CAN_IDE = CAN_IDE + tcp_client_buff[3]; CAN_IDE = CAN_IDE<<8; CAN_IDE = CAN_IDE + tcp_client_buff[4];//ID if(CAN_IDE>0x7FF)//扩展帧 { CanTxMsgValue.IDE = CAN_ID_EXT; CanTxMsgValue.ExtId = CAN_IDE; debug_printf("CAN_ID_EXT\r\n"); } else//标准帧 { CanTxMsgValue.IDE = CAN_ID_STD; CanTxMsgValue.StdId = CAN_IDE; debug_printf("CAN_ID_STD\r\n"); } CanTxMsgValue.RTR=CAN_RTR_DATA; if((tcp_client_buff[0]&0x10) == 0x10)//遥控帧 { CanTxMsgValue.RTR = CAN_RTR_REMOTE; debug_printf("CAN_RTR_REMOTE\r\n"); } CanTxMsgValue.DLC = 8; memcpy(CanTxMsgValue.Data, &tcp_client_buff[5], 8);//拷贝数据 if((tcp_client_buff[0]&0x01) == 0x01)//发送给CAN1口 { debug_printf("CAN_SendData(CAN1, &CanTxMsgValue)\r\n"); CAN_SendData(CAN1, &CanTxMsgValue);//发送CAN数据 } else if((tcp_client_buff[0]&0x02) == 0x02)//发送给CAN2口 { debug_printf("CAN_SendData(CAN2, &CanTxMsgValue)\r\n"); CAN_SendData(CAN2, &CanTxMsgValue);//发送CAN数据 } } }
6,程序里面默认还获取了 IMEI,ICCID,CSQ,时间等,都解析好了,用户可以直接选择对应的变量使用
用户可以在这里更改定时获取时间参数
.
标签:00,CanTxMsgValue,read,双路,tcp,TCP,client,控制板,data From: https://www.cnblogs.com/yangfengwu/p/18075230