利用MCP2515芯片在树莓派上使用CAN BUS协议

在树莓派上使用CAN_BUS(即CAN总线技术)来控制小物件对我来说很外行,概念也不深,只能按照小物件的说明来使用,但是使用之前需要进行与树莓派的连接,折腾了好多,这里简单做个梳理,但不过多介绍….因为自己对CAN协议也是一窍不通,囧~

我之前的完成过程基本依靠Google,贴上我参考的国外教程:

  1. [quick-guide] CAN bus on raspberry pi with MCP2515
  2. CAN-Bus with Raspberry Pi: HowTo/Quickstart MCP2515 Kernel 4.4.x+
  3. https://harrisonsand.com/can-on-the-raspberry-pi/

1. 硬件相关问题

关于MCP2515 SPI转CAN的芯片,可能有多个“款式”的存在(有些教程里的跟我的芯片不一样),但是必要的针脚的插法都是一致的。

1
2
3
4
5
6
7
8
RPi Pin    RPi Label     CAN Module
02---------5V------------VCC
06---------GND-----------GND
19---------GPIO10--------MOSI (SI)
21---------GPIO9---------MISO (SO)
22---------GPIO25--------INT
23---------GPIO11--------SCK
24---------GPIO8---------CS

其他没什么的说的,在肯定自己接线没错误之后,我们需要怀疑芯片是不是坏的,我试的时候前面两个都是坏的,导致挂不上去

2. 配置树莓派

编辑/boot/config.txt并添加以下行,将振荡器参数设置为模块上存在的振荡器参数。大多数模块使用16MHz振荡器作为时钟,但也有使用8MHz(即oscillator=8000000)。你可以通过查看芯片来确定频率。

1
2
3
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=25
dtoverlay=spi-bcm2835-overlay

通过**uname -a**查看树莓派内核,如果内核为4.4.x往上(树莓派4B基本都是这个版本往上),则需要将最后一行配置修改:

1
2
3
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=25
dtoverlay=spi1-1cs

3. 挂载CAN设备

1
2
3
sudo apt-get update
sudo apt-get install can-utils
sudo reboot

等机器起来之后,我们可以先查看连接是否准确,有没有这个MCP2515设备,有了我们才能继续挂载。

1
2
3
4
pi@piv2:~ $ ls /sys/bus/spi/devices/spi0.0
driver modalias net of_node subsystem uevent
pi@piv2:~ $ ls /sys/bus/spi/devices/spi0.0/net
can0

如果连接不准确基本上看不到上面的net文件夹,也就没有can0这个设备了

之后,设置你想要的波特率挂载,我这里用的是125000(即你想要驱动的电机的波特率),**sudo ip link set can0 up type can bitrate 125000,挂载成功后,就能在ifconfig**中看到:

1
2
3
4
5
6
7
8
9
10
11
12
13
pi@piv2:~ $ sudo ifconfig
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
etho xxxx
....
....
wlan0 xxxx
....
....

每当机器重启之后,这个挂载就会失效,需重新挂载。可以直接做成服务或者放在rc.local中,开机自动启动就行

4. 发送CAN数据

Usage: cansend <device> <can_frame>

1
cansend can0 127#DEADBEEF

具体的can_frame格式也不用担心,当你格式数据输的不准确时,命令会自动提示所需的格式。
同时可以再开个终端查看收到的数据:

1
candump can0

只有当线路完全接好形成回路时,才能用上面这个命令自发自收数据,当收到数据时,代表通信成功

5. 使用Python第三方库向CAN发送数据

当有需求要将功能写入Python脚本中时,可以使用**python-can**模块,具体的用法这里不多讲,看官方手册即可

6.尾声

对CAN BUS知之甚少,只能依葫芦画瓢,一步一步慢慢走验证结果,当觉得自己的操作都正确却没有得到正确结果时,怀疑一下硬件本身是否有问题!