📄 mcp2515.c
字号:
case 0x01:
// MCP2515_Enable();
SendSIOData(0x96);
// MCP2515_Disable();
break;
case 0x10:
// MCP2515_Enable();
SendSIOData(0x90);
// MCP2515_Disable();
break;
case 0x11:
// MCP2515_Enable();
SendSIOData(0x94);
// MCP2515_Disable();
break;
}
}
/*************************************************************************/
/*函数名称:MCP2515_LOAD_TXBUFF */
/*函数功能: 标识符装载命令 */
/*入口参数: :nu_tx_buff 各位说明如下: */
/* bit0:是否装载标识符,为0则要装载; bit2,bit1:选择发送缓冲区 */
/*返回值 : 无 */
/*************************************************************************/
void MCP2515_LOAD_TXBUFF(unsigned char nu_tx_buff)
{
SendSIOData(0x40|(nu_tx_buff & 0x07));
}
/*************************************************************************/
/*函数名称:MCP2515_RX_STATUS */
/*函数功能: 获取RX状态 */
/*入口参数: 无 */
/*返回值 : RX状态 */
/*************************************************************************/
unsigned char MCP2515_RX_STATUS(void)
{
unsigned char rx_stutus_p;
MCP2515_Enable();
SendSIOData(0xB0); //发送 RX 状态指令 1011 0000
SendSIOData(0);
rx_stutus_p = ReadSIOData(); //
MCP2515_Disable();
return rx_stutus_p;
}
/*************************************************************************/
/*函数名称:MCP2515_RTS */
/*函数功能: 请求报文发送 */
/*入口参数: n_tx_buf : 发送选项,后三位有效 */
/* n_tx_buf & 0x87 = 0x81 : 发送缓冲器0 请求发送 */
/* n_tx_buf & 0x87 = 0x82 : 发送缓冲器1 请求发送 */
/* n_tx_buf & 0x87 = 0x83 : 发送缓冲器2 请求发送 */
/*返回值 : 无 */
/*************************************************************************/
void MCP2515_RTS(unsigned char n_tx_buf)
{
MCP2515_Enable();
SendSIOData(0x80|n_tx_buf); //发送 请求发送报文指令(RTS) 1000 0nnn
MCP2515_Disable();
}
/*************************************************************************/
/*函数名称:MCP2515_WriteBits */
/*函数功能: 修改位数据 (位修改) */
/*入口参数: 1.address : 发送寄存器地址 */
/* 2.data : 修改数据(只能修改屏蔽字节中置 1 的相应位) */
/* 3.mask : 屏蔽字节 */
/*返回值 : 无 */
/*************************************************************************/
void MCP2515_WriteBits( int address, int data, int mask )
{
MCP2515_Enable(); //MCP2515 Enable
SendSIOData(MCP2515INSTR_BITMDFY); //发送位修改指令
SendSIOData((unsigned char)address); //发送寄存器地址
SendSIOData((unsigned char)mask); //发送屏蔽字节
SendSIOData((unsigned char)data); //发送数据字节
MCP2515_Disable(); //MCP2515 Disable
}
/*************************************************************************/
/*函数名称:MCP2515_SetBandRate */
/*函数功能: 波特率设置 */
/*入口参数: 1.bandrate : 波特率 */
/* 2.IsBackNormal : 1: 使用外部时钟 0: 不使用外部时钟 */
/*返回值 : 无 */
/*************************************************************************/
void MCP2515_SetBandRate(CanBandRate bandrate, unsigned char IsBackNormal)
{
MCP2515_Write(MCP2515REG_CANCTRL, MODE_CONFIG); //进入到配置模式
MCP2515_Read(0x0E); //读取 CAN 状态(0xXE)
switch(bandrate)
{
case BandRate_10kbps: //波特率NBR = 1/(同步段+传播段+相位缓冲段1(PS1)+相位缓冲段2(PS2))
MCP2515_Write(CNF1, SJW1|0x31); //Synchronization Jump Width Length(同步跳转宽度 SJW ) =1 TQ
//BRP = 0x31
//TQ = 2*(BRP+1)/Fosc = 625ns (Fosc = 16MHz)
//Sync Seg(同步段) = 1TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1(相位缓冲段1) = 4TQ, Prop Seg(传播) = 7TQ
MCP2515_Write(CNF3, SEG4); // Phase Seg 2(相位缓冲段2) = 4TQ
break; //NBR = 1/((1+7+4+4)*6.25ns)
case BandRate_20kbps:
MCP2515_Write(CNF1, SJW1|0x18); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG4); // Phase Seg 2 = 4
break;
case BandRate_50kbps:
MCP2515_Write(CNF1, SJW1|0x9); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG4); // Phase Seg 2 = 4
break;
case BandRate_62kbps:
MCP2515_Write(CNF1, SJW1|0x7); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG4);// Phase Seg 2 = 4
break;
case BandRate_100kbps:
MCP2515_Write(CNF1, SJW1|0x4); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG4); // Phase Seg 2 = 4
break;
case BandRate_125kbps:
MCP2515_Write(CNF1, SJW1|BRP4); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG4); // Phase Seg 2 = 4
break;
case BandRate_142kbps:
MCP2515_Write(CNF1, SJW1|0x6); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG3<<3)|SEG2); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG2); // Phase Seg 2 = 4
break;
case BandRate_167kbps:
MCP2515_Write(CNF1, SJW1|0x2); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG4); // Phase Seg 2 = 4
break;
case BandRate_200kbps:
MCP2515_Write(CNF1, SJW1|BRP5); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG3<<3)|SEG2); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG2); // Phase Seg 2 = 4
break;
case BandRate_250kbps:
MCP2515_Write(CNF1, SJW1|BRP2); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG4); // Phase Seg 2 = 4
break;
case BandRate_500kbps:
MCP2515_Write(CNF1, SJW1|BRP1); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2515_Write(CNF3, SEG4); // Phase Seg 2 = 4
break;
case BandRate_1Mbps: //
MCP2515_Write(CNF1, SJW1|BRP1); //Synchronization Jump Width Length =1 TQ
MCP2515_Write(CNF2, BTLMODE_CNF3|(SEG3<<3)|SEG2); // Phase Seg 1 = 2, Prop Seg = 3
MCP2515_Write(CNF3, SEG2); // Phase Seg 2 = 1
break;
}
if(IsBackNormal)
{
//Enable clock output
MCP2515_Write(CLKCTRL, MODE_NORMAL | CLKEN | CLK1); //使用外部时钟
}
MCP2515_Read(CNF3);
}
/*************************************************************************/
/*函数名称:MCP2515_SRead */
/*函数功能: 从MCP2515 读取一块数据,即从CAN总线接收一串数据 */
/*入口参数: 1.address : MCP2515接收寄存器地址 */
/* 2.* pdata : 接收数据的存放地址 */
/* 3. nlength : 接收数据长度 */
/*返回值 : 无 */
/*************************************************************************/
void MCP2515_SRead( unsigned char address, unsigned char* pdata, unsigned char nlength )
{
int i;
MCP2515_Enable(); //MCP2515 Enable
SendSIOData(MCP2515INSTR_READ); //发送读指令
SendSIOData((unsigned char)address); //发送MCP2515接收寄存器地址
for (i=0; i<nlength; i++) //接收数据
{
SendSIOData(0);
*pdata = ReadSIOData();
pdata++;
}
MCP2515_Disable(); //MCP2515 Disable
}
/*************************************************************************/
/*函数名称:MCP2515_Swrite */
/*函数功能: 向 MCP2515 写入一块数据,即向CAN总线发送一串数据 */
/*入口参数: 1.address : MCP2515发送寄存器地址 */
/* 2.* pdata : 待发送数据的存放地址 */
/* 3. nlength : 待发送数据长度 */
/*返回值 : 无 */
/*************************************************************************/
void MCP2515_Swrite(unsigned char address, unsigned char* pdata, unsigned char nlength)
{
int i;
MCP2515_Enable(); //MCP2515 Enable
SendSIOData(MCP2515INSTR_WRITE); //发送写指令
SendSIOData((unsigned char)address); //发送MCP2515发送寄存器地址
for (i=0; i < nlength; i++) //发送数据
{
SendSIOData((unsigned char)*pdata);
pdata++;
}
MCP2515_Disable(); //MCP2515 Disable
}
/***********************************************************************************************/
/*函数名称:MCP2515_Write_Can_ID */
/*函数功能: 写MCP2515 CAN 数据帧 标识符位(ID) */
/*入口参数: 1.address : MCP2515寄存器地址 */
/* 2.can_id : CAN 数据帧标识位 */
/* 3.IsExt : 表示是否为扩展标识符 1 : 是扩展标识符(EID) 0 : 是标准标识符(SID) */
/* 标准标识位 : 11位 扩展标识位 : 29位 */
/*返回值 : 无 */
/***********************************************************************************************/
void MCP2515_Write_Can_ID(U8 address, U32 can_id, U8 IsExt)
{
U32 tbufdata;
if (IsExt) //是扩展标识符(EID17~EID0 SID10~SID0)
{
can_id &= 0x1fffffff; //取后29位
tbufdata = (can_id >>21) | ((can_id>>5) & 0xe000) | ((can_id>>8) & 0x300) | ((can_id<<8) & 0xff0000) | (can_id<<24) | 0x800;
//can_id >>21 :写标准标识符位(EID)的 SID10~SID3 位
//can_id>>5) & 0xe000 :写标准标识符位(EID)的 SID2 ~SID0 位
//can_id>>8) & 0x300 :写扩展标识符位(EID)的 EID17~EID16 位
//can_id<<8) & 0xff0000 :写扩展标识符位(EID)的 EID15~EID8 位
//can_id<<24 :写扩展标识符位(EID)的 EID7 ~EID0 位
//0x800 :写扩展标识符位(EID)的 EID11 位
}
else
{
can_id &= 0x7ff; //取后11位
tbufdata= (can_id>>3)|((can_id & 0x07)<<13);
//can_id>>3 : 写标准标识符位(SID)的 SID7 ~SID0 位
//(can_id & 0x07)<<13 : 写标准标识符位(SID)的 SID10~SID8 位
}
MCP2515_Swrite(address, (unsigned char*)&tbufdata, 4);
}
/*********************************************************************************/
/*函数名称:MCP2515_Read_Can_ID */
/*函数功能: 读取MCP2515 CAN 数据帧 标识符位(ID) */
/*入口参数: 1.address : MCP2515寄存器地址 */
/* 2.*can_id : 为返回的ID值----(((标准帧ID在高位,扩展帧ID在地位))) */
/*返回值 : 1.TRUE : 表示是扩展ID(29位) */
/* 2.FALSE : 表示非扩展ID(11位) */
/*********************************************************************************/
U8 MCP2515_Read_Can_ID( U8 address, U32 *can_id)
{
U32 tbufdata;
U8 *p = (U8 *) &tbufdata; //? 既然 CAN ID 有可能 28 位 为什么不定义成 U32 ?
MCP2515_SRead(address, p, 4);
*can_id = (tbufdata<<3)|((tbufdata>>13) & 0x7); //标准ID
*can_id &= 0x7ff; //取低 11 位
if ( (p[MCP2515LREG_SIDL] & TXB_EXIDE_M) == TXB_EXIDE_M )
{
*can_id = (*can_id<<2) | (p[MCP2515LREG_SIDL] & 0x03);
*can_id <<= 16;
*can_id |= (tbufdata>>8) & 0xff00; //EID15~8
*can_id |= (tbufdata>>24) & 0xff; //EID 7~0
return 1;
}
return 0;
}
/*********************************************************************************/
/*函数名称:MCP2515_Write_Can */
/*函数功能: 装载CAN 发送数据到 MCP2515 的发送缓冲器 */
/*入口参数: 1.nbuffer : 发送缓冲区,可以为0、1、2 */
/* 2.ext : 表示是否是扩展总线 1: 是 0:否 */
/* 3.can_id : 为返回的ID值 */
/* 4.rxRTR : 表示是否是--远程帧1,数据帧0 */
/* 5.data : 表示发送的数据 */
/* 6.dlc : 表示 数据长度 */
/* 7.FALSE : 表示非扩展总线 */
/*返回值 : 无 */
/*********************************************************************************/
void MCP2515_Write_Can( U8 nbuffer, U8 ext, U32 can_id, U8 rxRTR, U8* data,unsigned char dlc )
{
U8 mcp_addr = (nbuffer<<4) + 0x31; //发送缓冲器 标准标识符(TXBnSID)地址 (高位在前)
//发送缓冲器0标准标识符(TXB0SID)地址 :0x31~0x32
//发送缓冲器1标准标识符(TXB1SID)地址 :0x41~0x42
//发送缓冲器2标准标识符(TXB2SID)地址 :0x51~0x52
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -