📄 mcp2515.c
字号:
//Enable clock output
//MCP2515_Write(CLKCTRL, MODE_LOOPBACK | CLK2);//回环模式
MCP2515_Write(CLKCTRL,MODE_NORMAL|CLK1); //配置为标准工作模式,单触发使能!!!
// Clear, deactivate the three transmit buffers ,包括设置发送缓冲器ID----全部置0
a = TXB0CTRL;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 14; j++)
{
MCP2515_Write(a, 0);
a++;
}
a += 2; // We did not clear CANSTAT or CANCTRL
}
// and the two receive buffers.(not buffer actually)
MCP2515_Write(RXB0CTRL, 0); //接收模式--接收所有报文,使能滚存
MCP2515_Write(RXB1CTRL, 0);
//Open Interrupt
// MCP2515_Write(CANINTE, RX0IE|RX1IE);
}
/*********************************************************************************/
/*函数名称:canPoll */
/*函数功能: 查询是否收到数据 */
/*入口参数: 无 */
/*返回值 : 如果没有收到数据,则返回-1, */
/* 否则,返回收到数据的缓冲区号 */
/* Note: 如果两个缓冲区都收到数据,则返回第一个缓冲区 */
/*********************************************************************************/
int canPoll(void)
{
// if (MCP2515_Read(EFLG)&0x40) //如果缓存区0溢出,则说明缓存区1已经存在数据
// return 1;
if(MCP2515_ReadStatus() & RX0INT) //CANINTF & 0x01
return 0;
if(MCP2515_ReadStatus() & RX1INT)
return 1;
return -1;
}
/*********************************************************************************/
/*函数名称:canRead */
/*函数功能: 查询是否收到CAN数据: */
/*入口参数: 无 */
/*返回值 : 0:没有收到 */
/* 1:缓冲区0收到数据 */
/* 2:缓冲区1收到数据 */
/* 3:两个缓冲区都收到数据 */
/*********************************************************************************/
unsigned char MPC2515_CanPoll(void)
{
unsigned char polldata;
polldata = MCP2515_ReadStatus() & 0x03; //CANINTF & 0x03
return polldata;
}
/*********************************************************************************/
/*函数名称:canRead */
/*函数功能: 查询是否收到数据 */
/*入口参数: 1: n : 表示是哪个接收缓冲区接收到数据 */
/* 2: *id : 存放数据 ID 地址 */
/* 3: *pdata : 存放数据地址 */
/* 4: *dlc : 数据长度地址 */
/* 5: *rxRTR : 帧类型 扩展帧 非扩展帧 */
/* 6: *isExt : 总线类型 扩展总线 */
/*返回值 : 0 : 读取接收缓冲器 0 (RXB0)成功 */
/* 1 : 读取接收缓冲器 1 (RXB0)成功 */
/* 0xFF :读取数据失败 */
/*********************************************************************************/
U8 canRead(int n, U32 *id, U8 *pdata, U8 *dlc, U8 *rxRTR, U8 *isExt) //n表示是哪个接收缓冲区接收到数据
{
U8 CAN_byte;
CAN_byte = MCP2515_Read(CANINTF);
if (n==0)
{
if (CAN_byte & RX0INT) //接收缓冲器 0 中有数据
{
*isExt = MCP2515_Read_Can(n+3, rxRTR, id, pdata, dlc); //读取各数据
MCP2515_WriteBits(CANINTF, ~RX0INT, RX0INT); //清除 RXB0 满中断标志
MCP2515_WriteBits(EFLG, 0, EFLG_RX0OVR); //清除溢出标志
}
return 0; //读取 RXB0 成功,返回 0
}
else if (n ==1 )
{
if (CAN_byte & RX1INT) //接收缓冲器 1 中有数据
{
*isExt=MCP2515_Read_Can(n+4, rxRTR, id, pdata, dlc);
MCP2515_WriteBits(CANINTF, ~RX1INT, RX1INT); // 清除 RXB1 满中断标志
MCP2515_WriteBits(EFLG, 0, EFLG_RX0OVR); //清除溢出标志
}
return 1; //读取 RXB1 成功,返回 1
}
return 0xff; //读取数据失败
}
/*********************************************************************************/
/*函数名称:CAN_RD */
/*函数功能: 读取从CAN总线上收到的数据 */
/*入口参数:1. *ppdata :接收到的数据的存放地址; */
/* 2. *datalenth : 接收到的数据字节长度的存放地址 */
/* 3. n_rxbuff :收到数据的缓冲区个数 */
/* 如果两个缓冲器都接收到数据,则一次性全部接收 */
/*返回值 : 无 */
/*********************************************************************************/
void CAN_RD (unsigned char *ppdata, unsigned char *datalenth, unsigned char n_rxbuff)
{
unsigned char CAN_RD_datalenth;
int i;
switch (n_rxbuff)
{
case 0x0: //没有收到数据
break;
case 0x01: //接收缓冲器 0 收到数据
*datalenth = (MCP2515_Read(0x65) & DLC_MASK); //读取数据长度
MCP2515_Enable();
MCP2515_READ_RXBUFF(0);
for (i = *datalenth; i>0; i--) //读取数据
{
SendSIOData(0);
*ppdata = ReadSIOData();
ppdata++;
}
MCP2515_Disable();
MCP2515_WriteBits(CANINTF, ~RX0INT, RX0INT); //清空 RXB0 中断满标志
break;
case 0x02: //接收缓冲器 1 收到数据
*datalenth = (MCP2515_Read(0x75) & DLC_MASK); //读取数据长度
MCP2515_Enable();
MCP2515_READ_RXBUFF(1);
for (i=*datalenth; i>0; i--) //读取数据
{
SendSIOData(0);
*ppdata=ReadSIOData();
ppdata++;
}
MCP2515_Disable();
MCP2515_WriteBits(CANINTF, ~RX1INT, RX1INT); //清空 RXB1 中断满标志
break;
case 0x03: //两个接收缓冲器 都收到数据
*datalenth = (MCP2515_Read(0x65) & DLC_MASK); //读取数据长度
MCP2515_Enable();
MCP2515_READ_RXBUFF(0); //先读 接收缓冲器 0 中的数据
for (i=*datalenth; i>0; i--)
{
SendSIOData(0);
*ppdata=ReadSIOData();
ppdata++;
}
MCP2515_Disable();
MCP2515_WriteBits(CANINTF, ~RX0INT, RX0INT); //清空 RXB0 中断满标志
CAN_RD_datalenth = (MCP2515_Read(0x75) & DLC_MASK); //?
MCP2515_Enable();
MCP2515_READ_RXBUFF(1); //再读 接收缓冲器 1 中的数据
for (i=CAN_RD_datalenth; i>0; i--)
{
SendSIOData(0);
*ppdata = ReadSIOData();
ppdata++;
}
MCP2515_Disable();
MCP2515_WriteBits(CANINTF, ~RX1INT, RX1INT); //清空 RXB1 中断满标
*datalenth = *datalenth + CAN_RD_datalenth;
break;
default :
break;
}
}
/*********************************************************************************/
/*函数名称:CAN_RD_PLAY */
/*函数功能: 读取从CAN总线上收到的数据,并直接给CODEC芯片(一次传输8*16bits) */
/*入口参数:n_rxbuff : 接收缓冲器数 */
/* NOTE : 1.如果收到的数据不足8个字节(只发生在通话结束),用0填充。 */
/* 2.如果两个缓冲器都接收到数据,则一次性全部接收 */
/*返回值 : 无 */
/*********************************************************************************/
void CAN_RD_PLAY (unsigned char n_rxbuff)
{
unsigned char *Play_databyte;
static unsigned short Play_data[8] = {0};
static int n_databuff = 0;
int i;
int j;
Play_databyte = (unsigned char *)Play_data + n_databuff;
switch (n_rxbuff)
{
case 0x0: //没有收到数据
break;
case 0x1:
MCP2515_Enable();
MCP2515_READ_RXBUFF(0);
for (i=8; i>0; i--)
{
SendSIOData(0);
*(Play_databyte++) = ReadSIOData();
}
MCP2515_Disable();
n_databuff += 8;
//判断是否够一个IISFIF的数据
if (n_databuff == 16)
{
// SIO_Send (0x0a16); //0x0a16 //DAC mute
while (rIISCON & 0x80); //当发送FIFO非空时,等待
for(j=0; j<8; j++)
{
*IISFIF = Play_data[j];
}
n_databuff = 0;
}
// SIO_Send (0x0a1e); //DAC POWERDOWN
break;
case 0x2:
MCP2515_Enable();
MCP2515_READ_RXBUFF(1);
for (i=8; i>0; i--)
{
SendSIOData(0);
*(Play_databyte++)=ReadSIOData();
}
MCP2515_Disable();
n_databuff +=8;
if (n_databuff==16)
{
// SIO_Send (0x0a16); //DAC POWERUP
while (rIISCON & 0x80); //当发送FIFO非空时,等待
for(j=0; j<8; j++)
{
*IISFIF =Play_data[j];
}
n_databuff = 0;
}
// SIO_Send (0x0a1e);
break;
case 0x3:
MCP2515_Enable();
MCP2515_READ_RXBUFF(0);
for (i=8; i>0; i--)
{
SendSIOData(0);
*(Play_databyte++) = ReadSIOData();
}
MCP2515_Disable();
n_databuff += 8;
if (n_databuff==16)
{
// SIO_Send (0x0a16); //DAC POWERUP
while (rIISCON & 0x80); //当发送FIFO非空时,等待
for(j=0; j<8; j++)
{
*IISFIF = Play_data[j];
}
n_databuff = 0;
}
// SIO_Send (0x0a1e);
Play_databyte = (unsigned char *)Play_data + n_databuff;
MCP2515_Enable();
MCP2515_READ_RXBUFF(1);
for (i=8; i>0; i--)
{
SendSIOData(0);
*(Play_databyte++)=ReadSIOData();
}
MCP2515_Disable();
n_databuff +=8;
if (n_databuff==16)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -