找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12250|回复: 13
打印 上一主题 下一主题
收起左侧

基于树莓派的can总线MCP2515驱动源程序(波形很好)

  [复制链接]
跳转到指定楼层
楼主
工作项目用到了can总线,是在树莓派的板子上运行的。用的can芯片是mcp2515。效果还不错,波形很好。



单片机源程序如下:
  1. #define        CAN_10Kbps        0x31
  2. #define CAN_25Kbps        0x13
  3. #define CAN_50Kbps        0x09
  4. #define CAN_100Kbps        0x04
  5. #define CAN_125Kbps        0x03
  6. #define CAN_250Kbps        0x01
  7. #define        CAN_500Kbps        0x00

  8. #define SCK 14
  9. #define SI 12
  10. #define SO 13
  11. #define CS 10   //CE0       
  12. #define INTIN 3
  13. #define RST 4
  14. #define TXREQ_M 0b11110111
  15. #define CH 0

  16. #include "MCP2515.h"
  17. #include "bcm2835.h"
  18. #include <wiringPi.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <time.h>

  22. //#include <wiringPiSPI.h>

  23. //采用bcm2835spi

  24. void MCP2515_WriteByte(unsigned char addr,unsigned char dat)
  25. {
  26.         unsigned char buf = CAN_WRITE;
  27.         unsigned char spiDat[] = {CAN_WRITE,addr,dat};
  28.         digitalWrite(CS,LOW);                        //置MCP2515的CS为低电平
  29.         bcm2835_spi_transfern(spiDat,3);
  30.         digitalWrite(CS,HIGH);                                //置MCP2515的CS为高电平
  31.         }

  32. unsigned char MCP2515_ReadByte(unsigned char addr)
  33. {
  34.         unsigned char rByte = 0;
  35.         unsigned char spiDat[] = {CAN_READ,addr,0xff};
  36.         digitalWrite(CS,LOW);                                //置MCP2515的CS为低电平
  37.         bcm2835_spi_transfern(spiDat,3);
  38.         digitalWrite(CS,HIGH);                        //置MCP2515的CS为高电平
  39.                 rByte = spiDat[2];
  40.         return rByte;                                //返回读到的一个字节数据

  41. }

  42. void MCP2515_Reset(void)
  43. {
  44.         digitalWrite(RST,LOW);
  45.         delay(100);
  46.         digitalWrite(RST,HIGH);
  47.         delay(100);
  48. }

  49. //void IntHandle()
  50. //{
  51. //        char temp=0;
  52. //        //中断处理函数,MCU清除中断FLAG,重新使能INTE,并且输出RXB
  53. //        //digitalWrite(28,HIGH);
  54. //  printf("into the interrupt mode\nINT-IN is: %d\n",digitalRead(INTIN));
  55. ////        temp = MCP2515_ReadByte(CANINTF);
  56. //        //MCP2515_WriteByte(CANINTF,0x00);
  57. //  printf("into the interrupt mode\nINT-IN is: %d\n",digitalRead(INTIN));
  58. //        printf("RXB0SIDH  :  %02x\n",MCP2515_ReadByte(RXB0SIDH));
  59. //        printf("RXB0SIDL  :  %02x\n",MCP2515_ReadByte(RXB0SIDL));
  60. //        printf("RXB0D0  :  %02x\n",MCP2515_ReadByte(RXB0D0));
  61. //        printf("RXB0D1  :  %02x\n",MCP2515_ReadByte(RXB0D1));
  62. //        printf("RXB0D2  :  %02x\n",MCP2515_ReadByte(RXB0D2));
  63. //        printf("RXB0D3  :  %02x\n",MCP2515_ReadByte(RXB0D3));       
  64. //        printf("RXB0D4  :  %02x\n",MCP2515_ReadByte(RXB0D4));
  65. //        printf("RXB0D5  :  %02x\n",MCP2515_ReadByte(RXB0D5));       
  66. //        printf("RXB0D6  :  %02x\n",MCP2515_ReadByte(RXB0D6));
  67. //        printf("RXB0D7  :  %02x\n",MCP2515_ReadByte(RXB0D7));       
  68. //        printf("\n\n");
  69. //        exit(1);
  70. //}

  71. void MCP2515_Init(void)
  72. {
  73.         unsigned char temp=1;

  74.         MCP2515_Reset();        //发送复位指令软件复位MCP2515
  75.         printf("Reset OK \n");
  76. // delay(1);        //Delay_Nms(1);                //通过软件延时约nms(不准确)

  77.         //设置波特率为125Kbps
  78.         //set CNF1,SJW=00,长度为1TQ,BRP=49,TQ=[2*(BRP+1)]/Fsoc=2*50/8M=12.5us
  79.         MCP2515_WriteByte(CNF1,CAN_125Kbps);

  80.         //set CNF2,SAM=0,在采样点对总线进行一次采样,PHSEG1=(2+1)TQ=3TQ,PRSEG=(0+1)TQ=1TQ
  81.         MCP2515_WriteByte(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ);
  82.         //set CNF3,PHSEG2=(2+1)TQ=3TQ,同时当CANCTRL.CLKEN=1时设定CLKOUT引脚为时间输出使能位
  83.         MCP2515_WriteByte(CNF3,PHSEG2_3TQ);
  84.        

  85.         MCP2515_WriteByte(RXB0CTRL,0x20);//接收 过滤器信息
  86.         MCP2515_WriteByte(RXB0DLC,DLC_8);//设置接收数据的长度为8个字节
  87.         MCP2515_WriteByte(RXF0SIDH,0x12);//配置验收滤波寄存器n标准标识符高位
  88.         MCP2515_WriteByte(RXF0SIDL,0x11);//配置验收滤波寄存器n标准标识符低位
  89.         MCP2515_WriteByte(RXM0SIDH,0xFF);//配置验收屏蔽寄存器n标准标识符高位
  90.         MCP2515_WriteByte(RXM0SIDL,0xE0);//配置验收屏蔽寄存器n标准标识符低位
  91.        
  92. //        MCP2515_WriteByte(RXB0SIDH,0x00);//清空接收缓冲器0的标准标识符高位
  93. //        MCP2515_WriteByte(RXB0SIDL,0x00);//清空接收缓冲器0的标准标识符低位
  94.        
  95.         MCP2515_WriteByte(CANINTE,0x01);//配置CAN中断使能寄存器的接收缓冲器0满中断使能,其它位禁止中断
  96.         MCP2515_WriteByte(CANINTF,0x00);//清空CAN中断标志寄存器的所有位(必须由MCU清空)
  97.        
  98.         MCP2515_WriteByte(CANCTRL,REQOP_LOOPBACK|CLKOUT_ENABLED);//将MCP2515设置为环回模式,退出配置模式
  99.        
  100.         temp=MCP2515_ReadByte(CANSTAT);//读取CAN状态寄存器的值
  101.        
  102.         while(OPMODE_LOOPBACK!=(temp & 0xE0))//判断MCP2515是否已经进入环回模式
  103.         {
  104.           //MCP2515_WriteByte(CANCTRL,REQOP_LOOPBACK|CLKOUT_ENABLED);//再次将MCP2515设置为环回模式,退出配置模式
  105.                 temp=MCP2515_ReadByte(CANSTAT);
  106.                
  107.         }
  108.         printf("MCP2515 loopback mode OK\n");
  109. }


  110. void LOOPTest()
  111. {
  112.         printf("LoopTest begin\n");

  113.         MCP2515_WriteByte(TXB0DLC,DLC_8);//设置发送数据长度为8
  114.         MCP2515_WriteByte(TXB0SIDH,0x12);//发送缓冲器0标准标识符高位
  115.         MCP2515_WriteByte(TXB0SIDL,0x11);//发送缓冲器0标准标识符低位
  116.         MCP2515_WriteByte(TXB0CTRL,0x02);  //高优先级
  117.         MCP2515_WriteByte(TXB0D0,0x83);    //数据
  118.         MCP2515_WriteByte(TXB0D1,0x83);
  119.         MCP2515_WriteByte(TXB0D2,0x83);
  120.         MCP2515_WriteByte(TXB0D3,0x87);
  121.         MCP2515_WriteByte(TXB0D4,0x87);
  122.         MCP2515_WriteByte(TXB0D5,0x87);
  123.         MCP2515_WriteByte(TXB0D6,0x84);
  124.         MCP2515_WriteByte(TXB0D7,0x84);

  125.         printf("TXB0D0  :  %02x\n",MCP2515_ReadByte(TXB0D0));
  126.         printf("TXB0D1  :  %02x\n",MCP2515_ReadByte(TXB0D1));
  127.         printf("TXB0D2  :  %02x\n",MCP2515_ReadByte(TXB0D2));
  128.         printf("TXB0D3  :  %02x\n",MCP2515_ReadByte(TXB0D3));       
  129.         printf("TXB0D4  :  %02x\n",MCP2515_ReadByte(TXB0D4));
  130.         printf("TXB0D5  :  %02x\n",MCP2515_ReadByte(TXB0D5));       
  131.         printf("TXB0D6  :  %02x\n",MCP2515_ReadByte(TXB0D6));
  132.         printf("TXB0D7  :  %02x\n",MCP2515_ReadByte(TXB0D7));       
  133.        
  134.        
  135.         printf("RXB0SIDH  :  %02x\n",MCP2515_ReadByte(RXB0SIDH));
  136.         printf("RXB0SIDL  :  %02x\n",MCP2515_ReadByte(RXB0SIDL));
  137.         printf("RXB0D0  :  %02x\n",MCP2515_ReadByte(RXB0D0));
  138.         printf("RXB0D1  :  %02x\n",MCP2515_ReadByte(RXB0D1));
  139.         printf("RXB0D2  :  %02x\n",MCP2515_ReadByte(RXB0D2));
  140.         printf("RXB0D3  :  %02x\n",MCP2515_ReadByte(RXB0D3));       
  141.         printf("RXB0D4  :  %02x\n",MCP2515_ReadByte(RXB0D4));
  142.         printf("RXB0D5  :  %02x\n",MCP2515_ReadByte(RXB0D5));       
  143.         printf("RXB0D6  :  %02x\n",MCP2515_ReadByte(RXB0D6));
  144.         printf("RXB0D7  :  %02x\n",MCP2515_ReadByte(RXB0D7));       
  145.         printf("\n\n");


  146.         char temp = 0;
  147.        

  148.         temp = MCP2515_ReadByte(TXB0CTRL);

  149.         MCP2515_WriteByte(TXB0CTRL,(temp| (~TXREQ_M )));  //请求发送
  150.        
  151.         int cnt = 0;
  152.         while(MCP2515_ReadByte(TXB0CTRL)&(0b00001000) != 0x00)
  153.         {
  154.                 cnt++;
  155.                 if(cnt>=100000)
  156.                 {
  157.                         printf("trasmission failed\n");
  158.                         exit(1);
  159.                 }
  160.         }
  161.         delay(100);
  162.         printf("RXB0SIDH  :  %02x\n",MCP2515_ReadByte(RXB0SIDH));
  163.         printf("RXB0SIDL  :  %02x\n",MCP2515_ReadByte(RXB0SIDL));
  164.         printf("RXB0D0  :  %02x\n",MCP2515_ReadByte(RXB0D0));
  165.         printf("RXB0D1  :  %02x\n",MCP2515_ReadByte(RXB0D1));
  166.         printf("RXB0D2  :  %02x\n",MCP2515_ReadByte(RXB0D2));
  167.         printf("RXB0D3  :  %02x\n",MCP2515_ReadByte(RXB0D3));       
  168.         printf("RXB0D4  :  %02x\n",MCP2515_ReadByte(RXB0D4));
  169.         printf("RXB0D5  :  %02x\n",MCP2515_ReadByte(RXB0D5));       
  170.         printf("RXB0D6  :  %02x\n",MCP2515_ReadByte(RXB0D6));
  171.         printf("RXB0D7  :  %02x\n",MCP2515_ReadByte(RXB0D7));       
  172.         printf("\n\n");
  173.        
  174. }

  175. void bcm2835_SPISetup(void)
  176. {
  177.         if (!bcm2835_init())
  178.     {
  179.       printf("bcm2835_init failed. Are you running as root??\n");
  180.       exit(1);
  181.     }

  182.     if (!bcm2835_spi_begin())
  183.     {
  184.       printf("bcm2835_spi_begin failed. Are you running as root??\n");
  185.       exit(1);
  186.     }
  187.     bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);      // The default
  188.     bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);                   // The default
  189.     bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); // The default
  190.     bcm2835_spi_chipSelect(BCM2835_SPI_CS0);                      // The default
  191.     bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);      // the default
  192. ……………………

  193. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
MCP2515.rar (25.34 KB, 下载次数: 114)




评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:315814 发表于 2018-4-24 22:50 | 只看该作者
感谢楼主热心分享
回复

使用道具 举报

板凳
ID:329716 发表于 2018-5-14 16:40 | 只看该作者

感谢楼主热心分享!!!
回复

使用道具 举报

地板
ID:329716 发表于 2018-5-14 16:59 | 只看该作者
非常感谢楼主分享,我找了好多地方,都不是专门针对树莓派。自己写因为不熟悉又太花时间了
回复

使用道具 举报

5#
ID:380699 发表于 2018-7-30 13:00 | 只看该作者
挺好的 参考参考
回复

使用道具 举报

6#
ID:385727 发表于 2018-8-13 11:43 | 只看该作者
谢谢分享,
回复

使用道具 举报

7#
ID:342519 发表于 2018-9-17 16:30 | 只看该作者
楼主好,很感谢你的分享。但是我想问一下那个printf()串口打印是MCP2515和CAN收发器之间的CAN串口,还是单纯的MCU的串口。谢谢
回复

使用道具 举报

8#
ID:342519 发表于 2018-9-17 16:31 | 只看该作者
请回复一下,初学者2677957815
回复

使用道具 举报

9#
ID:413508 发表于 2018-12-11 16:43 | 只看该作者
谢谢分享
回复

使用道具 举报

10#
ID:446581 发表于 2019-1-14 13:12 | 只看该作者
謝謝分享, 學習一下
回复

使用道具 举报

11#
ID:470794 发表于 2019-1-20 10:38 | 只看该作者
多谢楼主分享
回复

使用道具 举报

12#
ID:434390 发表于 2019-5-7 14:15 | 只看该作者
正好需要扩一路CAN,感谢分享
回复

使用道具 举报

13#
ID:306454 发表于 2019-11-18 13:57 | 只看该作者

感谢楼主热心分享
回复

使用道具 举报

14#
ID:555216 发表于 2020-5-19 20:39 | 只看该作者
非常感谢,热心分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表