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_
发表评论