树莓派3B+如何连接CAN总线模块

1. 背景说明

本文章介绍如何使用树莓派3代B+板连接CAN总线模块。笔者使用的CAN总线模块是从天猫购买,如下图:

上图中:

  • A为SPI排针
  • B为MCP2515模块,作为CAN控制器
  • C为TJA1050模块,作为CAN收发器

根据模块的DataSheet,该总线模块通讯速率最高为1Mb/s。

2. 连接树莓派板与CAN总线模块

树莓派与CAN总线模块的连接是使用SPI。SPI一种单主机多从机的串行通信总线,其主要使用4条线:

  1. SCLK(Serial Clock):串列时脉,由主机发出
  2. MOSI(Master Output, Slave Input):主机输出从机输入信号(数据由主机发出)
  3. MISO(Master Input, Slave Output):主机输入从机输出信号(数据由从机发出)
  4. SS(Slave Select):片选信号,由主机发出,一般是低电位有效

我们可以看到前面CAN总线模块的SPI排针共有7个,从上到下分别为:

  1. INT:用于MCP2515模块的中断
  2. SCK: 用于总线时钟
  3. SI:用于MCP2515 输入
  4. SO:用于MCP2515 输出
  5. CS: chip select,用于从机选择
  6. GND: 接地线
  7. VCC:电源线

因此,要连接CAN总线模块与树莓派,需要将CAN总线模块的SPI排针连接到树莓派相应的SPI接口上。

树莓派官网关于各种单板的电路示意图可参考 Raspberry Schematics and Mechanical Drawings,以笔者使用的树莓派3B+板,其电路图见 Raspberry Pi 3 Model B+ Schematics, Revision 1.0。我们可以看到其GPIO布局如下:

其中与SPI相关的有:

  1. GPIO7、GPIO8为用于片选信号
  2. GPIO11用于时钟信号
  3. GPIO9、GPIO10 分别用于主机的输入输出(即从机的输出输入)

但此处需要注意的是,Raspberry pi 3B+是有两个SPI控制器的,GPIO布局图上只显示了其中一个,另一个SPI模块可见Raspberry pi SPI1 pin/gpio mappings

为了连接CAN总线模块与树莓派,笔者使用的连接方案如下:

GPIO5 --> INT
GPIO11 (SPI_SCLK) --> SCK
GPIO10 (SPI_MOSI) --> SI
GPIO9 (SPI_MISO) --> SO
GPIO8 (SPI_CE0_N) --> CS
PIN14 --> GND
PIN2 --> VCC

上面连线中,GPIO5作为中断使用,主要用于MCP2515模块,也可选择其它闲置的GPIO。

3. 使能树莓派SPI

树莓派上SPI是默认不使能的,如下:

SPI的使能比较简单,直接修改/boot/config.txt,在文件中增加下面代码,然后重启即可。

dtparam=spi=on

重启后,可以发现SPI已经使能,如下:

上面的配置会将两个SPI模块全部使能,如果想单独使能其中一个,也可以参考Raspberry spi software进行配置。

4. 加载MCP2515 CAN驱动

树莓派OS默认是有MCP2515 CAN驱动的,只是没有加载而已,要加载MCP2515 CAN驱动,可以修改/boot/config.txt文件,增加下面一行:

dt_overlay=mcp2515-can0,interrupt=5

其中mcp2515-can0指配置使用SPI0控制器的片选0的MCP2515模块,如下:

Name:   mcp2515-can0
Info:   Configures the MCP2515 CAN controller on spi0.0
Load:   dtoverlay=mcp2515-can0,<param>=<val>
Params: oscillator              Clock frequency for the CAN controller (Hz)
            spimaxfrequency         Maximum SPI frequence (Hz)
            interrupt               GPIO for interrupt signal

关于该配置,可以参考文件/boot/overlays/README的说明。当然,也可以配置mcp2515-can1等,具体配置需要与连线匹配。

修改完config.txt文件后重启系统,可以通过查询dmesg看到驱动已加载:

eric@yangpaopao:~ $ dmesg | grep mcp
[   13.455379] mcp251x spi0.0 can0: MCP2515 successfully initialized.

5. CAN环回测试

由于只连接了CAN总线模块,因此如果想测试CAN功能,需要配置CAN环回,配置方式如下:

sudo ip link set can0 up type can bitrate 100000 loopback on

命令中:

  • can0为刚刚配置的can总线模块设备。如果找不到can0,可以检查/sys/class/net目录下是否有can设备并修改为相应的名称。
  • 100000为配置的比特率,需要注意的是受硬件限制,速率最高为1Mb/s

配置完成后,可以使用ifconfig can0查询到can0的网络配置信息:

eric@yangpaopao:~ $ ifconfig can0
can0: flags=193<UP,RUNNING,NOARP>  mtu 16
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 10  (UNSPEC)
        RX packets 0  bytes 0
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

要测试CAN功能,需要安装can-utils,命令如下:

sudo apt-get install can-utils

如果有tmuxscreen等分屏软件,可以先分两屏出来,一屏进行CAN的输入,一屏进行CAN的输出。如果没有分屏软件,可以使用以下命令将can输出程序放到后台运行:

candump can0 &

上面的命令用于接收CAN的环回数据。

然后使用cansend工具进行输出数据到CAN模块,如下:

cansend can0 123#AABBCCDDEEFF

上面的命令通过can0模块将数据AABBCCDDEEFF发送给ID为123的设备。命令敲完之后,可以看到终端收到了环回数据,如下:

eric@yangpaopao:~ $ candump can0 &
[1] 1641
eric@yangpaopao:~ $ cansend can0 123#AABBCCDDEEFF
eric@yangpaopao:~ $   can0  123   [6]  AA BB CC DD EE FF
  can0  123   [6]  AA BB CC DD EE FF

以上即为使用树莓派3B+板连接CAN总线模块的整体过程,如果使用的模块不是mcp2515或使用的不是树莓派3b+板,可以根据下面的参考资料进行相应的调整修改。

6. 参考资料

  1. MCP2515 Datasheet
  2. TJA1050 DataSheet
  3. wikipedia: SPI (Serial Peripheral Interface)
  4. Raspberry Schematics and Mechanical Drawings
  5. Raspberry SPI
  6. 在树莓派上使用基于MCP2515的CAN总线模块
  7. 树莓派CAN通讯教程

留言

您的邮箱地址不会被公开。 必填项已用 * 标注