⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcp2515.c

📁 MCP2515.rar
💻 C
字号:
#include "MCP2515.H"
#include "SPI.C"
#define CANID0	0x00										//标准标识码 低5位全为0			
#define CANID1	0x55

#define SIDH		0x22										//本地ID
#define SIDL		0x00
#define EIDH		0x22										//目的地ID
#define EIDL		0x00

#define TXB0		1
#define TXB1		2
#define TXB2		3
unsigned char CanBuf[8];
/*=============================================================================
//参    数:	Command单个字节的命令
//函数功能:	向MPC2515写入命令
=============================================================================*/
void MCP2515_Command(unsigned char Command)
{
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(Command);
	SPI_CE=1;
}
/*=============================================================================
//参    数:	unsigned char addre 送出要写入的寄存器地址
						unsigned char Buf		要写入至寄存器的数据
//函数功能:	写入数据至指定地址的MCP2515寄存器
=============================================================================*/
void MCP2515_Wirte(unsigned char addre,Buf)
{
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(MCP_WRITE);
	SpiSend(addre);
	SpiSend(Buf);
	SPI_CE=1;
}
/*=============================================================================
//参    数:	unsigned char addre 要读取寄存器的地址
						unsigned char Buf 返回参数,送出读取到寄存器的数据
//函数功能:	读取MCP2515指定地址寄存器的数据
=============================================================================*/
unsigned char MCP2515_Read(unsigned char addre)
{
	unsigned char Buf;
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(MCP_READ);
	SpiSend(addre);
	Buf=SpiReceive();
	SPI_CE=1;
	return(Buf);
}

/*=============================================================================
//参    数:	txbn选择要装载的缓冲区,d1,d2位有效
						idh标识码高8位 idl 标识码低3位;
						bytes要发送字节的长度
//函数功能:	装载标识码到发送缓冲器
=============================================================================*/
void MCP2515_SendTxID(unsigned char txbn,idh,idl,bytes)
{
	SPI_CE=1;
	SPI_CE=0;
	txbn&=0x06;														//屏蔽其它的位
	SpiSend(0x40|txbn);										//Load TX Buffer Instruction 0b01000abc
	SpiSend(idh);													//送标识码D3-D10
	SpiSend(idl&0xe0);										//送标识码D0-D2 高三位有效
	SpiSend(0);														//扩展ID EID8-EID15
	SpiSend(0);														//扩展ID EID0-EID7
	SpiSend(bytes&0x0f);									//发送数据长度码DL0-DL3 
	SPI_CE=1;
	SPI_CE=0;
}
/*=============================================================================
//参    数:	unsigned char Select 选择装载的缓冲区 0,1,2
						外部数组变量DataBuf[8]装载要发送的数据;
//函数功能:	装载数据到送至缓冲器
=============================================================================*/
void MCP2515_SendTx(unsigned char Select)
{
	unsigned char i;
	SPI_CE=1;
	SPI_CE=0;
	Select<<=1;														//左移一位
	Select&=0x06;													//屏蔽高6位
	SpiSend(Select|0x41);
	for(i=0;i<8;i++) SpiSend(DataBuf[i]);
	SPI_CE=1;
}
/*=============================================================================
//参    数:	unsigned char Select 选择要读取ID的缓冲区号 0,1
						读取缓冲区的标识码至外部数组变量DataBuf[8];
//函数功能:	读取接收缓冲器0和缓冲器1的标识信息码
=============================================================================*/
void MCP2515_ReadRxID(unsigned char Select)
{
	SPI_CE=1;
	SPI_CE=0;
	Select<<=2;
	Select&=0x04;													//只保留第3位
	SpiSend(Select|0x90);									//Load TX Buffer Instruction 0b01000abc
	DataBuf[0]=SpiReceive();							//送标识码D3-D10
	DataBuf[1]=SpiReceive();							//送标识码D0-D2 EID16-17
	DataBuf[2]=SpiReceive();							//扩展ID EID8-EID15
	DataBuf[3]=SpiReceive();							//扩展ID EID0-EID7
	DataBuf[4]=SpiReceive();							//扩展ID EID8-EID15
	DataBuf[5]=SpiReceive();							//发送数据长度码DL0-DL3 
	SPI_CE=1;
}	
/*=============================================================================
//参    数:	unsigned char Select 选择要读取的缓冲区号 0,1
						读取缓冲区的数据至外部数组变量DataBuf[8];
//函数功能:	读取接收缓冲器0和缓冲器1的数据
=============================================================================*/
void MCP2515_ReadRx(unsigned char Select)
{
	unsigned char i;
	SPI_CE=1;
	SPI_CE=0;
	if(Select) i=0x96;										//0b10010110 读取接收缓冲器1
	else i=0x92;													//0b10010010 读取接收缓冲器0
	SpiSend(i);														//Read RX Buffer Instruction 0b10010ab1
	for(i=0;i<8;i++) DataBuf[i]=SpiReceive();
	SPI_CE=1;
}

/*=============================================================================
//参    数:	返回发送和缓冲状态
//函数功能:	读取发送和缓冲状态
D0:	CANINTF.RX0IF
D1:	CANINTFL.RX1IF
D2:	TXB0CNTRL.TXREQ 
D3:	CANINTF.TX0IF
D4:	TXB1CNTRL.TXREQ	
D5:	CANINTF.TX1IF
D6:	TXB2CNTRL.TXREQ
D7:	CANINTF.TX2IF
=============================================================================*/
unsigned char MCP2515_Status(void)
{
	unsigned char i;
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(MCP_READ_STATUS);
	i=SpiReceive();
	SPI_CE=1;
	return(i);
}

/*=============================================================================
//参    数:	unsigned char Select 选择要发送的缓冲区号 TXB0,TXB1,TXB2
						
//函数功能:	启动发送标志位
=============================================================================/
void MCP2515_SendStart(unsigned char Select)
{
	unsigned char i;
	switch(Select)
	{
		case TXB0: i=0x30; break;
		case TXB1: i=0x40; break;
		case TXB2: i=0x50; break;
		default: return;
	}
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(0x05);												//发送位修改指令
	SpiSend(i);														//发送目标地址
	SpiSend(0x08);												//只写入TXREQ屏蔽其它的位
	SpiSend(0x08);												//将TXREQ置1
	SPI_CE=1;
}
*/
/*=============================================================================
//参    数:	unsigned char IntF 
						
//函数功能:	清中断标志位
=============================================================================*/
void MCP2515_CLRINTF(unsigned char IntF)
{
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(0x05);												//发送位修改指令
	SpiSend(MCP_CANINTF);									//发送目标地址
	SpiSend(IntF);												//只写入TXREQ屏蔽其它的位
	SpiSend(0);														//将TXREQ置0
	SPI_CE=1;
}

/*=============================================================================
//参    数:	unsigned char IntF 
						
//函数功能:	寄存器位清0
=============================================================================*/
void MCP2515_ClrBit(unsigned char BitAddress,BitModify)
{
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(0x05);												//发送位修改指令
	SpiSend(BitAddress);									//发送目标地址
	SpiSend(BitModify);										//送要修改的位和屏蔽其它的位
	SpiSend(0);														//将位清0
	SPI_CE=1;
}
/*=============================================================================
//参    数:	unsigned char IntF 
						
//函数功能:	寄存器位置1
=============================================================================*/
void MCP2515_SetBit(unsigned char BitAddress,BitModify)
{
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(0x05);												//发送位修改指令
	SpiSend(BitAddress);									//要修改的目标地址
	SpiSend(BitModify);										//送要修改的位和屏蔽其它的位
	SpiSend(0xff);												//将位置1
	SPI_CE=1;
}
void MCP2515_Init(void)
{
	MCP2515_Command(MCP_RESET);
	MCP2515_Wirte(MCP_CANCTRL,0x80);			//MCP2515进入配置模式
	//配置收发波特率150KBP
	MCP2515_Wirte(MCP_CNF1,0x0b);					//晶振频率22.1184M 波特率为57.6Kbps
	MCP2515_Wirte(MCP_CNF2,0xf1);
	MCP2515_Wirte(MCP_CNF3,0x45);
	//IO口相关
	MCP2515_Wirte(MCP_TXRTSCTRL,0);				//TXnRTS 引脚配置为数字输入
	//接收相关
	MCP2515_Wirte(MCP_RXF0SIDH,SIDH);			//写标识码到验收滤波器
	MCP2515_Wirte(MCP_RXF0SIDL,SIDL);			//写标识码到验收滤波器
	MCP2515_Wirte(MCP_RXM0SIDH,0x00);			//不屏蔽验收滤波器的相关接收
	MCP2515_Wirte(MCP_RXM0SIDL,0x00);			//不屏蔽验收滤波器的相关接收
	
	MCP2515_Wirte(MCP_CANCTRL,0x00);			//MCP2515进入工作模式
	//中断设置
	MCP2515_Wirte(MCP_CANINTE,0x01);			//只开RX0中断
}

/*=============================================================================
//参    数:	txbn选择要装载的缓冲区,d1,d2位有效
						idh标识码高8位 idl 标识码低3位;
						bytes要发送字节的长度
//函数功能:	装载标识码和数据到发送缓冲器
//外部变量: DataBuf[];8个要发送的数据数组
=============================================================================*/
void MCP2515_Send(unsigned char txbn,idh,idl,bytes)
{
	unsigned char i;
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(txbn);												//Load TX Buffer Instruction 0b01000abc
	SpiSend(idh);													//送标识码D3-D10
	SpiSend(idl&0xe0);										//送标识码D0-D2 高三位有效
	SpiSend(0);														//扩展ID EID8-EID15
	SpiSend(0);														//扩展ID EID0-EID7
	SpiSend(bytes&0x0f);									//发送数据长度码DL0-DL3 
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(txbn+1);											//向TXBn送数据
	i=0;
	do{ SpiSend(CanBuf[i]); i++; bytes--; }
	while(bytes);
	SPI_CE=1;															//
}
void MCP2515_Receive(unsigned char rxbn)
{
	unsigned char i,bytes;
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(MCP_READ);										//读取 RX Buffer 
	SpiSend(rxbn);												//送缓冲区地址
	bytes=SpiReceive();
	bytes&=0x0f;
	for(;bytes;bytes--)
	{
		CanRxBuf[CanRxPin]=SpiReceive();		//读取缓冲的数据直接向串口发送缓冲
		CanRxPin++;
		if(CanRxPin>31) CanRxPin=0;
	}
	SPI_CE=1;
	MCP2515_CLRINTF(MCP_RX0IF);							//清接收中断标志
}
/*
void CanInt(void)
{
	unsigned char i;
	SPI_CE=1;
	SPI_CE=0;
	SpiSend(MCP_READ_STATUS);
	i=SpiReceive();
	SPI_CE=1;
	if(i&0x01) CanRead();														//是否为接收中断
	if(i&0x08) MCP2515_CLRINTF(MCP_TX0IF);					//清发送成功标志
}
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -