相关文章推荐
不羁的手链  ·  啟用 GPIO、I2C 和 SPI ...·  6 天前    · 
强健的蚂蚁  ·  一文掌握Power ...·  2 年前    · 
  • MCP2515 Write Byte : 傳入值為暫存器地址與要寫入資料
  • void MCP2515_WriteByte(uint8_t address, uint8_t data)
      StartSPI();
      SPI_Tx(CAN_WRITE);
      SPI_Tx(address);
      SPI_Tx(data);
      StopSPI();
    
  • MCP2515 Read Byte
  • uint8_t MCP2515_ReadByte (uint8_t address)
      uint8_t redata;
      StartSPI();
      SPI_Tx(CAN_READ);
      SPI_Tx(address);
      retVal = SPI_Rx();
      StopSPI();
      return redata;
    
  • MCP2515 Set Config Mode : 由於要設定ID Mask Filter等等需要先進入設置模式
  • int MCP2515_SetConfigMode(void) //配置模式
      MCP2515_WriteByte(CANCTRL, 0x80);
      uint8_t t = 10;
      do { //檢查CANSTAT是否已進入配置模式
        if((MCP2515_ReadByte(CANSTAT) & 0xE0) == 0x80)
          return 1;
      } while(t > 0);
      return 0;
    
  • MCP2515 Set Normal Mode
  • int MCP2515_SetNormalMode(void) //正常模式
      MCP2515_WriteByte(CANCTRL, 0x00);
      uint8_t t = 10;
        if((MCP2515_ReadByte(CANSTAT) & 0xE0) == 0x00)
          return 1;
      } while(t > 0);
      return 0;
    
  • MCP2515 Set Loop Mode
  • int MCP2515_SetLoopMode(void) //loop mode
      MCP2515_WriteByte(CANCTRL, 0x40);
      uint8_t t = 10;
        if((MCP2515_ReadByte(CANSTAT) & 0xE0) == 0x40)
          return 1;
      } while(t > 0);
      return 0;
    
  • MCP2515 Reset
  • void MCP2515_ResetBus(void)
    	StartSPI();
    	SPI_Tx(CAN_RESET);
    	StopSPI();
    
  • MCP2515 Initialize : 初始化MCP2515,在這邊會去將ID、Mask、Filter、TQ、Interrupt都設定好!
  • int MCP2515_InitSys(void)
    	MCP2515_ResetBus(); //Reset
    	MCP2515_SetConfigMode(); //IntoConfig mode
    //	Set TQ
    	MCP2515_WriteByte(CNF1,0x03);
    	MCP2515_WriteByte(CNF2, 0x80|PHSEG1_3TQ|PRSEG_1TQ);
    	MCP2515_WriteByte(CNF3, PHSEG2_3TQ);
    //	Set CANBUS ID
    	MCP2515_WriteByte(TXB0SIDH, 0x11);
    	MCP2515_WriteByte(TXB0SIDL, 0xE8); //bit3 EXIDE set 1
    	MCP2515_WriteByte(TXB0EID8, 0xFF);
    	MCP2515_WriteByte(TXB0EID0, 0xFF);
    //	Clear Receive Register
    	MCP2515_WriteByte(RXB0SIDH, 0x00);
    	MCP2515_WriteByte(RXB0SIDL, 0x00);
    	MCP2515_WriteByte(RXB0EID8, 0x00);
    	MCP2515_WriteByte(RXB0EID0, 0x00);
    	MCP2515_WriteByte(RXB0CTRL, 0x40);
    	MCP2515_WriteByte(RXB0DLC, DLC_8);
    //	Set Filter
    	MCP2515_WriteByte(RXF0SIDH, 0x11);
    	MCP2515_WriteByte(RXF0SIDL, 0xE8);
    	MCP2515_WriteByte(RXF0EID8, 0xFF);
    	MCP2515_WriteByte(RXF0EID0, 0xFF);
    //	Set Mask
    	MCP2515_WriteByte(RXM0SIDH, 0x00);
    	MCP2515_WriteByte(RXM0SIDL, 0x00);
    	MCP2515_WriteByte(RXM0EID8, 0x00);
    	MCP2515_WriteByte(RXM0EID0, 0x00);
    //	Config Interrupt
    	MCP2515_WriteByte(CANINTE, 0x01);
    	MCP2515_WriteByte(CANINTF, 0x00);
    //	Exit ConfigMode
    	//MCP2515_SetNormalMode(); //手上有兩組可以設置為正常模式
    	MCP2515_SetLoopMode();
    
  • CAN Bus Send Buffer : 將資料傳送出去
  • void CAN_SendBuffer(uint8_t *CANTxBUFF,uint8_t len)
    	uint8_t j,dleaytime,count;count = 0;
    	while(count<len) //Read TXB0CTRL State wait TxREQ clean to 0
    		dleaytime=0;
    		while((MCP2515_ReadByte(TXB0CTRL)&0x08)&&(dleaytime<50))
    			HAL_Delay(1);dleaytime++;
    		for(j=0;j<8;) //Reload data to TXB0D0-D7
    			MCP2515_WriteByte(TXB0D0+j,CANTxBUFF[count++]);
    			if(count>=len)
    				break;
    	MCP2515_WriteByte(TXB0DLC, 8); //Set DataDLC 這邊將資料長度設為8Byte
    	StartSPI();
    	MCP2515_WriteByte(TXB0CTRL, 0x08); //Request Send Data
    	StopSPI();
    
  • CAN Bus Send Buffer : 接收Bus上的資料
  • uint8_t CAN_ReceiveBuffer(uint8_t *CANRXBuff)
    	unsigned char i=0,len=0,temp=0;
    	temp = MCP2515_ReadByte(CANINTF); //Read Interrupt Register Buffer
    	if(temp&0x01) 
    		len=MCP2515_ReadByte(RXB0DLC);
    		while(i<len)
    			CANRXBuff[i] = MCP2515_ReadByte(RXB0D0+i);
    	MCP2515_WriteByte(CANINTF, 0x00); //Receive Data Finish , need set 0 to Clear Interrupt Flag
    	return len;
    
  • main() :
  • uint8_t CAN_RX_BUFF[8];
    uint8_t CAB_TX_BUFF[8] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01};//要傳送的資料
    int main(void)
      HAL_Init();
      SystemClock_Config();
      MX_GPIO_Init();
      MX_USART2_UART_Init();
      MX_SPI1_Init();
      State =  MCP2515_InitSys(); //初始化MCP2515
      while (1)
    	  CAN_SendBuffer(CAB_TX_BUFF, 8);
    	  HAL_Delay(1000);
    	  CAN_ReceiveBuffer(CAN_RX_BUFF);
    	  HAL_UART_Transmit(&huart2, (uint8_t *)CAN_RX_BUFF, 8, 100); //透過USART顯示在電腦上
    
  • 接著就可以接上電腦實際測試一下接收回來的數據拉!
  •