最新动态

工业物联网通讯专家!
认真做好每一件事,设计简单、可靠、价格合理的产品!

MCP2515 程序库 CAN收发器芯片 经验证可用

MCP2515 程序库 CAN收发器芯片 经验证可用,提供MCP2515控制寄存器和初始化等函数。

C程序代码

/*============================================================         C file about MCP2515   V1.00 ============================================================== Chip:      MCP2515 Function:    The controller of CAN-BUS Writer:     Fenghui Zhu Data:      2009.3.31 Reference:   "mcp2515.c" of Fabian Greif =============================================================*/

//********************* //* 头 文 件 配 置 区 * //********************* #include "mcp2515.h"

//********************** //*   函 数 声 明 区   * //**********************

void mcp2515_init(void);

void mcp2515_write_register(u08 data, u08 adress);

u08 mcp2515_read_register(u08 adress);

void mcp2515_bit_modify(u08 data, u08 mask, u08 adress);

void mcp2515_write_register_p( u08 adress, u08 *data, u08 length );

//********************** //*   函 数 定 义 区   * //**********************

//**********************************************************// //   函数说明:MCP2515初始化程序                            // //   输入:    无                                   // //   输出:    无                                          // //   调用函数:                                  // //**********************************************************// void mcp2515_init(void) {  //初始化MCU的SPI总线  //SPI_MasterInit();    // MCP2515 启动前进行软件复位  SPI_PORT &= ~(1<<SPI_CS);  //MCP2515的CS有效  SPI_MasterTransmit( SPI_RESET );  SPI_PORT |= (1<<SPI_CS);  //MCP2515的CS无效    //使用位修改指令将MCP2515设置为配置模式  //也就是将CANCTRL寄存器的REQOP[2:0]设置为100  mcp2515_bit_modify( CANCTRL, 0xE0, (1<<REQOP2) );    /*  //计算并设置MCP2515的位时间    // 时钟频率:Fosc  = 16MHz  // 分频控制器 CNF1.BRP[5:0] = 7  // 最小时间份额 TQ = 2 * ( BRP + 1 ) / Fosc   = 2*(7+1)/16M = 1uS  // 同步段 Sync Seg   = 1TQ  // 传播段 Prop Seg   = ( PRSEG + 1 ) * TQ  = 1 TQ  // 相位缓冲段 Phase Seg1 = ( PHSEG1 + 1 ) * TQ = 3 TQ  // 相位缓冲段 Phase Seg2 = ( PHSEG2 + 1 ) * TQ = 3 TQ  // 同步跳转长度设置为 CNF1.SJW[1:0] = 00, 即 1TQ  // 总线波特率 NBR = Fbit =  1/(sync seg + Prop seg + PS1 + PS2 )  //                       = 1/(8TQ) = 1/8uS = 125kHz    //设置分频控制器CNF1.BRP[5:0] = 7,同步跳转长度设置为 CNF1.SJW[1:0] = 00  mcp2515_write_register( CNF1, (1<<BRP0)|(1<<BRP1)|(1<<BRP2) );  // 设置传播段 Prop Seg 为00,即1TQ,相位缓冲段 Phase Seg1的长度3TQ  mcp2515_write_register( CNF2, (1<<BTLMODE)|(1<<PHSEG11) );  // 设置 相位缓冲段 Phase Seg2为 3TQ , 禁用唤醒滤波器  mcp2515_write_register( CNF3, (1<<PHSEG21) );    */    //设置为500kbps ,TQ = 1/8us  //设置分频控制器CNF1.BRP[5:0] = 0,同步跳转长度设置为 CNF1.SJW[1:0] = 01 // mcp2515_write_register( CNF1, (1<<BRP0)|(1<<SJW0) );    // 500kbps  mcp2515_write_register( CNF1, (1<<SJW0) );               //1Mbps   // 设置传播段 Prop Seg 为00,即1TQ,相位缓冲段 Phase Seg1的长度3TQ  mcp2515_write_register( CNF2, (1<<BTLMODE)|(1<<PHSEG11) );  // 设置 相位缓冲段 Phase Seg2为 3TQ , 禁用唤醒滤波器  mcp2515_write_register( CNF3, (1<<PHSEG21) );      // 设置MCP2515中断使能寄存器,禁用所有中断 // mcp2515_write_register( CANINTE, /*(1<<RX1IE)|(1<<RX0IE)*/ 0 );    // 设置MCP2515中断使能寄存器,使能接收缓冲器中断  mcp2515_write_register( CANINTE, (1<<RX1IE)|(1<<RX0IE) );  

 //设置数据接收相关寄存器     // 设置RXM[1:0]=11,关闭接收缓冲器0屏蔽/滤波功能,接收所有报文;禁止滚存功能  mcp2515_write_register( RXB0CTRL, (1<<RXM1)|(1<<RXM0) );    // 设置RXM[1:0]=11,关闭接收缓冲器1屏蔽/滤波功能,接收所有报文;  mcp2515_write_register( RXB1CTRL, (1<<RXM1)|(1<<RXM0) );

 u08 temp[4] = { 0, 0, 0, 0 };    //设置6个验收滤波寄存器为0,  mcp2515_write_register_p( RXF0SIDH, temp, 4 );  mcp2515_write_register_p( RXF1SIDH, temp, 4 );  mcp2515_write_register_p( RXF2SIDH, temp, 4 );  mcp2515_write_register_p( RXF3SIDH, temp, 4 );  mcp2515_write_register_p( RXF4SIDH, temp, 4 );  mcp2515_write_register_p( RXF5SIDH, temp, 4 );    //设置2个验收滤波寄存器为0,  mcp2515_write_register_p( RXM0SIDH, temp, 4 );  mcp2515_write_register_p( RXM1SIDH, temp, 4 );    //配置引脚  //设置接收相关引脚控制寄存器,配置它们禁用第二功能  mcp2515_write_register( BFPCTRL, 0 );    //调试使用,设置BFPCTRL使RX0BF,RX1BF设置为数字输出。  //mcp2515_bit_modify( BFPCTRL, (1<<B1BFE)|(1<<B0BFE)|(1<<B1BFM)|(1<<B0BFM), (1<<B1BFE)|(1<<B0BFE) );      //设置发送相关引脚控制寄存器,配置它们禁用第二功能  mcp2515_write_register( TXRTSCTRL, 0 );    //MCP2515进入环回模式,进行功能测试  //mcp2515_bit_modify( CANCTRL, 0XE0, (1<<REQOP1) );    //MCP2515进入正常模式  mcp2515_bit_modify( CANCTRL, 0xE0, 0); }

//**********************************************************// //   函数说明:MCP2515写控制寄存器程序                      // //   输入:    寄存器地址,写入数据                         // //   输出:    无                                          // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************//

void mcp2515_write_register( u08 adress, u08 data ) {  // CS low ,MCP2515 enable  SPI_PORT &= ~(1<<SPI_CS);    SPI_MasterTransmit(SPI_WRITE); // 发送SPI写寄存器控制字    SPI_MasterTransmit(adress);  //发送寄存器地址    SPI_MasterTransmit(data);   //发送寄存器数据    //CS high ,MCP2515 disable  SPI_PORT |= (1<<SPI_CS); }

//**********************************************************// //   函数说明:MCP2515读控制寄存器程序                      // //   输入:    寄存器地址,                             // //   输出:    寄存器数据                                  // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************//

u08 mcp2515_read_register(u08 adress) {  u08 data;    // CS low ,MCP2515 enable  SPI_PORT &= ~(1<<SPI_CS);    SPI_MasterTransmit(SPI_READ); // 发送SPI写寄存器控制字    SPI_MasterTransmit(adress); //发送寄存器地址    data = SPI_MasterTransmit(0xff); //回读寄存器数据    //CS high ,MCP2515 disable  SPI_PORT |= (1<<SPI_CS);    return data; }

//**********************************************************// //   函数说明:读MCP2515接收缓冲器程序                      // //   输入:    缓冲器地址,                             // //   输出:    缓冲器数据                                  // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************//

u08 mcp2515_read_rx_buffer(u08 adress) {  u08 data;    // 判断adress是否有效,除了1,2位,其余都应为0  if (adress & 0xF9)   return 0;    // CS low ,MCP2515 enable  SPI_PORT &= ~(1<<SPI_CS);    SPI_MasterTransmit(SPI_READ_RX | adress); //发送读取控制字    data = SPI_MasterTransmit(0xff); //读回数据   //CS high ,MCP2515 disable  SPI_PORT |= (1<<SPI_CS);    return data; }

//**********************************************************// //   函数说明:MCP2515控制寄存器位修改程序                // //   输入:    寄存器地址,修改位,修改数据                // //   输出:    无                                      // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************//

void mcp2515_bit_modify(u08 adress, u08 mask, u08 data) {  // CS low ,MCP2515 enable  SPI_PORT &= ~(1<<SPI_CS);    SPI_MasterTransmit(SPI_BIT_MODIFY); //SPI位修改指令    SPI_MasterTransmit(adress);    //发送寄存器地址    SPI_MasterTransmit(mask);     //发送屏蔽字节,                   //屏蔽字节中“1”表示允许对相应位修改,“0”表示禁止修改  SPI_MasterTransmit(data);     //发送数据字节   //CS high ,MCP2515 disable  SPI_PORT |= (1<<SPI_CS); }

//**********************************************************// //   函数说明:对MCP2515连续寄存器进行连续写操作            // //   输入:    连续寄存器起始地址,数据指针,数据长度      // //   输出:    无                                      // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************// void mcp2515_write_register_p( u08 adress, u08 *data, u08 length ) {  u08 i;    // CS low ,MCP2515 enable  SPI_PORT &= ~(1<<SPI_CS);    SPI_MasterTransmit(SPI_WRITE);  //发送SPI写指令    SPI_MasterTransmit(adress);    //发送起始寄存器地址    for (i=0; i<length ;i++ )   SPI_MasterTransmit(*data++);  //发送数据    //CS high ,MCP2515 disable  SPI_PORT |= (1<<SPI_CS); }

//**********************************************************// //   函数说明:对MCP2515连续寄存器进行连续读操作            // //   输入:    连续寄存器起始地址,数据指针,数据长度      // //   输出:    无                                      // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************// void mcp2515_read_register_p( u08 adress, u08 *data, u08 length ) {  u08 i;    // CS low ,MCP2515 enable  SPI_PORT &= ~(1<<SPI_CS);    SPI_MasterTransmit(SPI_READ);  //发送SPI读指令    SPI_MasterTransmit(adress);   //发送起始寄存器地址    for (i=0; i<length ;i++ )   *data++ = SPI_MasterTransmit(0xff);  //数据保存    //CS high ,MCP2515 disable  SPI_PORT |= (1<<SPI_CS); }

头文件:

/*============================================================         Headfile about MCP2515   V1.00 ============================================================== Chip:      MCP2515 Function:    The controller of CAN-BUS Writer:     Fenghui Zhu Data:      2009-3-31 Reference:   "mcp2515.h" of Fabian Greif =============================================================*/

#ifndef _MCP2515_H_ #define _MCP2515_H_

//********************* //* 用户类型定义区    * //*********************

//********************* //* 头 文 件 配 置 区 * //********************* #include "Habit_Frank.h" #include "SPI_Ctrl.h" //******************** //*  系 统 宏 定 义  * //********************

// 定义寄存器地址 #define RXF0SIDH 0x00 #define RXF0SIDL 0x01 #define RXF0EID8 0x02 #define RXF0EID0 0x03 #define RXF1SIDH 0x04 #define RXF1SIDL 0x05 #define RXF1EID8 0x06 #define RXF1EID0 0x07 #define RXF2SIDH 0x08 #define RXF2SIDL 0x09 #define RXF2EID8 0x0A #define RXF2EID0 0x0B #define BFPCTRL  0x0C #define TXRTSCTRL 0x0D #define CANSTAT  0x0E #define CANCTRL  0x0F

#define RXF3SIDH 0x10 #define RXF3SIDL 0x11 #define RXF3EID8 0x12 #define RXF3EID0 0x13 #define RXF4SIDH 0x14 #define RXF4SIDL 0x15 #define RXF4EID8 0x16 #define RXF4EID0 0x17 #define RXF5SIDH 0x18 #define RXF5SIDL 0x19 #define RXF5EID8 0x1A #define RXF5EID0 0x1B #define TEC    0x1C #define REC       0x1D

#define RXM0SIDH 0x20 #define RXM0SIDL 0x21 #define RXM0EID8 0x22 #define RXM0EID0 0x23 #define RXM1SIDH 0x24 #define RXM1SIDL 0x25 #define RXM1EID8 0x26 #define RXM1EID0 0x27 #define CNF3   0x28 #define CNF2   0x29 #define CNF1   0x2A #define CANINTE  0x2B #define CANINTF  0x2C #define EFLG   0x2D

#define TXB0CTRL 0x30 #define TXB0SIDH 0x31 #define TXB0SIDL 0x32 #define TXB0EID8 0x33 #define TXB0EID0 0x34 #define TXB0DLC  0x35 #define TXB0D0  0x36 #define TXB0D1  0x37 #define TXB0D2  0x38 #define TXB0D3  0x39 #define TXB0D4  0x3A #define TXB0D5  0x3B #define TXB0D6  0x3C #define TXB0D7  0x3D

#define TXB1CTRL 0x40 #define TXB1SIDH 0x41 #define TXB1SIDL 0x42 #define TXB1EID8 0x43 #define TXB1EID0 0x44 #define TXB1DLC  0x45 #define TXB1D0  0x46 #define TXB1D1  0x47 #define TXB1D2  0x48 #define TXB1D3  0x49 #define TXB1D4  0x4A #define TXB1D5  0x4B #define TXB1D6  0x4C #define TXB1D7  0x4D

#define TXB2CTRL 0x50 #define TXB2SIDH 0x51 #define TXB2SIDL 0x52 #define TXB2EID8 0x53 #define TXB2EID0 0x54 #define TXB2DLC  0x55 #define TXB2D0  0x56 #define TXB2D1  0x57 #define TXB2D2  0x58 #define TXB2D3  0x59 #define TXB2D4  0x5A #define TXB2D5  0x5B #define TXB2D6  0x5C #define TXB2D7  0x5D

#define RXB0CTRL 0x60 #define RXB0SIDH 0x61 #define RXB0SIDL 0x62 #define RXB0EID8 0x63 #define RXB0EID0 0x64 #define RXB0DLC  0x65 #define RXB0D0  0x66 #define RXB0D1  0x67 #define RXB0D2  0x68 #define RXB0D3  0x69 #define RXB0D4  0x6A #define RXB0D5  0x6B #define RXB0D6  0x6C #define RXB0D7  0x6D

#define RXB1CTRL 0x70 #define RXB1SIDH 0x71 #define RXB1SIDL 0x72 #define RXB1EID8 0x73 #define RXB1EID0 0x74 #define RXB1DLC  0x75 #define RXB1D0  0x76 #define RXB1D1  0x77 #define RXB1D2  0x78 #define RXB1D3  0x79 #define RXB1D4  0x7A #define RXB1D5  0x7B #define RXB1D6  0x7C #define RXB1D7  0x7D

//定义寄存器BFPCTRL位信息 #define B1BFS  5 #define B0BFS  4 #define B1BFE  3 #define B0BFE  2 #define B1BFM  1 #define B0BFM  0

//定义寄存器TXRTSCTRL位信息 #define B2RTS  5 #define B1RTS  4 #define B0RTS  3 #define B2RTSM  2 #define B1RTSM  1 #define B0RTSM  0

//定义寄存器CANSTAT位信息 #define OPMOD2  7 #define OPMOD1  6 #define OPMOD0  5 #define ICOD2  3 #define ICOD1  2 #define ICOD0  1

//定义寄存器CANCTRL位信息 #define REQOP2  7 #define REQOP1  6 #define REQOP0  5 #define ABAT  4 #define CLKEN  2 #define CLKPRE1  1 #define CLKPRE0  0

 //定义寄存器CNF3位信息 #define WAKFIL  6 #define PHSEG22  2 #define PHSEG21  1 #define PHSEG20  0

 //定义寄存器CNF2位信息 #define BTLMODE  7 #define SAM   6 #define PHSEG12  5 #define PHSEG11  4 #define PHSEG10  3 #define PHSEG2  2 #define PHSEG1  1 #define PHSEG0  0

 //定义寄存器CNF1位信息 #define SJW1  7 #define SJW0  6 #define BRP5  5 #define BRP4  4 #define BRP3  3 #define BRP2  2 #define BRP1  1 #define BRP0  0

 //定义寄存器CANINTE位信息 #define MERRE  7 #define WAKIE  6 #define ERRIE  5 #define TX2IE  4 #define TX1IE  3 #define TX0IE  2 #define RX1IE  1 #define RX0IE  0

 //定义寄存器CANINTF位信息 #define MERRF  7 #define WAKIF  6 #define ERRIF  5 #define TX2IF  4 #define TX1IF  3 #define TX0IF  2 #define RX1IF  1 #define RX0IF  0

 //定义寄存器EFLG位信息 #define RX1OVR  7 #define RX0OVR  6 #define TXB0  5 #define TXEP  4 #define RXEP  3 #define TXWAR  2 #define RXWAR  1 #define EWARN  0

 //定义寄存器TXBnCTRL ( n = 0, 1, 2 )位信息 #define ABTF  6 #define MLOA  5 #define TXERR  4 #define TXREQ  3 #define TXP1  1 #define TXP0  0

 //定义寄存器RXB0CTRL位信息 #define RXM1  6 #define RXM0  5 #define RXRTR  3 #define BUKT  2 #define BUKT1  1 #define FILHIT0  0

//定义发送缓冲寄存器 TXBnSIDL ( n = 0, 1 )的位信息

#define EXIDE  3

//定义接受缓冲器1控制寄存器的位信息 #define FILHIT2  2 #define FILHIT1  1

/**  * 定义接收缓冲器n标准标示符低位 RXBnSIDL ( n = 0, 1 )的位信息  */ #define SRR   4 #define IDE   3

// 定义接收缓冲器n数据长度码 RXBnDLC ( n = 0, 1 )的位信息

#define RTR   6 #define DLC3  3 #define DLC2  2 #define DLC1  1 #define DLC0  0

 //定义SPI控制命令字 #define SPI_RESET    0xC0 #define SPI_READ    0x03 #define SPI_READ_RX   0x90 #define SPI_WRITE    0x02 #define SPI_WRITE_TX  0x40 #define SPI_RTS     0x80 #define SPI_READ_STATUS 0xA0 #define SPI_RX_STATUS  0xB0 #define SPI_BIT_MODIFY 0x05 //********************* //*   常 数 宏 定 义  * //*********************

//********************** //*   动 作 宏 定 义   * //**********************

//********************** //*   全局变量声明区   * //**********************

//********************** //*   函 数 声 明 区   * //**********************

 

//**********************************************************// //   函数说明:MCP2515初始化程序                            // //   输入:    无                                   // //   输出:    无                                          // //   调用函数:                                  // //**********************************************************// extern void mcp2515_init(void);

//**********************************************************// //   函数说明:MCP2515写控制寄存器程序                      // //   输入:    寄存器地址,写入数据                         // //   输出:    无                                          // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************// extern void mcp2515_write_register( u08 adress, u08 data );

//**********************************************************// //   函数说明:MCP2515读控制寄存器程序                      // //   输入:    寄存器地址,                             // //   输出:    寄存器数据                                  // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************// extern u08 mcp2515_read_register(u08 adress);

//**********************************************************// //   函数说明:MCP2515控制寄存器位修改程序                // //   输入:    寄存器地址,修改位,修改数据                // //   输出:    无                                      // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************// extern void mcp2515_bit_modify(u08 adress, u08 mask, u08 data);

//**********************************************************// //   函数说明:对MCP2515连续寄存器进行连续写操作            // //   输入:    连续寄存器起始地址,数据指针,数据长度      // //   输出:    无                                      // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************// extern void mcp2515_write_register_p( u08 adress, u08 *data, u08 length );

//**********************************************************// //   函数说明:对MCP2515连续寄存器进行连续读操作            // //   输入:    连续寄存器起始地址,数据指针,数据长度      // //   输出:    无                                      // //   调用函数:SPI发送程序SPI_MasterTransmit                // //**********************************************************// extern void mcp2515_read_register_p( u08 adress, u08 *data, u08 length );

#endif // _MCP2515_H_



上一篇: Windows操作系统25年发展历程
下一篇: 单片机自关机(彻底关机)电路的实现方法

发表评论