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

<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>

 

说明

这节是把设备从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,时间等,都解析好了,用户可以直接选择对应的变量使用

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

.

 

posted on 2024-03-15 13:41  广源时代  阅读(87)  评论(0编辑  收藏  举报

导航

支付宝 QQ群