初学者关于MCP2510不能通信问题 点击:656 | 回复:3



Succeed

    
  • 精华:0帖
  • 求助:1帖
  • 帖子:1帖 | 2回
  • 年度积分:0
  • 历史总积分:3
  • 注册:2016年5月20日
发表于:2016-05-20 12:08:37
楼主

论坛里不知道有没有用过MCP2510的CANBUS的通信IC,本人初学者。

对于MCP2510和CAN都不太了解,自己用STC15F2K60S2的IC写了一个软件测试MCP2510通信的软件,用CAN分析仪模拟数据接收发送。

用端口模拟的SPI通信,(规划时没有规划到SPI通信模块)。

环回模式下数据是可以被发送(TXB0CTRL寄存器bit3=0;TXB0D0-7全部为0)但是在正常模式下,连接CAN分析仪后,TXCAN引脚并没有数据发送出去并出现总线错误。

使能发送后TXCAN引脚一直输出11ms高0.26ms低的脉冲。程序代码编写是参考网上的MCP2510例程。不知道现在那部份有问题。


用CAN分析仪发送数据,RXCAN引脚是有数据输出的,所以电路上应该没问题 ,却不能接收数据。


有哪位朋友有空帮忙分析分析


主控晶体:24M

MCP2510的晶体:8M

CAN的波特率:125K


配置的源代码

//***************************************************************************

//初始化MCP2510

//***************************************************************************

void Mcp2510Initial(void)

{

    u8 n = 0;


    P0M0 = P0M0|0x00;

    P0M1 = P0M1|0x04;              ;SPI_MISO设为输入


    MCP2510_RESET = 1;                                                     //端口复位


    SPI_CS = 1;

    SPI_SCK = 0;

    SPI_MOSI = 0;

    SPI_MISO = 0;

    delayx1ms(500); //初始化SPI端口状态


    Mcp2510RESET();                                      //复位命令


    Mcp2510Write(CANCTRL,0x80); //设定为配置模式

    n = Mcp2510Read(CANSTAT);   //读取CANSTAT

    UARTTx(n);


    Mcp2510Write(CNF1,0x03);                            //晶振8MHZ,CAN总     线速度125KHZ 

    n = Mcp2510Read(CNF1);         //读取CNF1

    UARTTx(n);

    Mcp2510Write(CNF2,0x90);//相位段2位时间长度有CNF3中的PHSEG22:PHSEG20确定 

                            //(PHSEG1 + 1) x TQ = (2+1)*TQ

    n = Mcp2510Read(CNF2);         //读取CNF2

    UARTTx(n);

    Mcp2510Write(CNF3,0x02);         //(PHSEG2 + 1) x TQ = (2+1)*TQ

    n = Mcp2510Read(CNF3);         //读取CNF3

    UARTTx(n);


   Mcp2510Write(TXRTSCTRL,0x00); //TX2RTS作为数字输入

                                  //TX1RTS作为数字输入                         

                                //TX0RTS作为数字输入 

   Mcp2510Write(TXB0CTRL,0x03); //TBB0报文发送优先级最高

   Mcp2510Write(TXB1CTRL,0x00); //TBB1报文发送优先级最低

   Mcp2510Write(TXB2CTRL,0x00); //TBB1报文发送优先级最低  

 

   Mcp2510Write(TXB0SIDH,0xFF); //TXB0标准标识符bit10-bit3

   Mcp2510Write(TXB0SIDL,0xE0); //TXB0标准标识符bit2-bit0,标准标识符

   Mcp2510Write(TXB1SIDH,0xFF); //TXB1标准标识符bit10-bit3

   Mcp2510Write(TXB1SIDL,0xE0); //TXB1标准标识符bit2-bit0,标准标识符

   Mcp2510Write(TXB2SIDH,0xFF); //TXB2标准标识符bit10-bit3

   Mcp2510Write(TXB2SIDL,0xE0); //TXB2标准标识符bit2-bit0,标准标识符


   Mcp2510Write(TXB0DLC,0x08); //TXB0数据帧,长度为8个字节

   Mcp2510Write(TXB1DLC,0x08); //TXB1数据帧,长度为8个字节

   Mcp2510Write(TXB2DLC,0x08); //TXB2数据帧,长度为8个字节


   Mcp2510Write(TXB0D0,0x00); //清空TXB0发送缓存器

   Mcp2510Write(TXB0D1,0x00); //清空TXB1发送缓存器

   Mcp2510Write(TXB0D2,0x00); //清空TXB2发送缓存器

   Mcp2510Write(TXB0D3,0x00); //清空TXB3发送缓存器

   Mcp2510Write(TXB0D4,0x00); //清空TXB4发送缓存器

   Mcp2510Write(TXB0D5,0x00); //清空TXB5发送缓存器

   Mcp2510Write(TXB0D6,0x00); //清空TXB6发送缓存器

   Mcp2510Write(TXB0D7,0x00); //清空TXB7发送缓存器


   Mcp2510Write(CANINTE,0xFF); //使能所有总线状态和错误中断

   Mcp2510Write(CANINTF,0x00); //清0所有总线状态和错误中断标志


   Mcp2510ModifyBit(CANCTRL,0xE0,0x00);                                      //进入正常模式

   n = Mcp2510Read(CANSTAT)&0xE0; //读取CANSTAT

   UARTTx(n);

}



//***************************************************************************

//MCP2510数据接收

//***************************************************************************

void Mcp2510RedData(void)

{

    u8 n = 0;

    u8 m[2] ={0,0};


    n = Mcp2510Read(EFLG);                                                 //读取中断标志

    UARTTx(n);


    n = Mcp2510Read(CANINTF);                                                 //读取中断标志

    UARTTx(n);


    n = n&0x01;

   if(n==1)

   {

        Mcp2510ModifyBit(CANINTF,0x01,(0<<RX0IF));                           //RX0IF 清0 中断

        Mcp2510SerialReadByte(RXB0SIDH,&m,2); //读取ID

       u16_ID = m[0];

       u16_ID = u16_ID << 8;

       u16_ID = u16_ID |( m[1]&0xE0);

       Mcp2510SerialReadByte(RXB0DLC,&m,1); //数据长度

       u8_DLC = m[0]&0x0F;

       Mcp2510SerialReadByte(RXB0D0,&u8_CANdata[0],u8_DLC);                 //读取数据


       UARTTx(u16_ID>>8);

       UARTTx(u16_ID>>0);

       UARTTx(u8_DLC);

       UARTTx(u8_CANdata[0]);

       UARTTx(u8_CANdata[1]);

       UARTTx(u8_CANdata[2]);

       UARTTx(u8_CANdata[3]);

       UARTTx(u8_CANdata[4]);

       UARTTx(u8_CANdata[5]);

       UARTTx(u8_CANdata[6]);

       UARTTx(u8_CANdata[7]);

   }


}




//***************************************************************************

//MCP2510数据发送

//***************************************************************************

void Mcp2510TxData(u8 *dat,u8 length)

{

    u8 n = 0;

    Mcp2510SerialWriteByte(TXB0D0,dat,length);                                //装载发送数据

    n = Mcp2510Read(TXB0D0);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D1);         

    UARTTx(n);

    n = Mcp2510Read(TXB0D2);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D3);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D4);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D5);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D6);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D7);          

    UARTTx(n);


    Mcp2510Write(TXB0DLC,length);  //设置为发送8个字节    


    Mcp2510Write(TXB0CTRL,0x03);                //设置为中偏低的报文发送优先级


    Mcp2510Write(TXB0SIDH,u16_ID>>8);                  //TXB0SIDH 标识符高位 ID

 

    Mcp2510Write(TXB0SIDL,u16_ID>>0);                  //TXB0SIDL     标识符低位 ID


    Mcp2510RTS();                                                           //请求发送


    delayx1ms(1000);


    Mcp2510WaitTxEnd(TXB0CTRL);                                             //等待发送完成


    n = Mcp2510Read(TXB0D0);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D1);         

    UARTTx(n);

    n = Mcp2510Read(TXB0D2);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D3);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D4);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D5);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D6);          

    UARTTx(n);

    n = Mcp2510Read(TXB0D7);          

    UARTTx(n);


}  



//***************************************************************************

//MCP2510请求发送命令

//***************************************************************************

void Mcp2510RTS(void)

{

    SPI_CS = 0;

    spi_write(SPI_RTS|0x01);

    SPI_CS = 1; //发送请求命令

    delayx1ms(1);

}


//***************************************************************************

//读取MCP2510芯片的状态 

//***************************************************************************

u8 Mcp2510ReadStatus(void)

{

    uchar n = 0;

    SPI_CS = 0;

    spi_write(SPI_READ_STATUS);

     n = spi_write(0x00);

    SPI_CS = 1;

    delayx1ms(1);

    return(n);

}


//***************************************************************************

//等待MCP2510发送结束 

//addr : 读取地址

//***************************************************************************

void Mcp2510WaitTxEnd(u8 addr)

{

    u8 n = 0;


   do

   {

        n = Mcp2510Read(CANINTF);

        UARTTx(n);

        n = Mcp2510Read(EFLG);

        UARTTx(n);


        SPI_CS = 0;

        spi_write(SPI_READ);

        spi_write(addr);

        n = spi_write(0x00);

        SPI_CS = 1;

        n=n&0x08;

        delayx1ms(1);

    }

    while(n);



 

//***************************************************************************

//MCP2510 写数据

//addr:   MCP2510的寄存器地址

//dat:    写入MCP2510寄存器地址的数据

//SPI_WRITE:写命令

//***************************************************************************

void Mcp2510Write(u8 addr,u8 dat)

{

    SPI_CS = 0;

    spi_write(SPI_WRITE);

    spi_write(addr);

    spi_write(dat);

    SPI_CS = 1;

    delayx1ms(1);

}




//***************************************************************************

//MCP2510 读数据

//addr:   MCP2510的寄存器地址

//SPI_READ:读命令

//返回值: 读取地址对应的数据

//***************************************************************************

u8 Mcp2510Read(u8 addr)

{

    u8 n = 0;


    SPI_CS = 0;

    spi_write(SPI_READ);

    spi_write(addr);

    n = spi_write(0x00);

    SPI_CS = 1;

    delayx1ms(1);

    return(n);

}




//***************************************************************************

//MCP2510 位修改

//addr:   MCP2510的寄存器地址

//mask:   屏蔽位

//dat:    写入MCP2510寄存器地址的数据

//SPI_BIT_MODIFY:位修改命令

//***************************************************************************

void Mcp2510ModifyBit(u8 addr,u8 mask,u8 dat)

{

    SPI_CS = 0;

    spi_write(SPI_BIT_MODIFY);

    spi_write(addr);

    spi_write(mask);

    spi_write(dat);

    SPI_CS = 1;

    delayx1ms(1);

}




//***************************************************************************

//MCP2510 连续写字节

//addr:   MCP2510的寄存器地址

//dat:    写入MCP2510寄存器地址的连续数据

//length:数据长度

//***************************************************************************

void Mcp2510SerialWriteByte(u8 addr,u8 *dat,u8 length)

{

    u8 n = 0;


    SPI_CS = 0;

    spi_write(SPI_WRITE);

    spi_write(addr);

    for(n=0;n<length;n=n+1)

    {

        spi_write(*dat);

        dat = dat+1;

    }

    SPI_CS = 1;

    delayx1ms(1);

}



//***************************************************************************

//MCP2510 连续读字节

//addr:   MCP2510的寄存器地址

//dat:    读出MCP2510寄存器地址的连续数据

//length:数据长度

//***************************************************************************

void Mcp2510SerialReadByte(u8 addr,u8 *dat,u8 length)

{

    u8 n = 0;


    SPI_CS = 0;

    spi_write(SPI_READ);

    spi_write(addr);

    for(n=0;n<length;n=n+1)

   {

        dat = dat+n;

        *dat = spi_write(0x00);

    }

    SPI_CS = 1;

    delayx1ms(1);

}



/*

*****************************************************************************

* SPI  write 

*****************************************************************************

*/    

uchar spi_write(uchar spidata)

{

    uchar i;

    uchar j;


   for(i=8;i>0;i=i-1)

   {

       if(spidata&0x80)

       {

            SPI_MOSI = 1;

       }

      else

     {

            SPI_MOSI = 0;

      }    


      SPI_SCK = 1;

      spi_delay();


      j = j<<1;

     if(SPI_MISO)

     {

          j = j|0x01;

      }

      else

     {

          j = j&0xFE;

     }

     spidata = spidata<<1;


     SPI_SCK = 0;

     spi_delay();  

   }

    return(j);     

}



/*****************************************************************************

*SPI 时钟延时

******************************************************************************/

void spi_delay(void)

{

    uchar i;

    for(i=255;i!=0;i--)

   {   

   }   

}


正在下载,请等待……
下载附件需0积分!




Succeed

  • 精华:0帖
  • 求助:1帖
  • 帖子:1帖 | 2回
  • 年度积分:0
  • 历史总积分:3
  • 注册:2016年5月20日
发表于:2016-05-20 14:35:21
1楼

附件为MCP2510的中文规格书

LLLQQQ

  • 精华:0帖
  • 求助:1帖
  • 帖子:6帖 | 70回
  • 年度积分:2
  • 历史总积分:318
  • 注册:2016年5月20日
发表于:2016-05-20 18:33:20
2楼

不错,收下了!!!!!!!!!!!!!!!!!1!!!!

sange

  • 精华:0帖
  • 求助:0帖
  • 帖子:1帖 | 669回
  • 年度积分:0
  • 历史总积分:553
  • 注册:2019年5月30日
发表于:2019-05-30 13:26:31
3楼

现场总线,工业以太网,工业交换机通信产品:(手机13072208083,网址www.tj-sange.com 天津)

(1)CAN CANOpen DeviceNet 总线

CAN转光纤(点对点)、CAN转光纤(环网 手拉手)

CAN集线器(8路)、CAN总线延长 中继器器、CANModbus 485. CAN转网口

(2)Modbus 485总线

485转光纤(点对点)、485转光纤(环网 手拉手)

485集线器(8路)、485总线延长 中继器器、CANModbus 485. 485转网口

(3)Profibus总线

Profibus转光纤(点对点)、Profibus转光纤(环网 手拉手)

Profibus集线器(4路)、Profibus总线延长 中继器器、ProfibusModbus 485

4)模拟量转光纤4-20mA 、模拟量转光纤0-10V、  开关量转光纤

5HARTModbus 485.

64-20mA 0-10V采集卡( 485接口Modbus协议)

7)手持信号发生器 电荷测量仪

8CC-LINK转光纤

9485 CAN PRIFIBUS  转网口

10485 4-20MA 0-10VLORA

(11) Profinet 转Modbus网关



热门招聘
相关主题

官方公众号

智造工程师