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

📄 mcp2515.c

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