美文网首页
2018-10-28

2018-10-28

作者: 傻乎乎的家伙 | 来源:发表于2018-10-28 10:52 被阅读0次

    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时,表示接收的为扩展帧,程序使用的是在线程中查询接收。

    相关文章

      网友评论

          本文标题:2018-10-28

          本文链接:https://www.haomeiwen.com/subject/aelptqtx.html