MCP2515芯片的使用
树莓派作为大众开源硬件,一些高级功能是需要扩展的,刚刚用到了MCP2515扩展CAN总线,现在总结如下:
前提:使用内核自带的MCP2515驱动
1、打开SPI总线
在raspi-config中使能SPI总线
2、修改内核启动文件
dtparam=spi=on
dtoverlay=mcp2515-can0,oscillator=8000000,interrupt=25,spimaxfrequency=1000000
然后重启系统
3、例程是基于wiringPi
1、初始化代码如下
int mcp2515_init()
{
memset(&frame, 0, sizeof(struct can_frame));
system("sudo ifconfig can0 down");
delay(10);
system("sudo ip link set can0 type can bitrate 250000");
system("sudo ifconfig can0 up");
//1.Create socket
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (s < 0) {
perror("socket PF_CAN failed");
return 1;
}
//2.Specify can0 device
strcpy(ifr.ifr_name, "can0");
ret = ioctl(s, SIOCGIFINDEX, &ifr);
if (ret < 0) {
perror("ioctl failed");
return 1;
}
//3.Bind the socket to can0
addr.can_family = PF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
ret = bind(s, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
perror("bind failed");
return 1;
}
//4.Define receive rules
struct can_filter rfilter[1];
rfilter[0].can_id = 0x18feca33;
rfilter[0].can_mask = CAN_SFF_MASK;
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
return 0;
}
其中比较重要的几点就是波特率的设置,接收滤波器的设置
2、接收滤波器设置
struct can_filter rfilter[1];
rfilter[0].can_id = 0x18feca33;
rfilter[0].can_mask = CAN_SFF_MASK;
经此设置后,MCP2515仅接受扩展ID为0x18feca33的报文
3、发送设置
发送部分的代码摘录如下:
int mcp2515_write(canframe dataTemp)
{
canframe frame;
frame.can_id = CAN_EFF_FLAG|dataTemp.can_id;
frame.can_dlc = 8;
for (int i = 0; i < 8; i++)
{
frame.data[i]=dataTemp.data[i];
}
nbytes = write(s, &frame, sizeof(frame));
if(nbytes != sizeof(frame)) {
return 0;
}
return 1;
}
CAN_EFF_FLAG表示当前发送扩展帧,无此项时为标准帧
4、接收部分
canframe mcp2515_read()
{
canframe dataTemp;
for (int i = 0; i < 100; i++)
{
nbytes = read(s, &frame, sizeof(frame));
if(nbytes > 0) {
dataTemp.can_id=frame.can_id&0x1fffffff;
for (int i = 0; i < 8; i++)
{
dataTemp.data[i]=frame.data[i];
}
return dataTemp;
}
}
}
接收部分最高位为1时,表示接收的为扩展帧,程序使用的是在线程中查询接收。