MCP2515无法接收ID和数据,.C文件贴出来了,有哪位帮忙看看

2019-07-20 02:47发布

#include  "mcp2515.h"
#include  "delay.h"
#include  "spi.h"
#include "can_protocol_ywk.h"
#include "stdio.h"

#define CS PAout(4)// PA4
extern CAN_FRAME_STRUCT current_frame3;     //CAN2

u8 dummy=0;
u8 number=0,number1=0,number2=0,j,number3=0,number4=0,number5=0,number6=0;
///*RXB0's data registers:*/
unsigned char RXB0D[8]={RXB0D0,RXB0D1,RXB0D2,RXB0D3,RXB0D4,RXB0D5,RXB0D6,RXB0D7};
///*TXB0's data registers:*/
unsigned char TXB0D[8]={TXB0D0,TXB0D1,TXB0D2,TXB0D3,TXB0D4,TXB0D5,TXB0D6,TXB0D7};
volatile int can3_rx_data_flag=0;

void MCP_2515_init()
{
    SPIReset();
     delay_ms(1);
  //SPIByteWrite(CANCTRL,0x80);//CAN工作在配置模式
  //设置波特率为10Kbps
  //set CNF1,SJW=00,长度为1TQ,BRP=49,TQ=[2*(BRP+1)]/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(RXB0CTRL,0x20);//仅仅接收标准标识符的有效信息,FIILHIT0=0表示RXB0 ,采用FILHIT0
        SPIByteWrite(RXF0SIDH,0xFF);//初始化接收滤波器0,待修改***
  SPIByteWrite(RXF0SIDL,0xE0)
        ;
        SPIByteWrite(RXF1SIDH,0xFD);//初始化接收滤波器0,待修改***
  SPIByteWrite(RXF1SIDL,0xC0);
       
        SPIByteWrite(RXM0SIDH,0x00);
  SPIByteWrite(RXM0SIDL,0x00);
       
//set TXB0,设置发送缓冲器0的标识符和发送的数据,以及发送的数据长度
  SPIByteWrite(TXB0SIDH,0xFF);//设置发送缓冲器0的标准标识符,待修改***
  SPIByteWrite(TXB0SIDL,0xE0);//用到标准标识符
       
        SPIByteWrite(RXB0DLC,DLC_8);//设置接收数据的长度为8个字节

  //SPIByteWrite(TXB0D0,0x1E);//有待修改及确定是否使用
  //SPIByteWrite(TXB0D1,0x10);//有待修改及确定是否使用

  /*set TXB1
  SPIByteWrite(TXB1SIDH,0x50);    //Set TXB0 SIDH
  SPIByteWrite(TXB1SIDL,0x00);    //Set TXB0 SIDL
  SPIByteWrite(TXB1DLC,0x40 | DLC_8);    //Set DLC = 3 bytes and RTR bit*/
       
  //设置接收缓冲器0中断
    SPIByteWrite(CANINTF,0x00);//清空中断标志
                SPIByteWrite(CANINTE,0x01);//接收缓冲器0满中断使能位

  SPIByteWrite(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED);//设置正常模式

  dummy=SPIByteRead(CANSTAT);        //如果还处于配置模式,就进入工作模式配置
  
        if(OPMODE_NORMAL!=(dummy&0xE0))
  {
    SPIByteWrite(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED);//判断进入正常工作模式
  }

}         
void SPIReset()             //器件复位
{
   CS=0;
   SPI1_ReadWriteByte(CAN_RESET);
   CS=1;
}
//初始化完全完全正确
//读指定地址的指令
u8 SPIByteRead(u8 addr)
{
  u8 tempdata;
  CS=0;
  WriteSPI(CAN_READ);
  WriteSPI(addr);
  tempdata=ReadSPI();
  CS=1;
  return tempdata;

}

//功能:只修改寄存器中的某些位
//入口参数:Addr:寄存器地址  MASK:屏蔽字  dat:数据字节
void        MODIFY_2515(unsigned char Addr, unsigned char MASK, unsigned char dat)
{
    CS = 0 ;
    //WriteSPI(0x05);
          WriteSPI(CAN_BIT_MODIFY);
    WriteSPI(Addr) ;
    WriteSPI(MASK) ;
    WriteSPI(dat) ;
    CS = 1 ;
}


void SPIByteWrite(u8 addr,u8 value)          //向2515指定一个地址写指令
{
  CS=0;
  WriteSPI(CAN_WRITE);
  WriteSPI(addr);
  WriteSPI(value);
  CS=1;
}
/*******add zhang***********/
unsigned char ReadByte_MCP2515(unsigned char Addr)
{
    unsigned char Data;                    
    CS=0;               
    WriteSPI(CAN_READ);
    WriteSPI(Addr);
    Data = SPI1_ReadWriteByte(Addr);   
    CS=1;               
    return Data;
}
unsigned char SPI_CMD_MCP2515(unsigned char CMD)
{
  unsigned char Data;                  
  CS=0;
  Data=SPI1_ReadWriteByte(CMD);
  CS=1;
  return Data;
}

//CAN发送任意长度字节
void CAN_Send_anylength(u8 *CAN_TX_Buf,u8 length1)
{
     
  unsigned char tempdata,j;
  tempdata=SPIByteRead(CAN_RD_STATUS);
  SPIByteWrite(TXB0DLC,length1);
  for(j=0;j<length1;j++)
  {
    SPIByteWrite(TXB0D0+j,CAN_TX_Buf[j]);
  }

  if(tempdata&0x04)//判断TXREQ标志位
  {
    delay_ms(1);
                MODIFY_2515(TXB0CTRL,0x80,0x00);//clear TXREQ bit   add zhang
    //SPIByteWrite(TXB0CTRL,0);//清除TXREQ标志位  old code
    while(SPIByteRead(CAN_RD_STATUS)&0x04);//等待TXREQ清零
                 delay_ms(1);
  }
  CS=0;
  WriteSPI(CAN_RTS_TXB0);//发送缓冲器0请求发送
  CS=1;
}

void WriteSPI(u8 ch)                  //写函数
{
    SPI1_ReadWriteByte(ch);
}


u8 ReadSPI(void)
{  
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
   SPI_I2S_SendData(SPI1, 0xff);
   
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  return SPI_I2S_ReceiveData(SPI1);
}

/*********  ADD ***********
  * @brief  Send a byte to CAN bus by TXB0
  * @param  Data:data to be sent
  * @retval none
  */
void CAN_SendOneByte(unsigned char Data)
{
    unsigned char tempdata;
/*Test the driver between MCP2515 and the SPI periphere :tempdata<--------------*/
    tempdata=SPI_CMD_MCP2515(CAN_RD_STATUS);
    if(tempdata&0x04)//check the TXREQ bit
    {
        delay_ms(1);
        MODIFY_2515(TXB0CTRL,0x08,0x00);//clear TXREQ bit
        while(SPI_CMD_MCP2515(CAN_RD_STATUS)&0x04);//wait until TXREQ bit matchs 0
    }
    SPIByteWrite(TXB0D0,Data);
    CS=0;
    WriteSPI(CAN_RTS_TXB0);//TXB0 send-request
    CS=1;
}

/*********  Add
  * @brief  Receive a byte from MCP2515 RXB0
  * @param  none
  * @retval Data:return the effectively data from RXB0
  */
unsigned char CAN_Receive_onebyte()
{
    unsigned char tempdata;
    tempdata=SPI_CMD_MCP2515(CAN_RD_STATUS);//confirm receive data=RXB0IF
    if(tempdata&0x01)   
    {
        tempdata=SPI_CMD_MCP2515(CAN_RX_STATUS);
        if(tempdata&0x40)//true means RXB0's standard frame
        {            
            tempdata=ReadByte_MCP2515(RXB0D0);
        }
        else
            {tempdata=254;}//no standard frame receive
        MODIFY_2515(CANINTF,0x01,0x00);   
    }
    else
        {tempdata=255;}//no frame receive
    return tempdata;
}

/***************ADD ***********
  * @brief   Send n bytes with a given standard ID  corresponding to frame type
  * @param   CAN_TX_Buf: data to be sent
  * @param     DLCLC<=8
  * @param   SID:<=0x7FF
  * @param   CAN_FrameType:CAN_STD,CAN_RTR        
  * @retval None
  */
void CAN_SendData(unsigned char *CAN_TX_Buf,Frame_TypeDef *Frame )
{
    unsigned char tempdata;
    unsigned char HSID,LSID;
    if(Frame->Type==CAN_STD)
    {
        /*Set the ID of the frame*/
        HSID=(unsigned char)(Frame->SID>>3);
        LSID=(unsigned char)((Frame->SID<<5)&0xE0);
        SPIByteWrite(TXB0SIDH,HSID);
        SPIByteWrite(TXB0SIDL,LSID);
        /*Set the DLC and the type of the frame*/
        SPIByteWrite(TXB0DLC,Frame->DLC|CAN_STD);
        /*Write the data into the TXB0 data registers */
        for(tempdata=0;tempdata<Frame->DLC;tempdata++)
        SPIByteWrite(TXB0D[tempdata],CAN_TX_Buf[tempdata]);        

    }
    else  /*if(CAN_FrameType==CAN_RTR)*/
    {
        /*Set the ID of the frame*/
        HSID=(unsigned char)(Frame->SID>>3);
        LSID=(unsigned char)((Frame->SID<<5)&0xE0);
        SPIByteWrite(TXB0SIDH,HSID);
        SPIByteWrite(TXB0SIDL,LSID);
        /*Set the type of the frame*/
        SPIByteWrite(TXB0DLC,CAN_RTR);
    }

    tempdata=SPI_CMD_MCP2515(CAN_RD_STATUS);
    if(tempdata&0x04)
    {
        delay_ms(1);
        MODIFY_2515(TXB0CTRL,0x80,0x00);
        while(SPI_CMD_MCP2515(CAN_RD_STATUS)&0x04);
    }
    /*Send the SPI_RTS_TXB0 request command to MCP2515 to send the data loaded in the data register*/
    CS=0;
    WriteSPI(CAN_RTS_TXB0);
    CS=1;
}



/*********  
  * @brief  Receive n bytes from MCP2515 RXB0
  * @param  none
  * @retval Data:return the effectively data from RXB0
  */
unsigned char CAN_ReceiveData(unsigned char *CAN_RX_Buf,Frame_TypeDef *Frame)
{
    unsigned char tempdata;
    unsigned int CAN_ID;
          unsigned int RXID[6];

    tempdata=SPI_CMD_MCP2515(CAN_RD_STATUS);//check if it is received a  frame
    tempdata=SPI_CMD_MCP2515(CAN_RX_STATUS);

    if(tempdata&0x40)//RXB0
    {

                          RXID[0]=(unsigned int)(SPIByteRead(RXB0SIDH));
                          RXID[1]=(unsigned int)(SPIByteRead(RXB0SIDL));   //62h
                                RXID[4]=(unsigned int)(SPIByteRead(RXB0DLC));    //65h
                          Frame->DLC=RXID[4]&0x0f;                       
                        if((RXID[1]>>3)&1)       //判断是否是扩展id       
                        {
                          RXID[2]=(unsigned int)(SPIByteRead(RXB0EID8));   //63h
                                RXID[3]=(unsigned int)(SPIByteRead(RXB0EID0));   //64h


                                CAN_ID=((RXID[1]&0x03)<<16 ) +( RXID[2]<<8) + RXID[3];   //得到扩展id
                      Frame->SID=CAN_ID;
                        }
                                else
                        {
                                CAN_ID=RXID[0]<<8;
                          CAN_ID|= RXID[1]>>5;   //是标准id
                          //CAN_ID>>=5;         
                                Frame->SID=CAN_ID;
                        }  
        /*Check the CAN_ID you received that if it is matched with the SID you wish*/
        if(Frame->DLC==0x08)//if(Frame->DLC==8)
        {
            for(tempdata=0;tempdata<Frame->DLC;tempdata++)
            {
                                                  CAN_RX_Buf[tempdata]=SPIByteRead(RXB0D[tempdata]);
                                                }
                                                current_frame.id=CAN_ID;
                                                current_frame.message_length=Frame->DLC;
                                                current_frame.p_data_buf=CAN_RX_Buf;
                                                Can_Protocol_Analizy(current_frame);
                                                MODIFY_2515(CANINTF,0x01,0x00);
                                                return 1;//receive ok
        }
        else
        {
            return 0;//ID is not correct
        }
    }
    else
                {
                    return 2;//no standard frame receive
                }
}
















友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
夏天的清凉
1楼-- · 2019-07-20 07:03
已经解决,正常工作,调试完毕
正点原子
2楼-- · 2019-07-20 10:05
 精彩回答 2  元偷偷看……
夏天的清凉
3楼-- · 2019-07-20 14:32
 精彩回答 2  元偷偷看……
墨香余味
4楼-- · 2019-07-20 19:54
恩,你这样子的话,用canopen协议可以访问驱动器吗

一周热门 更多>