aisikaozhe 发表于 2012-11-4 16:15:18

STC+MCP2515的CAN总线发送失败的原因

本帖最后由 aisikaozhe 于 2012-11-4 16:20 编辑

unsigned char CAN_TX_Buf={'1','2','3','5','8','3','1','4'};
unsigned char CAN_RX_Buf;
void Init2515(void)
{
        SPIReset();          //CAN(MCP2515)复位
        delay_ms(1);
        BitModiMcp2515(CANCTRL,0xe0,REQOP_CONFIG);//进入配置模式
        while(SPIByteRead(CANSTAT)&0xE0!=0x80)          //判断是否已经进入配置模式
        {          
             BitModiMcp2515(CANCTRL,0xe0,0x80);
                   delay_ms(100);
                   SendString("Position 1");
        }

        //设置波特率为10Kbps
             //set CNF1,SJW=00,长度为1TQ,BRP=49,TQ=/Fsoc=2*50/8M=12.5us
        SPIByteWrite(CNF1,CAN_125Kbps);
             //set CNF2,SAM=0,在采样点对总线进行一次采样,PHSEG1=(2+1)TQ=3TQ,PRSEG=(0+1)TQ=1TQ
        SPIByteWrite(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ);
             //set CNF3,PHSEG2=(2+1)TQ=3TQ,同时当CANCTRL.CLKEN=1时设定CLKOUT引脚为时间输出使能位
        SPIByteWrite(CNF3,PHSEG2_3TQ);
       
        //配置发送
        SPIByteWrite( TXRTSCTRL, 0 );//禁用引脚的发送请求功能
        //配置接收,
    SPIByteWrite( BFPCTRL, 0 );           //禁用引脚的接收中断功能

        SPIByteWrite(RXM0SIDH,0x00);       //接收屏蔽
        SPIByteWrite(RXM0SIDL,0x00);       // H/L=0/0 ---- 接收符合滤波器条件的所有带扩展标识符或标准标识符的有效报文
       
        SPIByteWrite(RXF0SIDH,0x00);       //接收过滤
        SPIByteWrite(RXF0SIDL,0x00);       //接收所有数据

        SPIByteWrite(RXB0CTRL,0x60);   //0x60代表接收所有报文,0x20代表接收STDID的报文
    //CAN中断的初始化
        //MCP2515_INT_Init();
        //配置模式(回环/正常模式)       
        while(SPIByteRead(CANSTAT)&0xe0!=REQOP_LOOPBACK);       
        {
        SPIByteWrite(CANCTRL,REQOP_LOOPBACK);   //进入回环模式
        }
}



//CAN发送程序--包括ID、DLC(数据长度)、RTR(帧类型)、DATA
void CAN_Send(unsigned char *CAN_TX_Buf)
{
        unsigned char tempdata;          
//设置ID---每个节点的ID是唯一的,但接收的ID可以有多个
        SPIByteWrite(TXB0SIDH,0xFF);//设置发送缓冲器0的标准标识符,
        SPIByteWrite(TXB0SIDL,0xE0);//使用标准ID---发送标准标识符
//设置DLC和RTR
        SPIByteWrite(TXB0DLC,DLC_8);//设置发送数据帧---长度为8个字节
//发送数据
        SPIByteWrite(TXB0D0,CAN_TX_Buf);          //向发送缓冲器写数据
        SPIByteWrite(TXB0D1,CAN_TX_Buf);
        SPIByteWrite(TXB0D2,CAN_TX_Buf);
        SPIByteWrite(TXB0D3,CAN_TX_Buf);
        SPIByteWrite(TXB0D4,CAN_TX_Buf);
        SPIByteWrite(TXB0D5,CAN_TX_Buf);
        SPIByteWrite(TXB0D6,CAN_TX_Buf);
        SPIByteWrite(TXB0D7,CAN_TX_Buf);
        //启动发送
        BitModiMcp2515(TXB0CTRL,0x08,0x08);   //发送缓冲器0请求发送
        delay_ms(1);
        tempdata=SPIByteRead(TXB0CTRL);//读状态寄存器--读发送状态
        while(tempdata&0x08)    //判断TXREQ标志位(此处可能有错)
        {                                        //对应寄存器TXBnCTRL的位3
                BitModiMcp2515(TXB0CTRL,0x08,0x08);   //发送缓冲器0请求发送
                delay_ms(1);
          tempdata=SPIByteRead(TXB0CTRL);//读状态寄存器--读发送状态(读状态指令failed,但读TXB0CTRLsucceed)
                SendString("TX is failed\n");
        }
        SendString("TX is succeed\n");

}

//CAN接收程序
void CAN_Receive(unsigned char *CAN_RX_Buf)
{
      //接收数据
                CAN_RX_Buf=SPIByteRead(RXB0D0);       //从接收缓冲器0中读数据
                CAN_RX_Buf=SPIByteRead(RXB0D1);
                CAN_RX_Buf=SPIByteRead(RXB0D2);
                CAN_RX_Buf=SPIByteRead(RXB0D3);
                CAN_RX_Buf=SPIByteRead(RXB0D4);
                CAN_RX_Buf=SPIByteRead(RXB0D5);
                CAN_RX_Buf=SPIByteRead(RXB0D6);
                CAN_RX_Buf=SPIByteRead(RXB0D7);       //从接收缓冲器7中读数据               

}
//外中断(主要用于接收数据)
void MCP2515_Int(void) interrupt 0        using 1
{
CAN_Receive(CAN_RX_Buf);    //接收数据
SPIByteWrite(CANINTF,0);        //CAN中断标志位清零
SendString("Receive data:");
SendString("CAN_RX_Buf");
}
//中断初始化
void MCP2515_INT_Init(void)
{       
    //外部中断初始化
        EX0 = 1;//开外部中断0
        IT0 = 1;//负边沿触发
        EA = 1;          //开总中断
        //MCP2515中断初始化-----设置接收缓冲器0中断              
        SPIByteWrite(CANINTF,0x00);//清空中断标志位
        SPIByteWrite(CANINTE,0x01);//接收缓冲器0满中断使能位
}

void main()
{
        InitUart();
        LED_OFF(all);                        //全熄灭代表进入配置模式
        CAN_RX_Buf=0;
        while(1)
        {       
          Init2515();   //CAN初始化
          SendString("Position 3\n");
            CAN_Send(CAN_TX_Buf);
      //应该先判断是否接收到数据
                if(SPIByteRead(RXB0DLC)&0x0f!=0)
                {
                SendString("Receive data:");
                CAN_Receive(CAN_RX_Buf);       //轮询法接收数据 (或者中断法接收数据)
      SendString(CAN_RX_Buf);
                SendUart('\n');
                }
                LED_ON_OFF(LED_2);       //指示程序运行
                delay_ms(100);
        }
}

使用的是回环模式,发送成功了,但是未收到数据,这是为什么?
页: [1]
查看完整版本: STC+MCP2515的CAN总线发送失败的原因