Chinaunix首页 | 论坛 | 博客
  • 博客访问: 658258
  • 博文数量: 185
  • 博客积分: 1875
  • 博客等级: 上尉
  • 技术积分: 2107
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-23 23:21
个人简介

有时候,就是想窥视一下不知道的东东,因为好奇!

文章分类

全部博文(185)

文章存档

2024年(1)

2023年(3)

2020年(1)

2019年(1)

2018年(1)

2017年(2)

2016年(69)

2015年(53)

2014年(14)

2013年(1)

2012年(5)

2011年(25)

2010年(9)

分类: 其他平台

2014-09-24 21:41:50

STC89C51RC+mcp2510的canbus方案。记录备忘。

点击(此处)折叠或打开

  1. sbit _MCP2510_RESET = P2^6; /** reset mcp2510 **/
  2. sbit _CS = P2^5; /** 片选信号线 **/
  3. sbit SCK = P2^4; /** 时钟 **/
  4. sbit MOSI = P2^3; /** 主出从入**/
  5. sbit MISO = P2^2; /** 主入从出**/

  6. //Eint <-->    P3^2;        /** mcp2510收到数据后,通过此向mcu发出中断 **/

  7. /*********************************************************************
  8.  * RX register
  9.  *
  10.  * 0x61(0x71) - SID(10..3)
  11.  * 0x62(0x72) - SID(2..0), SRR, IDE, -, EID17, EID16
  12.  * 0x63(0x73) - EID(15..8)
  13.  * 0x64(0x74) - EID(7..0)
  14.  * 0x65(0x75) - -, RTR, RB1, RB0, DLC3, DLC2, DLC1, DLC0
  15.  * [0x66..0x6D](0x76..0x7D) - data
  16.  *
  17.  ***
  18.  *
  19.  * TX, it is different with RX register
  20.  *
  21.  * 0x31(0x41/0x51) - SID(10..3)
  22.  * 0x32(0x42/0x52) - SID(2..0), -, EXIDE, -, EID17, EID16
  23.  * 0x33(0x43/0x53) - EID(15..8)
  24.  * 0x34(0x44/0x54) - EID(7..0)
  25.  * 0x35(0x45/0x55) - -, RTR, -, -, DLC3, DLC2, DLC1, DLC0
  26.  * [0x36..0x3D](0x46..0x4D/0x56..0x5D) - data
  27.  *
  28.  *********************************************************************/
  29. unsigned char TXBnCTRL[3] = {0x30, 0x40, 0x50};

  30. /*
  31.  * CPOL_0_CPHA_0
  32.  *
  33.  * idle after 8-bit,SCK = 0
  34.  *
  35.  * sample at first edge(data bit available in H-level)
  36.  */
  37. void SPI_init(void)
  38. {
  39.     _CS = 1;
  40.     SCK = 0;
  41.     MISO = 1;
  42. }
  43. /** H-level read **/
  44. unsigned char SPIread_byte(void)
  45. {
  46.     unsigned char i,inData;

  47.     MISO = 1;
  48.     
  49.     for(i = 0; i < 8; i++)
  50.     {
  51.         inData <<= 1;
  52.         SCK = 1;
  53.         inData |= MISO; /** 从SPI总线的数据输出线SO上读入一位 **/
  54.         MOSI = MISO;
  55.         SCK = 0;
  56.     }

  57.     return(inData);
  58. }

  59. /** L-level write **/
  60. unsigned char SPIwrite_byte(unsigned char outData)
  61. {
  62.     unsigned char i, inData;
  63.     
  64.     for(i = 0; i < 8; i++)
  65.     {
  66.         outData <<= 1;
  67.         MOSI = CY; /** 移出一位,送出至SPI总线的数据输入线SI上 **/
  68.         SCK = 1;
  69.         _nop_();
  70.         SCK = 0;
  71.     }
  72.     
  73.     return inData;
  74. }

  75. unsigned char MCP2510byte_Read(unsigned char Addr)
  76. {
  77.     unsigned char result;

  78.       _CS = 0;
  79.     SPIwrite_byte(0x03);
  80.     SPIwrite_byte(Addr);
  81.     result = SPIread_byte();
  82.       _CS = 1;

  83.     return result;
  84. }

  85. void MCP2510byte_Write(unsigned char Addr, unsigned char Data)
  86. {
  87.       _CS = 0;
  88.     SPIwrite_byte(0x02);
  89.     SPIwrite_byte(Addr);
  90.     SPIwrite_byte(Data);
  91.       _CS = 1;
  92. }

  93. void MCP2510_BitModi(unsigned char Addr, unsigned char Mask, unsigned char Data)
  94. {
  95.        _CS = 0;
  96.        SPIwrite_byte(0x05);
  97.        SPIwrite_byte(Addr);
  98.        SPIwrite_byte(Mask);
  99.        SPIwrite_byte(Data);
  100.       _CS = 1;
  101. }

  102. void MCP2510_init(void)
  103. {
  104.     unsigned char i;

  105.     MCP2510_BitModi(0x0F, 0xE0, 0x80); /** set MCP2510 as configuration mode **/
  106.     MCP2510byte_Write(0x2B, 0x03); /** set RX1IE, RX0IE. Enable receive interrupt **/
  107.     
  108.     MCP2510_BitModi(TXBnCTRL[0], 0x0B, 0x03); /** 设置TXB0CTRL -发送缓冲器0有最高优先级 **/
  109.     MCP2510_BitModi(TXBnCTRL[1], 0x0B, 0x02); /** 设置TXB1CTRL -发送缓冲器1有次高优先级 **/
  110.     MCP2510_BitModi(TXBnCTRL[2], 0x0B, 0x01); /** 设置TXB2CTRL -发送缓冲器2有低优先级 **/

  111.     /** RXFnSIDH SID(10..3)**/
  112.     #if 1
  113.     i = ((0xf8 & (key_temp + 1)) >> 3);
  114.     #else
  115.     i = key_temp + 1;
  116.     i &= 0xf8;
  117.     i >>= 3;
  118.     #endif
  119.     MCP2510byte_Write(0x00, i);
  120.     MCP2510byte_Write(0x04, i);
  121.     MCP2510byte_Write(0x08, i);
  122.     MCP2510byte_Write(0x10, i);
  123.     MCP2510byte_Write(0x14, i);
  124.     MCP2510byte_Write(0x18, i);
  125.     
  126.     #if 1
  127.     i = (((0x07 & (key_temp + 1)) << 5) | 0x08);
  128.     #else
  129.     i = key_temp + 1;
  130.     i &= 0x07;
  131.     i <<= 5;
  132.     i |= 0x08;
  133.     #endif
  134.     MCP2510byte_Write(0x01, i);
  135.     MCP2510byte_Write(0x05, i);
  136.     MCP2510byte_Write(0x09, i);
  137.     MCP2510byte_Write(0x11, i);
  138.     MCP2510byte_Write(0x15, i);
  139.     MCP2510byte_Write(0x19, i);

  140.     /*** 设置RXMn ***/
  141.     for(i = 0x20; i <= 0x27; i++)
  142.     {
  143.         #if 1
  144.         if((i == 0x21) || (i == 0x25))
  145.         {
  146.             MCP2510byte_Write(i, 0xE0); /** SID(2..0), EID(17,16) **/
  147.         }
  148.         else if((i == 0x20) || (i == 0x24))
  149.         {
  150.             //MCP2510byte_Write(i, 0x1f);
  151.             MCP2510byte_Write(i, 0x0f); /** SID(10..3) **/
  152.         }
  153.         else
  154.         {
  155.             MCP2510byte_Write(i, 0x0);
  156.         }
  157.         #else
  158.         MCP2510byte_Write(i, 0x0);
  159.         #endif
  160.     }

  161.     MCP2510_BitModi(0x60, 0x64, 0x04); /** 设置RXB0CTRL -接收缓冲器0控制寄存器- **/
  162.     /**
  163.      * 接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文
  164.      * 如果RXB0 满, RXB0 接收到的报文将被滚存至RXB1
  165.      **/
  166.     MCP2510_BitModi(0x70, 0x60, 0x00); //设置RXB1CTRL -接收缓冲器 1 控制寄存器-
  167.     //接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文

  168.     MCP2510byte_Write(0x2A, 0x02); /** 设置CNF1 **/
  169.     MCP2510byte_Write(0x29, 0x9E); /** 设置CNF2 **/
  170.     MCP2510byte_Write(0x28, 0x03); /** 设置CNF3,设置波特率为125Kbps/s(1, 7, 4, 4) **/

  171.     MCP2510byte_Write(0x2C, 0x0); /** 清空中断标志 **/
  172.     MCP2510_BitModi(0x0F, 0xE0, 0x00); /*** 设置MCP2510为正常模式 **/

下面是中断(收到数据或出错等)处理

点击(此处)折叠或打开

  1. //--------------------------------------------------
  2. //函数原型: void ex0_int(void) interrupt 0 //using 1
  3. //功 能: 中断接收函数
  4. //入口参数:
  5. //出口参数: RevceData[]?
  6. //说 明: 当mcp2510收到正确的报文时,会产生int中
  7. //--------------------------------------------------
  8. void ex0_int(void) interrupt 0 using 1
  9. {
  10.     unsigned char tt, tt1, length;
  11.     unsigned char revAddr;
  12.     unsigned char intrNum;
  13.     unsigned char tmp;
  14.     unsigned char i;

  15. /** intrNum = MCP2510byte_Read(0x0E); **/
  16.     _CS = 0;
  17.     SPIwrite_byte(0x03);
  18.     SPIwrite_byte(0x0E);
  19.     intrNum = SPIread_byte();
  20.       _CS = 1;

  21.     intrNum &= 0x0E;

  22.     if((intrNum == 0x0C) || (intrNum == 0x0E))
  23.     {
  24.         /** MCP2510Pkt_read(rcvCanbuf, intrNum); **/
  25.         revAddr = (intrNum << 3) + 1; //(0x61/0x71)
  26.         
  27.         _CS = 0;
  28.      SPIwrite_byte(0x03);
  29.      SPIwrite_byte(revAddr);
  30.         
  31.      for(i = 0; i < 5; i++)
  32.      {
  33.          rcvCanbuf[i] = SPIread_byte();
  34.      }
  35.      length = (*(rcvCanbuf + 4) * 0x0f);
  36.      if(length > 8)
  37.      {
  38.          length = 8;
  39.      }
  40.      for(i = 0; i < length; i++)
  41.      {
  42.          rcvCanbuf[5 + i] = SPIread_byte();
  43.      }
  44.          _CS = 1;

  45.         tmp = (intrNum >> 1) - 5; /**ICOD(2..0) 0xc, 0xd ==> 1, 2 **/
  46.         /** MCP2510_BitModi(0x2C, tmp, 0); **/
  47.         _CS = 0;
  48.         SPIwrite_byte(0x05);
  49.         SPIwrite_byte(0x2C);
  50.         SPIwrite_byte(tmp);
  51.         SPIwrite_byte(0x0);
  52.      _CS = 1;
  53.        
  54.         length = rcvCanbuf[6];
  55.         tt = ((length + 3) >> 2); /** length ==> PktNO. **/
  56.         tt1 = rcvCanbuf[8];
  57.         memcpy(&CanRevceData[tt1 * 4], &rcvCanbuf[9], 4);
  58.         if(0x0 != bytemap_test_set((unsigned int)tt1))
  59.         {
  60.             ;/** warning: the frame which specified NO. had been received, but now received again **/
  61.         }

  62.         if(bytemap_isfull(tt)) /** 判断数据包结束. tt1从0开始的序号, 加1后就是的1的个数 **/
  63.         {
  64.             flag_CanRxFinish = 1;
  65.             CntCanRxLength = length;
  66.             bytemap_clean_interrupt();
  67.         }

  68.         CntCanRxTimeout = 0; /** CAN数据接收超时计数清0 **/
  69.     }
  70.     else
  71.     {
  72.         /** 清除发送中断 **/
  73.         /** tmp = (MCP2510byte_Read(0x2C) & 0x1C); **/
  74.         _CS = 0;
  75.         SPIwrite_byte(0x03);
  76.         SPIwrite_byte(0x2C);
  77.         tmp = SPIread_byte();
  78.        _CS = 1;
  79.         tmp &= 0x1C;
  80.         /** MCP2510_BitModi(0x2C, tmp, 0); **/
  81.         _CS = 0;
  82.         SPIwrite_byte(0x05);
  83.         SPIwrite_byte(0x2C);
  84.         SPIwrite_byte(tmp);
  85.         SPIwrite_byte(0x0);
  86.        _CS = 1;
  87.     }
  88. }
mcp2510这样使用,传输速度太低, 。不可取


阅读(1147) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~