📄 mcp2515.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 + -