树莓派CAN通讯教程 - MCP2515
1. 楔
在上篇文章树莓派GPIO和PWM控制教程中,笔者详细介绍了如何使用树莓进行普通IO控制模拟,以及PWM 波形发送等操作,同时还提到了汽车电子常见的CAN 通讯也能够使用树莓派完成,本文针对此进行详细说明。
使用硬件为树莓派3b+, MCP2515 spiCAN模块 ,总成本控制在300 元以内。使用树莓派4b也可以,不过近期的4b价格离谱,而且仅仅can和io的测试,3b+性能完全够用。
操作系统使用ubuntu server ,如使用Raspberry Pi OS 也可以,本教程也可适用。需要注意的是,不能魔法上网的同学需要首先进行操作系统换源,以及python3 的换源。而其中ubuntu server arm 的系统不能够按照常用的清华源教程替换,需要使用后缀为-ports的源,笔者使用的源如下:
-
/etc/apt/sources.list
# 默认注释了源码仓库,如有需要可自行取消注释 deb https://mirrors.ustc.edu.cn/ubuntu-ports/ focal main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ focal main main restricted universe multiverse deb https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-updates main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-updates main restricted universe multiverse deb https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-backports main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-backports main restricted universe multiverse deb https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-security main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ focal-security main restricted universe multiverse
2. 硬件连接和环境准备
连接MCP2515和树莓派spi接口,并在操作系统中开启spi,整个的运行原理就是让MCP2515的CAN 通讯作为网络通讯接口,挂接到socketCAN 上,使用系统驱动spi,无需手工编写spi驱动以及can wrapper部分。针对socketCAN,网上有很多优秀的开源工具可以使用,笔者这里使用的是cantools ,可以使用dbc进行报文格式解析。
2.1. 硬件连接
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.2. 环境准备
-
安装socket can工具以及cantools工具
sudo apt install can-utils pip3 install cantools
-
使能树莓派SPI并加载MCP2515内核驱动
针对Ubuntu server 操作系统,在
/boot/firmware/usercfg.txt
文件后添加如下内容,若操作系统为Raspberry Pi OS,则在/boot/config.txt
文件后添加如下内容:dtparam=spi=on dtoverlay=mcp2515-can0,oscillator=16000000,interrupt=25 dtoverlay=spi1-1cs
-
重启
sudo reboot -h now
2.3. 检测MCP2515是否被正确挂载
输入sudo ifconfig -a
指令可以看到已经挂载了网络通讯卡CAN0,如没有ifconfig,则使用sudo apt install net-tools
进行安装
ubuntu@ubuntu:~$ sudo ifconfig -a
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 9343435 bytes 74747480 (74.7 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 64 (64.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
ether b8:27:eb:c2:61:84 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
输入 sudo ip -s -d link show can0
查看can0 通讯是否进入ready状态。
ubuntu@ubuntu:~$ sudo ip -s -d link show can0
3: can0: <NOARP,ECHO> mtu 16 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 10
link/can promiscuity 0 minmtu 0 maxmtu 0
can state STOPPED restart-ms 0
bitrate 1000000 sample-point 0.750
tq 125 prop-seg 2 phase-seg1 3 phase-seg2 2 sjw 1
mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1
clock 8000000
re-started bus-errors arbit-lost error-warn error-pass bus-off
0 0 0 0 0 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
RX: bytes packets errors dropped overrun mcast
74955120 9369390 0 0 0 0
TX: bytes packets errors dropped carrier collsns
64 8 0 0 0 0
3. CAN 通讯设置及程序开发
如上步骤如果已经完成,则可进行相关CAN 通讯开发,使用python和c都可以,因为系统支持命令行进行报文发送读取及设定,所以python可以简单的调用系统命令。c的话不建议调用系统命令,而是使用socket接口进行编程。
需注意,由于硬件限制,此方案can通讯波特率最高仅支持500Kbps
3.1. 系统命令
-
关闭can0
sudo ip link set can0 down
-
设置波特率 500K ,需注意bitrate 需要除2才是常规的通讯波特率
sudo ip link set can0 type can bitrate 1000000
-
开启can0
sudo ip link set can0 up
-
查看状态
sudo ip -s -d link show can0
-
接收报文命令
candump any,0:0,#FFFFFFFF
-
联合 cantools 使用dbc文件进行报文解码
candump can0 | cantools decode temp.dbc
-
发送报文命令
cansend can0 123#1122334455667788
-
设置回环 波特率 250K ,用于测试can通路,在没有其它硬件连接测试的情况下,可以设定成回环,自发自收
sudo ip link set can0 type can bitrate 500000 loopback on
3.2. c语言调用socket接口进行开发
/**
*-----------------------------------------------------------------------------
* @file can_control.c
* @brief
* @author Tomato
* @version 0.1
* @date 2021-07-22
* @note [change history]
*
* @copyright NAAAAA
*-----------------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#define<