USB-CAN收发器

低成本实现USB-CAN收发器

方案:使用UART+CAN实现CAN数据收发

一、器件选择

1、串口

串口波特率要高,封装要小,所以最终选择了CH340N

CH340N特征如下:

  • 串口波特率支持50~2Mbps
  • 支持5V与3.3V串口电平
  • 封装SOP-8
  • 内置晶振,外围精简

2、主控

主控只要求有UART和CAN即可

所以最终选择了STM32F042F4 其封装为TSSOP20

3、CAN PHY

选择了TJA1050

4、电源

电源主要为5V降3.3V,所以选择AMS1117

二、原理图

image

三、PCB

image

四、程序

1、库的选择

​ STM32程序编写主要分两种形式:库和寄存器。

HAL库:

到今天,STM32库的主流为HAL库,其主要特点为方便移植开发,芯片间兼容性高。但是也有很多缺点:

  • BUG多
  • 运行效率低

标准库:

HAL库之前就是标准库,这个库虽然软件功能不多,但是硬件功能BUG少,相对于寄存器编写已经很好了。

所以最终选择标准库

在有中断、速度要求的情况下推荐选择标准库或寄存器。

2、数据处理

UART中断:

接收上位机的消息,并将数据通过CAN发出去

进中断一定要清中断标志位!!!

CAN数据:

经测试,在中断中接受数据,并通过UART发送出去,此方法在数据量比较低的情况下可以,但数据量高的情况下就不行了!!!!!

所以采用在While循环中接受CAN消息,然后在通过串口发送出去。

      if(CAN_MessagePending(CAN, CAN_FIFO0) > 0)
      {
        LedSta = !LedSta;
        CAN_Receive(CAN, CAN_FIFO0, &RxMessage);

        res_data_cnt = 0;
        if(RxMessage.IDE)
            id = RxMessage.ExtId;
        else
            id = RxMessage.StdId;
        dlc = RxMessage.DLC;
        if(RxMessage.IDE)
            ide = 0;
        else
            ide = 0x1;
        
        if(RxMessage.RTR)
            rtr = 0;
        else
            rtr = 0x2;
        
        res_data_buf[res_data_cnt++] = ide | rtr;
        res_data_buf[res_data_cnt++] = id >> 24;
        res_data_buf[res_data_cnt++] = id >> 16;
        res_data_buf[res_data_cnt++] = id >> 8;
        res_data_buf[res_data_cnt++] = id;
        res_data_buf[res_data_cnt++] = dlc;
        memcpy(res_data_buf + res_data_cnt, RxMessage.Data, 8);
        res_data_cnt += 8;
        send_cmd_data(UART_DATA_CMD_RECV_CAN_DATA, res_data_buf, res_data_cnt);
      }

待开发功能:

固件更新:STM32F042这款芯片有个很好的功能就是可以在程序内选择启动模式,不像其他32设置Boot0、Boot1的电平。在程序内可以实现跳转。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容