📄 mcp2515.c
字号:
MCP2515_Swrite(mcp_addr+5, data, dlc ); //装载数据到发送缓冲器的数据字节
//发送缓冲器0数据数据字节(TXB0)地址 : 0x36~0x3D
//发送缓冲器1数据数据字节(TXB1)地址 : 0x46~0x4D
//发送缓冲器2数据数据字节(TXB2)地址 : 0x56~0x5D
MCP2515_Write_Can_ID( mcp_addr, can_id,ext); //写 CAN 标识符(ID)
if (rxRTR)
dlc |= RTR_MASK; //如果是远程帧 置远程发送请求位 : TXBnDLC.6 (RTR_MASK = 0x40)
MCP2515_Write((mcp_addr+4), dlc); //装载发送数据长度到发送缓冲器数据长度码
//发送缓冲器0数据长度码(TXB0DLC)地址 : 0x35
//发送缓冲器1数据长度码(TXB1DLC)地址 : 0x45
//发送缓冲器2数据长度码(TXB2DLC)地址 : 0x55
}
/*********************************************************************************/
/*函数名称:MCP2515_Read_Can */
/*函数功能: 从 CAN 接收数据到 MCP2515 接收缓冲器 */
/*入口参数: 1.nbuffer : 接收缓冲器,可以为3或者4 */
/* 2.*can_id : 接收到的CAN_ID值的存放地址 */
/* 3.*rxRTR : 表示帧类型存放地址 远程帧1,数据帧0 */
/* 4.*data : 表示接收到的数据的存放地址 */
/* 5.*dlc : 表示data length code */
/*返回值 1.TRUE : 表示是扩展总线 */
/* 2.FALSE : 表示非扩展总线 */
/*********************************************************************************/
U8 MCP2515_Read_Can(U8 nbuffer, U8 * rxRTR, U32* can_id, U8* data , U8* dlc)
{
U8 IsExt, ctrl;
U8 mcp_addr = (nbuffer<<4) + 0x31; //接收缓冲器 标准标识符(RXBnSID)地址 (高位在前)
//接收缓冲器0标准标识符(RXB0SID)地址 :0x61~0x62
//接收缓冲器1标准标识符(RXB1SID)地址 :0x71~0x72
IsExt = MCP2515_Read_Can_ID( mcp_addr, can_id); //读取标准标识符(ID)并返回总线类型
ctrl = MCP2515_Read(mcp_addr-1); //读接收缓冲器控制寄存器状态 (RXB0CTRL 地址 0x60, RXB1CTRL 地址 0x70)
*dlc = MCP2515_Read(mcp_addr+4); //读取数据的长度码 (RXB0DLC 地址 0x65, RXB1DLC 地址 0x75)
if ((ctrl & 0x08)) //RXBnCTRL.3 ->RXRTR : 远程传送位 为 1 时为远程传送请求
*rxRTR = 1; //是远程传送请求 置该帧为远程帧
else
*rxRTR = 0;
*dlc &= DLC_MASK; //读取数据长度码(RXBnDLC 低四位) (DLC_MASK = 0x07)
MCP2515_SRead(mcp_addr+5, data, *dlc); //读取接收到的数据,存放在data中
return IsExt;
}
/*********************************************************************************/
/*函数名称:canSetup */
/*函数功能: 设置接收模式和滚存设置 */
/*入口参数: 无 */
/*返回值 : 无 */
/*********************************************************************************/
void canSetup(void)
{
// MCP2515_WriteBits(RXB0CTRL, (RXB_BUKT+RXB_RX_ANY), 0xFF); //使能滚存,并且关闭滤波功能,接收所有数据
// MCP2515_WriteBits(RXB1CTRL, RXB_RX_ANY, 0xFF);
MCP2515_WriteBits(RXB0CTRL, (RXB_BUKT+RXB_RX_STDEXT), 0xFF); //接收符合滤波条件的报文,关闭滚存
MCP2515_WriteBits(RXB1CTRL, RXB_RX_STDEXT, 0xFF);
MCP2515_WriteBits(TXB0CTRL, 0x2, 0x3); //设置发送优先级,0最高,1次之.
MCP2515_WriteBits(TXB1CTRL, 0x3, 0x3);
MCP2515_WriteBits(TXB2CTRL, 0x0, 0x3);
}
/*********************************************************************************/
/*函数名称:canWrite */
/*函数功能: 向 CAN 发送数据 */
/*入口参数: 1.id : CAN ID */
/* 2.*pdata : 要发送的数据块地址 */
/* 3.dlc : 发送数据的数据长度 */
/* 4.IsExt : 总线类型 1 : 扩展总线 0 :非扩展总线 */
/* 5.rxRTR : 是远程帧1,还是数据帧0 */
/*返回值 : 无 */
/*********************************************************************************/
void canWrite(U32 id, U8 *pdata, unsigned char dlc, U8 IsExt, U8 rxRTR)
{
static U8 ntxbuffer = 0;
MCP2515_Write_Can(ntxbuffer, IsExt, id, rxRTR, pdata, dlc); //装载待发送的数据到 MCP2515 发送缓冲器
switch(ntxbuffer)
{
case 0: //发送缓冲器0
// while (MCP2515_ReadStatus()&STATUS_TXB0REQ); //等待发送缓冲区有效
// MCP2515_transmit(TXB0CTRL);
MCP2515_RTS(0x01); //发送 发送缓冲器 0 中的数据
ntxbuffer = 1; //准备发送下一缓冲器中的数据
break;
case 1: //发送缓冲器1
// while (MCP2515_ReadStatus()&STATUS_TXB1REQ);
// MCP2515_transmit(TXB1CTRL);
MCP2515_RTS(0x02); //发送 发送缓冲器 1 中的数据
ntxbuffer = 2;
break;
case 2: //发送缓冲器2
// while (MCP2515_ReadStatus()&STATUS_TXB2REQ);
// MCP2515_transmit(TXB2CTRL);
MCP2515_RTS(0x04); //发送 发送缓冲器 2 中的数据
ntxbuffer = 0;
break;
}
}
/***************************************************\
发送数据(只发送数据,标识符等相关标志使用之前的设置)
注意:每次都发送8个字节
\***************************************************/
void MCP2515_CAN_WRITE(unsigned char *ppdata)
{
static unsigned char num_tx_buffer=0;
int i;
MCP2515_Enable();
switch(num_tx_buffer)
{
case 0:
SendSIOData(0x41); //使用装载TX BUFFER命令
//写入要发送的数据字节
for (i=8; i>0;i--)
{
SendSIOData((unsigned char)*ppdata);
ppdata++;
}
MCP2515_Disable();
MCP2515_RTS(0x1);
num_tx_buffer=1;
break;
case 1:
SendSIOData(0x43);
for (i=8; i>0;i--)
{
SendSIOData((unsigned char)*ppdata);
ppdata++;
}
MCP2515_Disable();
MCP2515_RTS(0x2);
num_tx_buffer=2;
break;
case 2:
SendSIOData(0x45);
for (i=8; i>0;i--)
{
SendSIOData((unsigned char)*ppdata);
ppdata++;
}
MCP2515_Disable();
MCP2515_RTS(0x4);
num_tx_buffer=0;
break;
}
}
/*********************************************************************************/
/*函数名称:MCP2515_CAN_WRITE_SingleCE */
/*函数功能: 发送数据(只发送数据,标识符等相关标志在使用之前的设置) */
/* 注意:每次都发送8个字节 */
/*入口参数: *ppdata : 数据地址 */
/*返回值 : 无 */
/*********************************************************************************/
void MCP2515_CAN_WRITE_SingleCE(unsigned char *ppdata)
{
static unsigned char num_tx_buffer = 0;
int i;
MCP2515_Enable();
switch(num_tx_buffer)
{
case 0:
SendSIOData(0x41); //使用装载TX BUFFER命令,装载数据到 发送缓冲器 0
//写入要发送的数据字节
for (i=8; i>0;i--)
{
SendSIOData((unsigned char)*ppdata);
ppdata++;
}
MCP2515_Disable();
MCP2515_RTS(0x01); //将发送缓冲器 0 中的数据发送出去
num_tx_buffer = 1;
break;
case 1:
SendSIOData(0x43); //装载数据到 发送缓冲器 1
for (i=8; i>0;i--)
{
SendSIOData((unsigned char)*ppdata);
ppdata++;
}
MCP2515_Disable();
MCP2515_RTS(0x2); //将发送缓冲器 1 中的数据发送出去
num_tx_buffer = 2;
break;
case 2:
SendSIOData(0x45); //装载数据到 发送缓冲器 2
for (i=8; i>0;i--)
{
SendSIOData((unsigned char)*ppdata);
ppdata++;
}
MCP2515_Disable();
MCP2515_RTS(0x4); //将发送缓冲器 2 中的数据发送出去
num_tx_buffer = 0;
break;
}
}
/*********************************************************************************/
/*函数名称:MCP2515_CAN_WRITE_SingleC */
/*函数功能: 发送数据(只发送数据,标识符等相关标志使用之前的设置) */
/* 注意:每次都发送8个字节 */
/* 只发送一个声道的数据 */
/*入口参数: *ppdata : 数据地址 */
/*返回值 : 无 */
/*********************************************************************************/
void MCP2515_CAN_WRITE_SingleC(unsigned char *ppdata)
{
static unsigned char num_tx_buffer=0;
int i;
MCP2515_Enable();
switch(num_tx_buffer)
{
case 0:
SendSIOData(0x41); //使用装载TX BUFFER命令 装载数据到 发送缓冲器 0
//写入要发送的数据字节
for (i=4; i>0;i--)
{
SendSIOData(*ppdata);
SendSIOData(*(ppdata+1));
ppdata = ppdata+4;
}
MCP2515_Disable();
MCP2515_RTS(0x1); //将发送缓冲器 0 中的数据发送出去
num_tx_buffer = 1;
break;
case 1:
SendSIOData(0x43); //装载数据到 发送缓冲器 1
for (i=4; i>0;i--)
{
SendSIOData(*ppdata);
SendSIOData(*(ppdata+1));
ppdata = ppdata+4;
}
MCP2515_Disable();
MCP2515_RTS(0x2); //将发送缓冲器 1 中的数据发送出去
num_tx_buffer=2;
break;
case 2:
SendSIOData(0x45); //装载数据到 发送缓冲器 2
for (i=4; i>0; i--)
{
SendSIOData(*ppdata);
SendSIOData(*(ppdata+1));
ppdata = ppdata+4;
}
MCP2515_Disable();
MCP2515_RTS(0x4); //将发送缓冲器 2 中的数据发送出去
num_tx_buffer=0;
break;
}
}
/*********************************************************************************/
/*函数名称:init_MCP2515 */
/*函数功能: 初始化 MCP2515 */
/*入口参数: bandrate : 总线波特率 */
/*返回值 : 无 */
/*********************************************************************************/
void init_MCP2515(CanBandRate bandrate)
{
unsigned char i,j,a;
rPDATB = rPDATB | 0x020; //配置GPB5为功能脚
rPCONB = rPCONB & 0xFDF;
MCP2515_Reset();
Delay60ns(4);
MCP2515_SetBandRate(bandrate,0); //使用外部晶振
// Disable interrups.
MCP2515_Write(CANINTE, NO_IE); //禁止中断
// Mark all filter bits as don't care:
MCP2515_Write_Can_ID(RXM0SIDH, 0x0F, 0); //设置接收缓冲器 0 验收滤波屏蔽寄存器
MCP2515_Write_Can_ID(RXM1SIDH, 0xffffffff, 0); //设置接收缓冲器 1 验收滤波屏蔽寄存器 低4位
// Anyway, set all filters to 0:
MCP2515_Write_Can_ID(RXF0SIDH, 0x001, 0); //设置接收缓冲器 0 验收滤波寄存器
MCP2515_Write_Can_ID(RXF1SIDH, 0x023, 0);
MCP2515_Write_Can_ID(RXF2SIDH, 0x023, 0); //设置接收缓冲器 1 验收滤波寄存器 将RXB1的滤波条件设置不一样
MCP2515_Write_Can_ID(RXF3SIDH, 0x023, 0);
MCP2515_Write_Can_ID(RXF4SIDH, 0x023, 0);
MCP2515_Write_Can_ID(RXF5SIDH, 0x023, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -