原创 MCP2515驱动代码

2022-5-18 16:02 2092 10 分类: MCU/ 嵌入式 文集: C语言
/*
  • * @file mcp2515.h
  • * @author TanQi
  • * @version V1.0.0
  • * @date 2022-1-20
  • * @brief Header for mcp2515.c module
  • */
  • /* Define to prevent recursive inclusion -------------------------------------*/
  • #ifndef __MCP2515_H
  • #define __MCP2515_H
  • /* Includes ------------------------------------------------------------------*/
  • #include "board.h"
  • /* Exported types ------------------------------------------------------------*/
  • /* Exported constants --------------------------------------------------------*/
  • /* Exported macro ------------------------------------------------------------*/
  • /* Exported functions ------------------------------------------------------- */
  • void MCP2515_Init(void);
  • void MCP2515_Poll(void);
  • void MCP2515_Poll_1ms(void);
  • void MCP2515_Reset(void);
  • void MCP2515_Read(uint8_t addr, uint8_t count, uint8_t * ptr);
  • void MCP2515_ReadRxBuf(uint8_t buf, uint8_t count, uint8_t * ptr);
  • void MCP2515_Write(uint8_t addr, uint8_t count, uint8_t * ptr);
  • void MCP2515_LoadTxBuf(uint8_t buf, uint8_t count, uint8_t * ptr);
  • void MCP2515_LoadTxDLC(uint8_t buf,uint8_t DLC);
  • void MCP2515_RTS(uint8_t txb);
  • uint8_t MCP2515_ReadStatus(void);
  • uint8_t MCP2515_RxStatus(void);
  • void MCP2515_BitModfye(uint8_t addr, uint8_t mask, uint8_t data);
  • void MCP2515_SetTxPriority(uint8_t txb, uint8_t priority);
  • void MCP2515_InitiateTx(uint8_t txb);
  • void MCP2515_SetRxMode(uint8_t rxb,uint8_t mode);
  • void MCP2515_BitTimingConfig(void);
  • void MCP2515_InterruptConfig(uint8_t bit_mask, uint8_t enable);
  • void MCP2515_LoadTxSID(uint8_t txb, uint32_t sid);
  • void MCP2515_LoadRxf(uint8_t rxf, uint32_t sid);
  • void MCP2515_LoadRxm(uint8_t rxm, uint32_t mask);
  • uint8_t MCP2515_ReadICOD(void);
  • void MCP2515_LoopBackMode(void);
  • void MCP2515_NormalOpMode(void);
  • #endif /* __MCP2515_H */
  • /*
  • * @file mcp2515.c
  • * @author TanQi
  • * @version V1.0.0
  • * @date 2022-1-20
  • * @brief mcp2515 driver
  • */
  • #include "board.h"
  • #include "mcp2515.h"
  • #define RESET 0xc0 // 0b11000000
  • #define READ 0x03 // 0b00000011
  • #define READ_RX_BUF 0x90 // 0b10010nm0
  • #define WRITE 0x02 // 0b00000010
  • #define LOAD_TX_BUF 0x40 // 0b01000abc
  • #define RTS 0x80 // 0b10000nnn
  • #define READ_STATUS 0xa0 // 0b10100000
  • #define RX_STATUS 0xb0 // 0b10110000
  • #define BIT_MODIFY 0x05 // 0b00000101
  • void SPI_WriteByte(uint8_t byte)
  • {
  • // MSB first,rising edge clock in data
  • uint8_t i;
  • for(i = 0;i < 8;i++)
  • {
  • if(byte & (1<<7))
  • {
  • BOARD_SPI2_MOSI_SET();
  • }
  • else
  • {
  • BOARD_SPI2_MOSI_RESET();
  • }
  • byte <<= 1;
  • BOARD_SPI2_SCK_SET();
  • BOARD_SPI2_SCK_SET();
  • BOARD_SPI2_SCK_RESET();
  • BOARD_SPI2_SCK_RESET();
  • }
  • }
  • uint8_t SPI_ReadByte(void)
  • {
  • // MSB first,falling edge clock out data
  • uint8_t i;
  • uint8_t byte = 0;
  • for(i = 0;i < 8;i++)
  • {
  • byte <<= 1;
  • if(BOARD_MISO_READ())
  • {
  • byte |= 0x01;
  • }
  • else
  • {
  • byte &= ~0x01;
  • }
  • BOARD_SPI2_SCK_SET();
  • BOARD_SPI2_SCK_SET();
  • BOARD_SPI2_SCK_RESET();
  • BOARD_SPI2_SCK_RESET();
  • }
  • return byte;
  • }
  • void MCP2515_Reset(void)
  • {
  • BOARD_nSPI2_SS_ACTIVE();
  • SPI_WriteByte(RESET);
  • BOARD_nSPI2_SS_INACTIVE();
  • }
  • void MCP2515_Read(uint8_t addr, uint8_t count, uint8_t * ptr)
  • {
  • uint8_t i;
  • BOARD_nSPI2_SS_ACTIVE();
  • SPI_WriteByte(READ);
  • SPI_WriteByte(addr);
  • for(i = 0;i < count;i++)
  • {
  • *(ptr++) = SPI_ReadByte();
  • }
  • BOARD_nSPI2_SS_INACTIVE();
  • }
  • void MCP2515_ReadRxBuf(uint8_t buf, uint8_t count, uint8_t * ptr)
  • {
  • uint8_t i;
  • BOARD_nSPI2_SS_ACTIVE();
  • SPI_WriteByte( READ_RX_BUF | (buf << 2) | (1 << 1) );
  • for(i = 0;i < count;i++)
  • {
  • *(ptr++) = SPI_ReadByte();
  • }
  • BOARD_nSPI2_SS_INACTIVE();
  • }
  • void MCP2515_Write(uint8_t addr, uint8_t count, uint8_t * ptr)
  • {
  • uint8_t i;
  • BOARD_nSPI2_SS_ACTIVE();
  • SPI_WriteByte(WRITE);
  • SPI_WriteByte(addr);
  • for(i = 0;i < count;i++)
  • {
  • SPI_WriteByte(*(ptr++));
  • }
  • BOARD_nSPI2_SS_INACTIVE();
  • }
  • void MCP2515_LoadTxBuf(uint8_t buf, uint8_t count, uint8_t * ptr)
  • {
  • uint8_t i;
  • BOARD_nSPI2_SS_ACTIVE();
  • buf *= 2;
  • buf += 1;
  • SPI_WriteByte( LOAD_TX_BUF | buf );
  • for(i = 0;i < count;i++)
  • {
  • SPI_WriteByte(*(ptr++));
  • }
  • BOARD_nSPI2_SS_INACTIVE();
  • }
  • void MCP2515_LoadTxDLC(uint8_t buf,uint8_t DLC)
  • {
  • uint8_t addr;
  • if(buf == 0)
  • {
  • addr = 0x35;
  • }
  • else if(buf == 1)
  • {
  • addr = 0x45;
  • }
  • else if(buf == 2)
  • {
  • addr = 0x55;
  • }
  • MCP2515_Write(addr,1,&DLC);
  • }
  • static uint8_t read_out;
  • void MCP2515_RTS(uint8_t txb)
  • {
  • BOARD_nSPI2_SS_ACTIVE();
  • SPI_WriteByte( RTS | (1<
  • BOARD_nSPI2_SS_INACTIVE();
  • MCP2515_Read(0x30, 1, &read_out); // debug
  • }
  • uint8_t MCP2515_ReadStatus(void)
  • {
  • uint8_t status;
  • BOARD_nSPI2_SS_ACTIVE();
  • SPI_WriteByte(READ_STATUS);
  • status = SPI_ReadByte();
  • BOARD_nSPI2_SS_INACTIVE();
  • return status;
  • }
  • uint8_t MCP2515_RxStatus(void)
  • {
  • uint8_t status;
  • BOARD_nSPI2_SS_ACTIVE();
  • SPI_WriteByte(RX_STATUS);
  • status = SPI_ReadByte();
  • BOARD_nSPI2_SS_INACTIVE();
  • return status;
  • }
  • void MCP2515_BitModfye(uint8_t addr, uint8_t mask, uint8_t data)
  • {
  • BOARD_nSPI2_SS_ACTIVE();
  • SPI_WriteByte(BIT_MODIFY);
  • SPI_WriteByte(addr);
  • SPI_WriteByte(mask);
  • SPI_WriteByte(data);
  • BOARD_nSPI2_SS_INACTIVE();
  • }
  • void MCP2515_SetTxPriority(uint8_t txb, uint8_t priority)
  • {
  • uint8_t start_addr;
  • if(txb == 0)
  • {
  • start_addr = 0x30;
  • }
  • else if(txb == 1)
  • {
  • start_addr = 0x40;
  • }
  • else if(txb == 2)
  • {
  • start_addr = 0x50;
  • }
  • MCP2515_BitModfye(start_addr, 0x03, priority);
  • }
  • void MCP2515_InitiateTx(uint8_t txb)
  • {
  • uint8_t addr;
  • if(txb == 0)
  • {
  • addr = 0x30;
  • }
  • else if(txb == 1)
  • {
  • addr = 0x40;
  • }
  • else if(txb == 2)
  • {
  • addr = 0x50;
  • }
  • MCP2515_BitModfye(addr, 1<<3, 1<<3);
  • MCP2515_BitModfye(0x0f, 1<<4, 0<<4);
  • }
  • /*
  • * rxm : 11 = Turns mask/filters off; receives any message
  • * 00 = Receives all valid messages using either Standard or Extended Identifiers that meet filter criteria;
  • * Extended ID Filter registers, RXFnEID8:RXFnEID0, are applied to the first two bytes of data in
  • * the messages with standard IDs
  • */
  • void MCP2515_SetRxMode(uint8_t rxb,uint8_t mode)
  • {
  • uint8_t addr;
  • if(rxb == 0)
  • {
  • addr = 0x60;
  • }
  • else if(rxb == 1)
  • {
  • addr = 0x70;
  • }
  • MCP2515_BitModfye(addr, 0x03<<6, mode);
  • }
  • void MCP2515_ConfigMode(void)
  • {
  • uint8_t byte;
  • MCP2515_BitModfye(0x0f, 0x7<<5, 4<<5);
  • do
  • {
  • MCP2515_Read(0x0e, 1, &byte);
  • byte &= (0x07 << 5);
  • }
  • while(byte != (4<<5));
  • }
  • void MCP2515_LoopBackMode(void)
  • {
  • uint8_t byte;
  • MCP2515_BitModfye(0x0f, 0x7<<5, 2<<5);
  • do
  • {
  • MCP2515_Read(0x0e, 1, &byte);
  • byte &= (0x07 << 5);
  • }
  • while(byte != (2<<5));
  • }
  • void MCP2515_NormalOpMode(void)
  • {
  • uint8_t byte;
  • MCP2515_BitModfye(0x0f, 0x7<<5, 0<<5);
  • do
  • {
  • MCP2515_Read(0x0e, 1, &byte);
  • byte &= (0x07 << 5);
  • }
  • while(byte != (0<<5));
  • }
  • void MCP2515_BitTimingConfig(void)
  • {
  • /*
  • MCP2515_ConfigMode();
  • MCP2515_BitModfye(0x2a, 0xff, (0<<6) | (1<<0)); // 125KHz @ 8MHz,SJW = 1T_q, T_q = 2*(1 + 1)/8MHz = 0.5us
  • MCP2515_BitModfye(0x29, 0xff, (6<<3) | (1<<0)); // PS1 = 7T_q, ProgSeg = 2T_q
  • MCP2515_BitModfye(0x28, 0xff, (5<<0)); // PS2 = 6T_q
  • MCP2515_NormalOpMode();
  • */
  • MCP2515_ConfigMode();
  • MCP2515_BitModfye(0x2a, 0xff, (0<<6) | (3<<0)); // 125KHz @ 8MHz,SJW = 1T_q, T_q = 2*(3 + 1)/8MHz = 1us
  • MCP2515_BitModfye(0x29, 0xff, (1<<7) | (2<<3) | (0<<0)); // PS1 = 3T_q, ProgSeg = 1T_q
  • MCP2515_BitModfye(0x28, 0xff, (2<<0)); // PS2 = 3T_q
  • MCP2515_NormalOpMode();
  • }
  • void MCP2515_InterruptConfig(uint8_t bit_mask, uint8_t enable)
  • {
  • MCP2515_ConfigMode();
  • if(enable)
  • {
  • MCP2515_BitModfye(0x2b, bit_mask, 0xff);
  • }
  • else
  • {
  • MCP2515_BitModfye(0x2b, bit_mask, 0x00);
  • }
  • MCP2515_NormalOpMode();
  • }
  • void MCP2515_LoadTxSID(uint8_t txb, uint32_t sid)
  • {
  • uint8_t addr;
  • uint8_t sid_array[2];
  • sid_array[0] = sid>>3;
  • sid_array[1] = (sid<<5);
  • if(txb == 0)
  • {
  • addr = 0x31;
  • }
  • else if(txb == 1)
  • {
  • addr = 0x41;
  • }
  • else if(txb == 2)
  • {
  • addr = 0x51;
  • }
  • // MCP2515_ConfigMode();
  • MCP2515_Write(addr, 2, sid_array);
  • }
  • void MCP2515_LoadRxf(uint8_t rxf, uint32_t sid)
  • {
  • uint8_t addr;
  • uint8_t sid_array[2];
  • sid_array[0] = sid>>3;
  • sid_array[1] = (sid<<5);
  • MCP2515_ConfigMode();
  • if(rxf == 0)
  • {
  • addr = 0x00;
  • }
  • else if(rxf == 1)
  • {
  • addr = 0x04;
  • }
  • else if(rxf == 2)
  • {
  • addr = 0x08;
  • }
  • else if(rxf == 3)
  • {
  • addr = 0x10;
  • }
  • else if(rxf == 4)
  • {
  • addr = 0x14;
  • }
  • else if(rxf == 5)
  • {
  • addr = 0x18;
  • }
  • MCP2515_Write(addr, 2, sid_array);
  • MCP2515_NormalOpMode();
  • }
  • void MCP2515_LoadRxm(uint8_t rxm, uint32_t mask)
  • {
  • uint8_t addr;
  • uint8_t mask_array[2];
  • mask_array[0] = mask>>3;
  • mask_array[1] = mask<<5;
  • MCP2515_ConfigMode();
  • if(rxm == 0)
  • {
  • addr = 0x20;
  • }
  • else if(rxm == 1)
  • {
  • addr = 0x24;
  • }
  • MCP2515_Write(addr, 2, mask_array);
  • MCP2515_NormalOpMode();
  • }
  • uint8_t MCP2515_ReadICOD(void)
  • {
  • uint8_t ret_val = 0;
  • MCP2515_Read(0x0e, 1, &ret_val);
  • ret_val >>= 1;
  • ret_val &= 0x07;
  • return ret_val;
  • }
  • 复制代码

    作者: Qeecoda, 来源:面包板社区

    链接: https://mbb.eet-china.com/blog/uid-me-1099225.html

    版权声明:本文为博主原创,未经本人允许,禁止转载!

    PARTNER CONTENT

    文章评论0条评论)

    登录后参与讨论
    我要评论
    0
    10
    关闭 站长推荐上一条 /3 下一条