前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >STM32F105双路隔离型CAN总线转4G控制板 - 把CAN数据发送到TCP服务器,实现通过TCP透传通信

STM32F105双路隔离型CAN总线转4G控制板 - 把CAN数据发送到TCP服务器,实现通过TCP透传通信

作者头像
杨奉武
发布2024-03-16 08:23:02
2991
发布2024-03-16 08:23:02
举报
文章被收录于专栏:知识分享

说明

这节是把设备从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总线输出

代码语言:javascript
复制
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,时间等,都解析好了,用户可以直接选择对应的变量使用

 用户可以在这里更改定时获取时间参数

.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 说明
  • 这节是把设备从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总线输出
                            • 6,程序里面默认还获取了 IMEI,ICCID,CSQ,时间等,都解析好了,用户可以直接选择对应的变量使用
                              •  用户可以在这里更改定时获取时间参数
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档