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

📄 mcp2515.c

📁 一个在三星S3C44B0 ARM 上实现的带SPI接口的MCP2515 CAN总线控制芯片的 CAN 读写程序!
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -