树莓派3B+如何连接CAN总线模块
1. 背景说明
本文章介绍如何使用树莓派3代B+板连接CAN总线模块。笔者使用的CAN总线模块是从天猫购买,如下图:
上图中:
- A为SPI排针
- B为MCP2515模块,作为CAN控制器
- C为TJA1050模块,作为CAN收发器
根据模块的DataSheet,该总线模块通讯速率最高为1Mb/s。
2. 连接树莓派板与CAN总线模块
树莓派与CAN总线模块的连接是使用SPI。SPI一种单主机多从机的串行通信总线,其主要使用4条线:
- SCLK(Serial Clock):串列时脉,由主机发出
- MOSI(Master Output, Slave Input):主机输出从机输入信号(数据由主机发出)
- MISO(Master Input, Slave Output):主机输入从机输出信号(数据由从机发出)
- SS(Slave Select):片选信号,由主机发出,一般是低电位有效
我们可以看到前面CAN总线模块的SPI排针共有7个,从上到下分别为:
- INT:用于MCP2515模块的中断
- SCK: 用于总线时钟
- SI:用于MCP2515 输入
- SO:用于MCP2515 输出
- CS: chip select,用于从机选择
- GND: 接地线
- VCC:电源线
因此,要连接CAN总线模块与树莓派,需要将CAN总线模块的SPI排针连接到树莓派相应的SPI接口上。
树莓派官网关于各种单板的电路示意图可参考 Raspberry Schematics and Mechanical Drawings,以笔者使用的树莓派3B+板,其电路图见 Raspberry Pi 3 Model B+ Schematics, Revision 1.0。我们可以看到其GPIO布局如下:
其中与SPI相关的有:
- GPIO7、GPIO8为用于片选信号
- GPIO11用于时钟信号
- 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
如果有tmux
或screen
等分屏软件,可以先分两屏出来,一屏进行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+板,可以根据下面的参考资料进行相应的调整修改。