前段时间接手一个项目一个CAN总线的扩展板,由于CAN口不够用故采用MCP2515扩展,驱动代码如下:

/*! \file MCP2515.h\brief API to control the Microchip MCP2515 CAN controller. This CANcontroller use the SPI link. For that reason, SPI initiation and datacontrol should custom by the user.\author Sy Sech VONGFr��d��ric NadeauFangZheng @2014.9.10
*/#ifndef MCP2515_H_
#define MCP2515_H_#define USE_INT_STAT            1   // use INT pin indicate recived data//MCP2515 RX/TX buffers selection
#define MCP2515_RX_BUF_0        0
#define MCP2515_RX_BUF_1        1
#define MCP2515_TX_BUF_0        0
#define MCP2515_TX_BUF_1        1
#define MCP2515_TX_BUF_2        2//MCP2515 SPI instructions
#define MCP2515_RESET                   0xC0
#define MCP2515_READ                    0x03
#define MCP2515_READ_BUF_RXB0SIDH       0x90    //read data from begin address of Standard ID (MSB) of RX buffer 0
#define MCP2515_READ_BUF_RXB0D0         0x92    //read data from begin address of data byte 0 of RX buffer 0
#define MCP2515_READ_BUF_RXB1SIDH       0x94    //...RX buffer 1
#define MCP2515_READ_BUF_RXB1D0         0x96    //...RX buffer 1
#define MCP2515_WRITE                   0x02
#define MCP2515_LOAD_BUF_TXB0SIDH       0x40    //load data from begin address of Standard ID (MSB) of TX buffer 0
#define MCP2515_LOAD_BUF_TXB0D0         0X41    //load data from begin address of data byte 0 of TX buffer 0
#define MCP2515_LOAD_BUF_TXB1SIDH       0x42    //...TX buffer 1
#define MCP2515_LOAD_BUF_TXB1D0         0X43    //...TX buffer 1
#define MCP2515_LOAD_BUF_TXB2SIDH       0x44    //...TX buffer 2
#define MCP2515_LOAD_BUF_TXB2D0         0X45    //...TX buffer 2
#define MCP2515_RTS_TXB0                0x81    //activate the RTS of TX buffer 0.
#define MCP2515_RTS_TXB1                0x82    //...TX buffer 1.
#define MCP2515_RTS_TXB2                0x84    //...TX buffer 2.
#define MCP2515_RTS_ALL                 0x87    //...TX buffer 0, 1 and 2.
#define MCP2515_READ_RXTX_STATUS        0xA0
#define MCP2515_RX_STATUS               0xB0
#define MCP2515_BIT_MODIFY              0x05//MCP2515 control settings register address.
//All can be used with the Bit Modify command, except the CANSTAT register.
#define MCP2515_BFPCTRL         0x0C    //RXnBF pin control/status
#define MCP2515_TXRTSCTRL       0x0D    //TXnRTS pin control/status
#define MCP2515_CANSTAT         0x0E    //CAN status. any addr of MSB will give the same info???
#define MCP2515_CANCTRL         0x0F    //CAN control status. any addr of MSB will give the same info???
#define MCP2515_TEC             0x1C    //Transmit Error Counter
#define MCP2515_REC             0x1D    //Receive Error Counter
#define MCP2515_CNF3            0x28    //Phase segment 2
#define MCP2515_CNF2            0x29    //Propagation segment & Phase segment 1 & n sample setting
#define MCP2515_CNF1            0x2A    //Baud rate prescaler & Sync Jump Width
#define MCP2515_CANINTE         0x2B    //CAN interrupt enable
#define MCP2515_CANINTF         0x2C    //Interrupt flag
#define MCP2515_EFLG            0x2D    //Error flag
#define MCP2515_TXB0CTRL        0x30    //TX buffer 0 control
#define MCP2515_TXB1CTRL        0x40    //TX buffer 1 control
#define MCP2515_TXB2CTRL        0x50    //TX buffer 2 control
#define MCP2515_RXB0CTRL        0x60    //RX buffer 0 control
#define MCP2515_RXB1CTRL        0x70    //RX buffer 1 control//MCP2515 relate to CAN settings/status register address.
//Only the most used are listed below. please see the datasheet MCP2515.pdf p61 for complete info.
#define MCP2515_RXF0SIDH        0x00    //RX standard ID (High bits) filter 0
#define MCP2515_RXF0SIDL        0x01    //RX standard ID (Low bits) filter 0
#define MCP2515_RXF0EID8        0x02    //RX Extended ID (High bits) filter 0 ->can be reached by bust read/write Standard ID then Ext. ID
#define MCP2515_RXF0EID0        0x03    //RX Extended ID (Low bits) filter 0
#define MCP2515_RXF1SIDH        0x04    //RX standard ID (High bits) filter 1
#define MCP2515_RXF1SIDL        0x05    //RX standard ID (Low bits) filter 1
#define MCP2515_RXF1EID8        0x06    //RX Extended ID (High bits) filter 1
#define MCP2515_RXF1EID0        0x07    //RX Extended ID (Low bits) filter 1
#define MCP2515_RXF2SIDH        0x08    //RX standard ID (High bits) filter 2
#define MCP2515_RXF2SIDL        0x09    //RX standard ID (Low bits) filter 2
#define MCP2515_RXF2EID8        0x0A    //RX Extended ID (High bits) filter 2
#define MCP2515_RXF2EID0        0x0B    //RX Extended ID (Low bits) filter 2
#define MCP2515_RXF3SIDH        0x10    //RX standard ID (High bits) filter 3
#define MCP2515_RXF3SIDL        0x11    //RX standard ID (Low bits) filter 3
#define MCP2515_RXF3EID8        0x12    //RX Extended ID (High bits) filter 3
#define MCP2515_RXF3EID0        0x13    //RX Extended ID (Low bits) filter 3
#define MCP2515_RXF4SIDH        0x14    //RX standard ID (High bits) filter 4
#define MCP2515_RXF4SIDL        0x15    //RX standard ID (Low bits) filter 4
#define MCP2515_RXF4EID8        0x16    //RX Extended ID (High bits) filter 4
#define MCP2515_RXF4EID0        0x17    //RX Extended ID (Low bits) filter 4
#define MCP2515_RXF5SIDH        0x18    //RX standard ID (High bits) filter 5
#define MCP2515_RXF5SIDL        0x19    //RX standard ID (Low bits) filter 5
#define MCP2515_RXF5EID8        0x1A    //RX Extended ID (High bits) filter 5
#define MCP2515_RXF5EID0        0x1B    //RX Extended ID (Low bits) filter 5
#define MCP2515_RXM0SIDH        0x20    //RX standard ID (High bits) mask filter 0
#define MCP2515_RXM0SIDL        0x21    //RX standard ID (Low bits) mask filter 0
#define MCP2515_RXM0EID8        0x22    //RX Extended ID (High bits) mask filter 0
#define MCP2515_RXM0EID0        0x23    //RX Extended ID (Low bits) mask filter 0
#define MCP2515_RXM1SIDH        0x24    //RX standard ID (High bits) mask filter 1
#define MCP2515_RXM1SIDL        0x25    //RX standard ID (Low bits) mask filter 1
#define MCP2515_RXM1EID8        0x26    //RX Extended ID (High bits) mask filter 1
#define MCP2515_RXM1EID0        0x27    //RX Extended ID (Low bits) mask filter 1
#define MCP2515_RXB0SIDH        0x61    //RX buffer 0 standard ID (High bits)
#define MCP2515_RXB0SIDL        0x62    //RX buffer 0 standard ID (Low bits)
#define MCP2515_RXB0EID8        0x63    //RX buffer 0 Extended ID (High bits) ->can be reached by bust read/write Standard ID then Ext. ID
#define MCP2515_RXB0EID0        0x64    //RX buffer 0 Extended ID (Low bits)
#define MCP2515_RXB0DLC         0x65    //RX buffer 0 DLC  ->can be reached by bust read/write Standard ID, Ext. ID then DLC
#define MCP2515_RXB0D0          0x66    //RX buffer 0 data byte0
#define MCP2515_RXB1SIDH        0x71    //RX buffer 1 standard ID (High bits)
#define MCP2515_RXB1SIDL        0x72    //RX buffer 1 standard ID (Low bits)
#define MCP2515_RXB1EID8        0x73    //RX buffer 1 Extended ID (High bits)
#define MCP2515_RXB1EID0        0x74    //RX buffer 1 Extended ID (Low bits)
#define MCP2515_RXB1DLC         0x75    //RX buffer 1 DLC
#define MCP2515_RXB1D0          0x76    //RX buffer 1 data byte0#define MCP2515_TXB0SIDH        0x31    //TX buffer 0 standard ID (High bits)
#define MCP2515_TXB0SIDL        0x32    //TX buffer 0 standard ID (Low bits)
#define MCP2515_TXB0EID8        0x33    //TX buffer 0 Extended ID (High bits) ->can be reached by bust read/write Standard ID then Ext. ID
#define MCP2515_TXB0EID0        0x34    //TX buffer 0 Extended ID (Low bits)
#define MCP2515_TXB0DLC         0x35    //TX buffer 0 DLC  ->can be reached by bust read/write Standard ID, Ext. ID then DLC
#define MCP2515_TXB0D0          0x36    //TX buffer 0 data byte0
#define MCP2515_TXB1SIDH        0x41    //TX buffer 1 standard ID (High bits)
#define MCP2515_TXB1SIDL        0x42    //TX buffer 1 standard ID (Low bits)
#define MCP2515_TXB1EID8        0x43    //TX buffer 1 Extended ID (High bits)
#define MCP2515_TXB1EID0        0x44    //TX buffer 1 Extended ID (Low bits)
#define MCP2515_TXB1DLC         0x45    //TX buffer 1 DLC
#define MCP2515_TXB1D0          0x46    //TX buffer 1 data byte0
#define MCP2515_TXB2SIDH        0x51    //TX buffer 2 standard ID (High bits)
#define MCP2515_TXB2SIDL        0x52    //TX buffer 2 standard ID (Low bits)
#define MCP2515_TXB2EID8        0x53    //TX buffer 2 Extended ID (High bits)
#define MCP2515_TXB2EID0        0x54    //TX buffer 2 Extended ID (Low bits)
#define MCP2515_TXB2DLC         0x55    //TX buffer 2 DLC
#define MCP2515_TXB2D0          0x56    //TX buffer 2 data byte0//MCP2515 limit values
#define MCP2515_MIN_TQ          0x07    //7 = Minimum TQ in 1 bit of CAN bus time
#define MCP2515_MAX_TQ          0x19    //25 = Maximum TQ in 1 bit of CAN bus time
#define MCP2515_MIN_BRP         0x00    //0 = Minimum baud rate prescaler clock
#define MCP2515_MAX_BRP         0x3F    //63 = Maximum baud rate prescaler clock
#define MCP2515_MAX_SJW         0x03    //4 = Maximum Synchronization Jump Width. 4-1 = 3 actually
#define MCP2515_MAX_BYTE_CANFRM 0x08//8 = Maximun bytes in a CAN frame//MCP2515 register values: CANCTRL register
#define MCP2515_MODE_NORMAL     0x00
#define MCP2515_MODE_SLEEP      0x20
#define MCP2515_MODE_LOOPBACK   0x40
#define MCP2515_MODE_LISTENONLY 0x60
#define MCP2515_MODE_CONFIG     0x80
#define MCP2515_ABORT_TX        0x10
#define MCP2515_MODE_MASK       0xE0
#define MCP2515_MODE_ONESHOT    0x08
#define MCP2515_CLKOUT_ENABLE   0x04
#define MCP2515_CLKOUT_PS1      0x00    //Set CLK out prescaler to 1. Note: not the same as the CAN CLK prescaler.
#define MCP2515_CLKOUT_PS2      0x01    //... to 2
#define MCP2515_CLKOUT_PS4      0x02    //... to 4
#define MCP2515_CLKOUT_PS8      0x03    //... to 8//MCP2515 CAN Status Register bits (CANSTAT 0xXE, ICOD)
#define MCP2515_CANSTAT_NO_INT   0x00
#define MCP2515_CANSTAT_ERR_INT  0x02
#define MCP2515_CANSTAT_WAK_INT  0x04 //Wake-up Interrupt
#define MCP2515_CANSTAT_TXB0_INT 0x06
#define MCP2515_CANSTAT_TXB1_INT 0x08
#define MCP2515_CANSTAT_TXB2_INT 0x0A
#define MCP2515_CANSTAT_RXB0_INT 0x0C
#define MCP2515_CANSTAT_RXB1_INT 0x0E//MCP2515 CAN Interrupt Flag Define
#define MCP2515_CANINTF_MERRF   0x80
#define MCP2515_CANINTF_WAKIF   0x40
#define MCP2515_CANINTF_ERRIF   0x20
#define MCP2515_CANINTF_TX2IF   0x10
#define MCP2515_CANINTF_TX1IF   0x08
#define MCP2515_CANINTF_TX0IF   0x04
#define MCP2515_CANINTF_RX1IF   0x02
#define MCP2515_CANINTF_RX0IF   0x01#define MCP2515_CANINT_MERR     0x80
#define MCP2515_CANINT_WAKI     0x40
#define MCP2515_CANINT_ERRI     0x20
#define MCP2515_CANINT_TX2I     0x10
#define MCP2515_CANINT_TX1I     0x08
#define MCP2515_CANINT_TX0I     0x04
#define MCP2515_CANINT_RX1I     0x02
#define MCP2515_CANINT_RX0I     0x01// porting for F2808 edit by fz
#define ASSERT(expr)   ((void)0) //assert function not use here, so ...
typedef unsigned long  uint32_t;
typedef unsigned int   uint8_t;
/*! \struct mcp2515_can_frame_s*  Structure of a CANbus frame.*/
#if 0
typedef struct mcp2515_can_frame_s{uint32_t id;        /**< Standard or Extented ID*/uint8_t dlc;        /**< Data Length Code*/uint8_t data[8];    /**< Data*/
}mcp2515_can_frame_t;   /**< Typedef of #mcp2515_can_frame_s*/
#endif
// endtypedef struct canfd_frame mcp2515_can_frame_t;typedef enum mcp2515_rx_e
{mcp2515_rx_0,mcp2515_rx_1
}mcp2515_rx_t;typedef enum mcp2515_tx_e
{mcp2515_tx_0,mcp2515_tx_1,mcp2515_tx_2
}mcp2515_tx_t;typedef enum mcp2515_op_mode_e
{mcp2515_op_mode_normal = 0,mcp2515_op_mode_sleep,mcp2515_op_mode_loopback,mcp2515_op_mode_listen,mcp2515_op_mode_config
}mcp2515_op_mode_t;typedef enum mcp2515_rx_op_mode_e
{mcp2515_rx_op_mode_filter_any = 0,mcp2515_rx_op_mode_filter_standard,mcp2515_rx_op_mode_filter_extended,mcp2515_rx_op_mode_any
}mcp2515_rx_op_mode_t;typedef enum mcp2515_rx_filter_mask_e
{mcp2515_rx_filter_mask_RXF0 = 0x00,mcp2515_rx_filter_mask_RXF1 = 0x04,mcp2515_rx_filter_mask_RXF2 = 0x08,mcp2515_rx_filter_mask_RXF3 = 0x10,mcp2515_rx_filter_mask_RXF4 = 0x14,mcp2515_rx_filter_mask_RXF5 = 0x18,mcp2515_rx_filter_mask_RXM0 = 0x20,mcp2515_rx_filter_mask_RXM1 = 0x24
}mcp2515_rx_filter_mask_t;enum
{MCP2515_SPIA = 0,MCP2515_SPIB,MCP2515_SPIC,MCP2515_SPID,MCP2515_DBG
};extern void mcp2515_spi_port_init(void);
extern void mcp2515_chn_select(uint8_t chn);
extern int16 mcp2515_sendmsg(struct canfd_frame *cf);
extern int16 mcp2515_recvmsg(struct canfd_frame *cf);
extern Uint16 mcp2515_init(uint32_t canID, uint8_t ext);
extern void read(uint8_t regAddr, uint8_t *dataAddr);
extern void write(uint8_t regAddr, uint8_t data);//extern void mcp2515_init_ext(uint32_t canID, uint32_t mask, uint8_t ext);
extern void mcp2515_init_ext(uint32_t canID1, uint32_t canID2, uint8_t ext);
extern int16 mcp2515_sendext(struct canfd_frame *cf);
extern int16 mcp2515_recvext(struct canfd_frame *cf);#endif /*MCP2515_H_*/
/*! \file MCP2515.c\brief API for Microchip MCP2515 CAN controller.This CAN controller use the SPI link. For that reason, SPI initiation and datacontrol should custom by the user.\author Sy Sech VONGFr��d��ric NadeauFangZheng @2014.9.20*/#include "global.h"#define DEBUG_MCP 1extern void mcp2515_spi_port_init(void);//extern void mcp2515_spi_select(void);//extern void mcp2515_spi_unselect(void);//extern void mcp2515_spi_transfer(uint8_t dataOut, uint8_t *dataIn);void mcp2515_reset(void);void mcp2515_read_rx_buf(mcp2515_rx_t channel, mcp2515_can_frame_t *canData);void mcp2515_load_tx_buf(uint8_t nBuf, mcp2515_can_frame_t *canData);void mcp2515_rts(uint8_t nBuf);void mcp2515_read_rxtx_status(uint8_t* canRxTxStatus);void mcp2515_rx_status(uint8_t* canRxStatus);void mcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_t regAddr, uint32_t canID, uint8_t ext);int mcp2515_get_int_flag(void);
void mcp2515_clear_interrupt(void);void mcp2515_set_op_mode(mcp2515_op_mode_t mode);void mcp2515_set_rx_op_mode(mcp2515_rx_t channel, mcp2515_rx_op_mode_t mode);void mcp2515_enable_rx_int(mcp2515_rx_t channel);
void mcp2515_enable_tx_int(mcp2515_tx_t channel);static void (*mcp2515_spi_select)(void);
static void (*mcp2515_spi_unselect)(void);
//static void (*mcp2515_spi_transfer)(uint8_t ubDataOut, uint8_t *pubDataIn);
static void (*mcp2515_spi_transfer)(uint8_t tdata, uint8_t *prdata);void mcp2515_chn_select(uint8_t chn)
{switch(chn){case MCP2515_SPIA:mcp2515_spi_select = spi_select_spia;mcp2515_spi_unselect = spi_unselect_spia;mcp2515_spi_transfer = spi_transfer_spia;break;case MCP2515_SPIB:mcp2515_spi_select = spi_select_spib;mcp2515_spi_unselect = spi_unselect_spib;mcp2515_spi_transfer = spi_transfer_spib;break; case MCP2515_SPIC:mcp2515_spi_select = spi_select_spic;mcp2515_spi_unselect = spi_unselect_spic;mcp2515_spi_transfer = spi_transfer_spic;break;case MCP2515_SPID:mcp2515_spi_select = spi_select_spid;mcp2515_spi_unselect = spi_unselect_spid;mcp2515_spi_transfer = spi_transfer_spid;break;case MCP2515_DBG:mcp2515_spi_select = spi_select_spic;mcp2515_spi_unselect = spi_unselect_spic;mcp2515_spi_transfer = spi_dbg_transfer;break;   default :break;}
}void mcp2515_spi_port_init(void)
{mcp2515_status_init();mcp2515_cs_init();mcp2515_en_init();
}#if 0
void mcp2515_spi_select(void){}
void mcp2515_spi_unselect(void){}void mcp2515_spi_transfer(uint8_t ubDataOut, uint8_t *pubDataIn)
{/*SPDR = ubDataOut;loop_until_bit_is_set(SPSR, SPIF);if (pubDataIn != (void*) 0){*pubDataIn = SPDR;}else{uint8_t tmp;tmp = SPDR;}*/
}
#endif
static void id_read(uint32_t *canID)
{uint8_t dataIn;volatile uint32_t uwID = 0;mcp2515_spi_transfer(0, &dataIn);//read XXXnSIDHuwID = (((uint32_t)dataIn) << 21);mcp2515_spi_transfer(0, &dataIn);//read XXXnSIDLuwID |= ( ((uint32_t)(dataIn & 0xE0)) << 13);uwID |= ( ((uint32_t)(dataIn & 0x03)) << 16);if (dataIn & 0x08) //Ext. ID? (bit mask on bit3)uwID |= 0x80000000;mcp2515_spi_transfer(0, &dataIn);//read XXXnEID8uwID |= (((uint32_t)dataIn) << 8);mcp2515_spi_transfer(0, &dataIn);//read XXXnEID0uwID |= (uint32_t)dataIn;*canID = uwID;
}static void id_write(uint32_t canID)
{uint8_t ubtempo = 0;mcp2515_spi_transfer((uint8_t) (canID >> 21), NULL);//send XXXnSIDHubtempo = ( (uint8_t)(canID >> 13) ) & 0xE0;ubtempo |= ( (uint8_t)(canID >> 16) ) & 0x03;if (canID & 0x80000000)//Ext. ID?ubtempo |= 0x08;mcp2515_spi_transfer(ubtempo, NULL);//send XXXnSIDLmcp2515_spi_transfer((uint8_t) (canID >> 8), NULL);//Send XXXnEID8mcp2515_spi_transfer((uint8_t) canID, NULL);//Send XXXnEID0
}void read(uint8_t regAddr, uint8_t *dataAddr)
{ASSERT(dataAddr != 0);mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_READ, NULL);mcp2515_spi_transfer(regAddr, NULL);mcp2515_spi_transfer(0, dataAddr);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void write(uint8_t regAddr, uint8_t data)
{mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_WRITE, NULL);mcp2515_spi_transfer(regAddr, NULL);mcp2515_spi_transfer(data, NULL);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}#if 0
static void write_bust(uint8_t regAddr, uint8_t *dataAddr, uint8_t size)
{uint8_t i;ASSERT(dataAddr != NULL);mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_WRITE, NULL);mcp2515_spi_transfer(regAddr, NULL);for (i=0; i < size; i++)mcp2515_spi_transfer(dataAddr[i], NULL);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}static void read_bust(uint8_t regAddr, uint8_t *dataAddr, uint8_t size)
{uint8_t i;ASSERT((dataAddr != NULL) && (size != 0));mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_READ, NULL);mcp2515_spi_transfer(regAddr, NULL);for (i=0; i <= size; i++)mcp2515_spi_transfer(0, dataAddr++);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}
#endifstatic void bit_modify(uint8_t regAddr, uint8_t bitMask, uint8_t val)
{mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_BIT_MODIFY, NULL);mcp2515_spi_transfer(regAddr, NULL);mcp2515_spi_transfer(bitMask, NULL);mcp2515_spi_transfer(val, NULL);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void mcp2515_reset(void)
{mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_RESET, NULL);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void mcp2515_read_rx_buf(mcp2515_rx_t channel, mcp2515_can_frame_t *canData)
{uint8_t i;ASSERT(canData != NULL);mcp2515_spi_select();//Select the MCP2515 on the SPI busswitch (channel){case mcp2515_rx_0:mcp2515_spi_transfer(MCP2515_READ_BUF_RXB0SIDH, NULL);break;case mcp2515_rx_1:mcp2515_spi_transfer(MCP2515_READ_BUF_RXB1SIDH, NULL);break;default:ASSERT(0);break;}id_read(&canData->id);// add by fzif(canData->id & 0x80000000UL){canData->ext = 1;canData->id &= 0x1FFFFFFF;}else{canData->ext = 0;canData->id &= 0x1FFFFFFF;canData->id >>= 18;}mcp2515_spi_transfer(0, &canData->dlc);//read DLCcanData->dlc &= 0x0F;for (i = 0; i < canData->dlc; i++){mcp2515_spi_transfer(0, &canData->data[i]);}mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void mcp2515_load_tx_buf(uint8_t nBuf, mcp2515_can_frame_t *canData)
{uint8_t i;ASSERT(canData != NULL);switch (nBuf){case MCP2515_TX_BUF_0:mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_LOAD_BUF_TXB0SIDH, NULL);break;case MCP2515_TX_BUF_1:mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_LOAD_BUF_TXB1SIDH, NULL);break;case MCP2515_TX_BUF_2:mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_LOAD_BUF_TXB2SIDH, NULL);break;default:ASSERT(0);//break;}// add by fzif(canData->ext){canData->id |= 0x80000000UL;}else{canData->id &= ~0x80000000UL;canData->id <<= 18;}id_write(canData->id);mcp2515_spi_transfer(canData->dlc & 0x0F, NULL);for (i = 0; (i < canData->dlc) && (i < MCP2515_MAX_BYTE_CANFRM); i++){mcp2515_spi_transfer(canData->data[i], NULL);}mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void mcp2515_rts(uint8_t nBuf)
{//uint8_t ubRetVal = SPI_OK;//uint8_t dataIn;mcp2515_spi_select();//Select the MCP2515 on the SPI busswitch (nBuf){case MCP2515_TX_BUF_0://mcp2515_spi_transfer(MCP2515_RTS_TXB0, &dataIn);mcp2515_spi_transfer(MCP2515_RTS_TXB0, NULL);break;case MCP2515_TX_BUF_1://mcp2515_spi_transfer(MCP2515_RTS_TXB1, &dataIn);mcp2515_spi_transfer(MCP2515_RTS_TXB1, NULL);break;case MCP2515_TX_BUF_2://mcp2515_spi_transfer(MCP2515_RTS_TXB2, &dataIn);mcp2515_spi_transfer(MCP2515_RTS_TXB2, NULL);break;default:ASSERT(0);//break;}mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void mcp2515_read_rxtx_status(uint8_t* canRxTxStatus)
{ASSERT(canRxTxStatus != NULL);mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_READ_RXTX_STATUS, NULL);mcp2515_spi_transfer(0, canRxTxStatus);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void mcp2515_rx_status(uint8_t* canRxStatus)
{ASSERT(canRxStatus != NULL);mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_RX_STATUS, NULL);mcp2515_spi_transfer(0, canRxStatus);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void mcp2515_clear_interrupt(void)
{mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_WRITE, NULL);mcp2515_spi_transfer(MCP2515_CANINTF, NULL);mcp2515_spi_transfer(0, NULL);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}void mcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_t regAddr, uint32_t canID, uint8_t ext)
{if(ext){canID |= 0x80000000UL;}else{canID &= ~0x80000000UL;canID <<= 18;}mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_WRITE, NULL);mcp2515_spi_transfer((uint8_t)regAddr, NULL);id_write(canID);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus
}int mcp2515_get_int_flag(void)
{uint8_t value;mcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_READ, NULL);mcp2515_spi_transfer(MCP2515_CANINTF, NULL);mcp2515_spi_transfer(0, &value);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI busreturn (int)value;
}void mcp2515_set_op_mode(mcp2515_op_mode_t mode)
{bit_modify(MCP2515_CANCTRL, 0xE0, mode<<5);
}void mcp2515_set_rx_op_mode(mcp2515_rx_t channel, mcp2515_rx_op_mode_t mode)
{switch(channel){case mcp2515_rx_0:bit_modify(MCP2515_RXB0CTRL, 0x60, mode<<5);break;case mcp2515_rx_1:bit_modify(MCP2515_RXB1CTRL, 0x60, mode<<5);break;default:ASSERT(0);break;}
}void mcp2515_enable_rx_int(mcp2515_rx_t channel)
{switch(channel){case mcp2515_rx_0:bit_modify(MCP2515_CANINTE, 0x01, 0x01);break;case mcp2515_rx_1:bit_modify(MCP2515_CANINTE, 0x02, 0x02);break;default:ASSERT(0);break;}
}void mcp2515_enable_tx_int(mcp2515_tx_t channel)
{switch(channel){case mcp2515_tx_0:bit_modify(MCP2515_CANINTE, 0x04, 0x04);break;case mcp2515_tx_1:bit_modify(MCP2515_CANINTE, 0x08, 0x08);break;case mcp2515_tx_2:bit_modify(MCP2515_CANINTE, 0x10, 0x10);break;default:ASSERT(0);break;}
}
/* ---- Beispiel zum Einstellen des Bit Timings ----*   *   Fosc        = 16MHz*   BRP         = 1*   TQ          = 2 * (BRP + 1) / Fosc*               = 1/4 uS** Sync Seg    =                  = 1 TQ*    Prop Seg    = (PRSEG + 1) * TQ    = 5 TQ*    Phase Seg1  = (PHSEG1 + 1) * TQ   = 6 TQ*    Phase Seg2  = (PHSEG2 + 1) * TQ = 4 TQ*                                  --------*                                     16 TQ*    *   Bus speed   = 1 / ((Total # of TQ) * TQ)*              = 1 / (4 * TQ) = 250 kHz// 250 kbps{  0x03, // CNF30xac, // CNF20x81  // CNF1},// 500 kbps{   0x03,0xac,0x80},*/
int mcp2515_set_baudrate(uint8_t bdr)
{Uint16 tmp = 0xFF; #if 0static uint8_t prs, phs1, phs2, BRP, sjw;if(bdr == CAN_BAUD_250K){BRP = 1;prs = 4;phs1 = 5;phs2 = 3;sjw = 2;}else{BRP = 0;prs = 4;phs1 = 5;phs2 = 3;sjw = 2;}//SET ALL THE REGISTER OF THE MCP 2515 FOR THE DESIRED BAUD RATEmcp2515_spi_select();//Select the MCP2515 on the SPI busmcp2515_spi_transfer(MCP2515_WRITE, NULL);mcp2515_spi_transfer(MCP2515_CNF3, NULL);mcp2515_spi_transfer(phs2, NULL);//CF3mcp2515_spi_transfer(prs|(phs1<<3)|0x80, NULL);//CF2//CF1 : 1TQ for SJW and BRP = 5 for 1TQ = 12/F_CPUmcp2515_spi_transfer((sjw<<6)|BRP, NULL);mcp2515_spi_unselect();//Unselect the MCP2515 on the SPI bus#elsewrite(MCP2515_CNF1, 0x81);write(MCP2515_CNF2, 0xAC);write(MCP2515_CNF3, 0x03);read(MCP2515_CNF1, &tmp);if(tmp != 0x81){return 1; // err!}#endifreturn 0;
}int16 mcp2515_sendmsg(struct canfd_frame *cf)
{cf->id = 0x1807E5F4;cf->ext = 1;mcp2515_load_tx_buf(MCP2515_TX_BUF_0, cf);mcp2515_rts(MCP2515_TX_BUF_0);return SUCCESS;
}int16 mcp2515_recvmsg(struct canfd_frame *cf)
{Uint16 status;#if USE_INT_STATif(mcp2515_spi_transfer == spi_transfer_spia){if(mcpa_int_stat())return FAILURE;}else if(mcp2515_spi_transfer == spi_transfer_spib){if(mcpb_int_stat())return FAILURE;}else if(mcp2515_spi_transfer == spi_transfer_spic){if(mcpc_int_stat())return FAILURE;}else if(mcp2515_spi_transfer == spi_transfer_spid){if(mcpd_int_stat())return FAILURE;}else{if(mcpc_int_stat())return FAILURE;}#elsemcp2515_read_rxtx_status(&status);if((status&0x01) != 0x01) return FAILURE;#endifmcp2515_read_rx_buf(mcp2515_rx_0, cf);return SUCCESS;
}
/*
int16 send_data_spia(struct canfd_frame *cf, Uint16 noblock)
{mcp2515_chn_select(MCP2515_SPIA);return mcp2515_sendmsg(cf);
}int16 recv_data_spia(struct canfd_frame *cf, Uint16 noblock)
{mcp2515_chn_select(MCP2515_SPIA);return mcp2515_recvmsg(cf);
}
*/
Uint16 mcp2515_init(uint32_t canID, uint8_t ext)
{Uint16 err = 0;//mcp2515_spi_port_init();mcp2515_reset();DELAY_US(1000); // 1mswrite(MCP2515_CANCTRL, 0);mcp2515_set_op_mode(mcp2515_op_mode_config);write(MCP2515_TXRTSCTRL, 0); // disable TXnRTSwrite(MCP2515_BFPCTRL, 0);   // disable RxnBF#if USE_INT_STATwrite(MCP2515_CANINTE, MCP2515_CANINT_RX0I); // RX0 interrupt enable
#elsewrite(MCP2515_CANINTE, 0);
#endifwrite(MCP2515_RXB0CTRL, 0x60); // receive any message, Rollover disavle//mcp2515_set_rx_op_mode(mcp2515_rx_0, mcp2515_rx_op_mode_any);err = mcp2515_set_baudrate(CAN_BAUD_RATE);bit_modify(MCP2515_CANCTRL, 0x08, 1<<3); // one shot modemcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXM0, 0x1FFFFFFF, ext);//mcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXM1, 0x1FFFFFFF, 0);//mcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXM0, 0x00000000, 0);//mcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXM1, 0x00000000, 0);mcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXF0, canID, ext);mcp2515_set_rx_op_mode(mcp2515_rx_0, mcp2515_rx_op_mode_filter_any);//mcp2515_set_rx_op_mode(mcp2515_rx_1, mcp2515_rx_op_mode_filter_any);//write(MCP2515_RXB0CTRL, 0);mcp2515_set_op_mode(mcp2515_op_mode_normal); return err;
}/*
void mcp2515_init_ext(uint32_t canID, uint32_t mask, uint8_t ext)
{mcp2515_set_op_mode(mcp2515_op_mode_config);write(MCP2515_RXB1CTRL, 0x62); // receive any message, Rollover disavlemcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXM1, mask, ext);mcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXF2, canID, ext);mcp2515_set_rx_op_mode(mcp2515_rx_1, mcp2515_rx_op_mode_filter_any);mcp2515_set_op_mode(mcp2515_op_mode_normal);
}
*/
void mcp2515_init_ext(uint32_t canID1, uint32_t canID2, uint8_t ext)
{uint32_t mask = ~(canID1 ^ canID2) & 0x1FFFFFFF;//uint32_t mask = 0x00;mcp2515_set_op_mode(mcp2515_op_mode_config);write(MCP2515_RXB1CTRL, 0x62); // receive any message, Rollover disavlemcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXM1, mask, ext);mcp2515_set_rx_filter_mask(mcp2515_rx_filter_mask_RXF2, canID1, ext);//mcp2515_set_rx_op_mode(mcp2515_rx_1, mcp2515_rx_op_mode_filter_any);mcp2515_set_rx_op_mode(mcp2515_rx_1, mcp2515_rx_op_mode_any);mcp2515_set_op_mode(mcp2515_op_mode_normal);
}int16 mcp2515_sendext(struct canfd_frame *cf)
{mcp2515_load_tx_buf(MCP2515_TX_BUF_1, cf);mcp2515_rts(MCP2515_TX_BUF_1);return SUCCESS;
}int16 mcp2515_recvext(struct canfd_frame *cf)
{Uint16 status;mcp2515_read_rxtx_status(&status);if((status&0x02) != 0x02) return FAILURE;mcp2515_read_rx_buf(mcp2515_rx_1, cf);return SUCCESS;
}
void spi_transfer_spia(Uint16 tdata, Uint16 *prdata)
{spi_transfer_chn(tdata, prdata, &SpiaRegs);
}
void spi_transfer_chn(Uint16 tdata, Uint16 *prdata, volatile struct SPI_REGS *pREGS)
{Uint16 tx = DUMMY_BYTE, rx = DUMMY_BYTE;if(prdata == NULL) tx = tdata;pREGS->SPITXBUF = tx << 8; // dummy writewhile(pREGS->SPISTS.bit.INT_FLAG != 1);// Check against sent datarx = pREGS->SPIRXBUF; // right-justifiedif(prdata != NULL) *prdata = rx;
}

给大家提供一个思路,在遇到相同的问题是可以减少码农的工作负担~~

MCP2515 驱动程序相关推荐

  1. MCP2515驱动程序

    下载链接https://download.csdn.net/download/y1757655788/13197815   STM32芯片内部已有1个或2个CAN控制器,但是在有些情况下两个CAN控制 ...

  2. SPI转can芯片mcp2515

    开发环境 CPU:RK3399 ARCH: aarch64 KERNEL:Linux4.4 OS:ubuntu18.04 mcp2515芯片相关信息 CAN.SPI接口控制电路图 修改设备树文件 文件 ...

  3. atlas 200移植mcp2515

    mcp2515是spi接入的模块 淘宝买的can小板子,直接通过spi飞线到atlas 200的单板 1.首先需要配置spi复用 2.配置内核 3.配置设备树 调试问题: 第一个问题 重新编译dtb文 ...

  4. Android评分栏示例

    在Android中,您可以使用" android.widget.RatingBar "以星号图标显示评分栏组件. 用户可以触摸,拖动或单击星号以轻松设置评级值. 在本教程中,我们向 ...

  5. Spi cp2515 linux,基于MCP2515的Linux CAN总线驱动程序设计

    图3 MCP2515硬件连接图 5.MCP2515 Socket CAN驱动实现 FS2416平台使用Linux2.6.39的内核,内核中为MCP2515提供了Socket CAN驱动程序,我们只需为 ...

  6. OpenGL在图形管道中调用了什么用户模式图形驱动程序(UMD)?

    OpenGL在图形管道中调用了什么用户模式图形驱动程序(UMD)? 图形硬件供应商,需要为显示适配器编,编写用户模式显示驱动程序.用户模式显示驱动程序,是由Microsoft Direct3D运行时加 ...

  7. 嵌入式Linux设备驱动程序:在运行时读取驱动程序状态

    嵌入式Linux设备驱动程序:在运行时读取驱动程序状态 Embedded Linux device drivers: Reading driver state at runtime 在运行时了解驱动程 ...

  8. 嵌入式Linux设备驱动程序:用户空间中的设备驱动程序

    嵌入式Linux设备驱动程序:用户空间中的设备驱动程序 Embedded Linux device drivers: Device drivers in user space Interfacing ...

  9. 嵌入式Linux设备驱动程序:发现硬件配置

    嵌入式Linux设备驱动程序:发现硬件配置 Embedded Linux device drivers: Discovering the hardware configuration Interfac ...

最新文章

  1. python中execute函数_Python 中的内置函数与模块
  2. android 命令启动服务,adb 命令
  3. 用python函数画德国国旗代码_python海龟绘图之画国旗实例代码
  4. mac笔记本怎么外接显示屏_苹果MAC笔记本怎么外接显示器?
  5. 专家预测第二波WannaCry勒索病毒攻击即将到来!
  6. linux 下使用 curl post
  7. sap相关性不能被编译_经典综述编译丨生物硝化抑制丨NAT PLANTS:现代农业中的氮转化和生物硝化抑制作用...
  8. 【开源GPS追踪】 之 服务器端opengts安装
  9. JavaScript数组的某些操作(一)
  10. 信创只是开始_一切只是开始!谁是下一个“第一创业”?
  11. SQLServer2008R2密钥
  12. python职场应用英语作文_春考关于职场应用的英语作文
  13. WinDbg实践--入门篇
  14. 前端三剑客 HTML、CSS、JavaScript 入门到上手
  15. Invalid Java package name: '1' is not a valid Java identifier eclipse创建sevlet时,无法创建
  16. 常见点击反应(Click Reactions)及其试剂——CuAAC
  17. java将汉字转成拼音首字母大写字母_Java 将汉字转换为拼音并取首字母大写
  18. VS2008上安装64位编译器工具
  19. 反向恢复时间trr的影响
  20. 分享武汉大学李征航老师的《GPS原理与应用》

热门文章

  1. 解决66版本后Chrome浏览器无法安装插件的问题
  2. Vivado中FFT9.1 IP核的使用(1)
  3. C语言头文件和源文件差异,#include两种引用方式差异
  4. 详解:IP地址132.119.100.200的子网掩码是255.255.255.240,那么它所在子网的广播地址是(132.119.100.207)
  5. 计算机电子电路原理图,电子电路图 如何看懂电子电路图 凡亿教你如何看懂电路图...
  6. 全国计算机等级考试三级数据库技术-知识点汇总
  7. SRTP RFC 3711
  8. 不容错过 产品发布ppt模板素材推荐
  9. 百度百科词条创建技巧及经验之谈,如何顺利创建百科
  10. 一顿饭的事儿,搞懂了Linux5种IO模型