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顯示在電腦上
接著就可以接上電腦實際測試一下接收回來的數據拉!