低成本实现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的电平。在程序内可以实现跳转。