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

📄 mcp2510.c

📁 can总线通信程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "config.h"
#include "UART_SPI.h"
#include "MCP2510.h"

#define CAN_RESET_ADD		0xc0
#define CAN_READ_ADD		0x03
#define CAN_WRITE_ADD		0x02
#define CAN_RTS_ADD			0x80	//发送请求
#define CAN_RDSTAT_ADD	    0xa0	//读状态
#define CAN_BITMDFY_ADD		0x05	//位修改
/****************************************************
 
	  ****************CAN Lib************* 

****************************************************/
void MCPWriteByte(uint8 addr,uint8 data)
{
	CAN_CS();			    // 片选
	SpiSendByte(CAN_WRITE_ADD);
	SpiSendByte(addr);
	SpiSendByte(data);	
	CAN_UnCS();
}
uint8 MCPReadByte(uint8 addr)
{
	uint8 tempdata;

	CAN_CS();
	SpiSendByte(CAN_READ_ADD);
	SpiSendByte(addr);
	tempdata = SpiSendByte(0xFF);
	CAN_UnCS();

	return tempdata;
}

uint8 MCPReadCANStatus()
{
	uint8 temp;
	
	CAN_CS();
	
	S0PDR = CAN_RDSTAT_ADD;	
    while( 0==(S0PSR&0x80) );		// 等待SPIF置位,即等待数据发送完毕 
    
  	temp = S0PDR;    
    //S0PDR = 0x00; //得不到数据就写
	S0PDR = 0xFF;
    while( 0==(S0PSR&0x80) );		// 等待SPIF置位,即等待数据发送完毕
    temp = S0PDR;
	//temp = S0PDR;
	CAN_UnCS();
	
	return temp;
}
void CAN_Modefybits( uint8 address, uint8 data, uint8 mask )//mask 位为0:data中相应的位无效
{														    //     位为1:data中相应的位写入
	
	CAN_CS();
	
	SpiSendByte(CAN_BITMDFY_ADD);
	SpiSendByte(address);
	SpiSendByte(mask);
	SpiSendByte(data);
	
	CAN_UnCS();
}

void CANReset()
{
	CAN_CS();
	SpiSendByte(CAN_RESET_ADD);
	CAN_UnCS();
}
/*******************************************\
*	序列写入CAN控制器数据				*
\*******************************************/
void MCP_WriteSeq(uint8 address, uint8* pdata, uint8 nlength)
{
	uint8 i;
	CAN_CS();

	SpiSendByte(CAN_WRITE_ADD);      //从spi口写入write命令
	SpiSendByte(address);  //写入要写入的地址

	for (i=0; i < nlength; i++)        //写入数据0-8个byte
	 { 
		SpiSendByte(*pdata);
		pdata++;
	}
		
	CAN_UnCS();
}
/*******************************************\
*	序列读出CAN控制器数据				*
\*******************************************/
void MCP_ReadSeq(uint8 address,uint8 *pdata,uint8 nlength)
{
	uint8 i;
	CAN_CS();
	SpiSendByte(CAN_READ_ADD);      //从spi口写入read命令
	SpiSendByte(address);  //写入读出的地址
	for (i=0; i<nlength; i++) {
		//SendSIOData(0);
		*pdata=SpiSendByte(0xFF);
		pdata++;
	}
	CAN_UnCS();
}

/***********************************************************\
*	写入MCP2510 发送的数据							*
*	参数: nbuffer为第几个缓冲区可以为0、1、2    	*
*			ext表示是否是扩展总线					*
*			can_id为返回的ID值						*
*			rxRTR表示是否是RXRTR					*
*			data表示读取的数据						*
*			dlc表示data length code				    *
*		FALSE,表示非扩展总线						*
\***********************************************************/
void CAN_WriteData(uint8 ntxbuffer0_2,uint32 id, uint8 *pdata, uint8 dlc, BOOL isExt, BOOL rxRTR)
{
	uint8 i;	
	uint32 temp;
	
	CANTXDATA txdata;	
	temp=id;
	if(isExt)
	{
			for(i=0;i<8;i++)
			{
				if(temp & (1<<i))
				{
					txdata.TXBnEID0 |= (1<<i);
				}
				else
					txdata.TXBnEID0 &= ~(1<<i);
			}
			for(i=0;i<8;i++)
			{
				if(temp & (1<<(i+8)))
				{
				txdata.TXBnEID8 |= (1<<i);
				}
				else
					txdata.TXBnEID8 &= ~(1<<i);
			}
			for(i=0;i<2;i++)
			{
				if(temp & (1<<(i+16)))
				{
				txdata.TXBnSIDL |= (1<<i);
				}
				else
					txdata.TXBnSIDL &= ~(1<<i);
			}
			for(i=0;i<3;i++)
			{
				if(temp & (1<<(i+18)))
				{
				txdata.TXBnSIDL |= (1<<(i+5));
				}
				else
					txdata.TXBnSIDL &= ~(1<<i);
			}
			for(i=0;i<8;i++)
			{
				if(temp & (1<<(i+21)))
				{
				txdata.TXBnSIDH |= (1<<i);
				}
				else
					txdata.TXBnSIDH &= ~(1<<i);
			}
			txdata.TXBnSIDL |= EXIDE;//扩展标识符使能
		}
	else{
			for(i=0;i<3;i++)
			{
				if(temp & (1<<i))
				{
				txdata.TXBnSIDL |= (1<<i+5);
				}
				else
					txdata.TXBnSIDL &= ~(1<<i);
			}
			for(i=0;i<8;i++)
			{
				if(temp & (1<<(i+3)))
				{
				txdata.TXBnSIDH |= (1<<i);
				}
				else
					txdata.TXBnSIDH &= ~(1<<i);
			}
			txdata.TXBnSIDL &= ~EXIDE;//扩展标识符使能
		
		}
		
	txdata.TXBnDLC = 0;
	txdata.TXBnDLC = dlc;	
	if(rxRTR)
	{
		txdata.TXBnDLC |= 0x40; 
	}
	else
		txdata.TXBnDLC &= ~0x40; 
	
	for(i=0;i<8;i++)
	{
		txdata.TXBmDn[i]=*pdata++;
	}
	 
	switch (ntxbuffer0_2)
	{
		case 0:
		MCP_WriteSeq(TXB0SIDH,&txdata.TXBnSIDH,13);	
		UART0_SendByte(MCPReadByte(TXB0CTRL));
		CAN_Modefybits(TXB0CTRL,0x0B,0x0B);//以最高优先级启动发送
		break;
		case 1:
		MCP_WriteSeq(TXB1SIDH,&txdata.TXBnSIDH,13);
		CAN_Modefybits(TXB1CTRL,0x0B,0x0B);//以最高优先级启动发送
		break;
		case 2:
		MCP_WriteSeq(TXB2SIDH,&txdata.TXBnSIDH,13);
		CAN_Modefybits(TXB2CTRL,0x0B,0x0B);//以最高优先级启动发送
		break;
	}
}

CANRXDATA MCPReadCANData(uint8 rxbuff0_1)
{
	uint8 i;
	CANRXDATAREG rxdata;
	CANRXDATA MCPrxdata;
	
	if(rxbuff0_1 == 0)
	{
		MCP_ReadSeq(RXB0SIDH,&rxdata.RXBnSIDH,13);
	}
	else
	{
		MCP_ReadSeq(RXB1SIDH,&rxdata.RXBnSIDH,13);
	}
	
	if((rxdata.RXBnSIDL & 0x18)==0x18)//收到的为扩展帧
	{
		MCPrxdata.isExt = TRUE;		
		if(rxdata.RXBnDLC & 0x40) //远程请求帧
		{
			MCPrxdata.isRTR = TRUE;
			MCPrxdata.rxNum = 0;//没有数据
			for(i=0;i<8;i++)
				MCPrxdata.rxData[i]=0;
			
		}
		else //远程数据帧
			MCPrxdata.isRTR = FALSE;		
		MCPrxdata.rxNum = (rxdata.RXBnDLC & 0x07);  //远程数据帧的数据长度
		MCPrxdata.id = (uint32)rxdata.RXBnEID0;
		MCPrxdata.id |= ((uint32)rxdata.RXBnEID8)<<8;
		MCPrxdata.id |= ((uint32)(rxdata.RXBnSIDL & 0x03))<<16;
		MCPrxdata.id |= ((uint32)(rxdata.RXBnSIDL & 0xE0))<<13;//5->18
		MCPrxdata.id |= ((uint32)rxdata.RXBnSIDH)<<21;		
	}
	else if((rxdata.RXBnSIDL & 0x18)==0x00)	//标准数据帧
	{					
		MCPrxdata.isExt = FALSE;
		MCPrxdata.id = (uint32)rxdata.RXBnSIDL;
		MCPrxdata.id = ((uint32)rxdata.RXBnSIDH)<<8;
	}
	for(i=0;i<8;i++)
				MCPrxdata.rxData[i]=rxdata.RXBmDn[i];
	
	
	return (MCPrxdata);
}


CANRXDATA CAN_ReadData()//用中断模式的接收从另一个CAN总线发送过来的数据
{					  //查询方式可读取CANSTAT值
	uint8 byte;
	//uint8 *pdata;
	CANRXDATA mcprxdata;
	byte = MCPReadByte(CANINTF);
	if(byte & RX0INT)
	{
		mcprxdata = MCPReadCANData(0);
		CAN_Modefybits(CANINTF,(uint8)~RX0INT,RX0INT);//清除中断标志
	}
	else if(byte & RX1INT)
	{
		mcprxdata = MCPReadCANData(1);
		CAN_Modefybits(CANINTF,(uint8)~RX1INT,RX1INT);
	}
	return (mcprxdata);
}

/****************************************************
 
	  ****** 			CAN 	 	 ******* 

****************************************************/
/*******************************************\
*	设置MCP2510 CAN总线ID				*
*	参数: address为MCP2510寄存器地址    *
*			can_id为设置的ID值			*
*			IsExt表示是否为扩展ID	    *
\*****************************************/


void CAN_SetMask(uint8 RXnMASK0_1,uint32 MaskID,BOOL isExt)//id:是扩展帧:0-17:扩展ID,18-28:标识符
{															//不是 :0-10标识符
	uint8 i;
	uint32 temp;
	uint8 RXMnSIDH=0;
	uint8 RXMnSIDL=0;
	uint8 RXMnEID8=0;
	uint8 RXMnEID0=0;
	
	temp = MaskID;
	
	if(isExt)
	{
		for(i=0;i<8;i++)
		{
			if(temp & (1<<i))
			{
				RXMnEID0 |= (1<<i);
			}
			else
				RXMnEID0 &= ~(1<<i);
		}
		for(i=0;i<8;i++)
		{
			if(temp & (1<<(i+8)))
			{
				RXMnEID8 |= (1<<i);
			}
			else
				RXMnEID8 &= ~(1<<i);
		}
		for(i=0;i<2;i++)
		{
			if(temp & (1<<(i+16)))
			{
				RXMnSIDL |= (1<<i);
			}
			else
				RXMnSIDL &= ~(1<<i);
		}
		for(i=0;i<3;i++)
		{
			if(temp & (1<<(i+18)))
			{
				RXMnSIDL |= (1<<(i+5));
			}
			else
				RXMnSIDL &= ~(1<<i);
		}
		for(i=0;i<8;i++)
		{
			if(temp & (1<<(i+21)))
			{
				RXMnSIDH |= (1<<i);
			}
			else
				RXMnSIDH &= ~(1<<i);
		}
	}
	else
	{
		for(i=0;i<3;i++)
		{
			if(temp & (1<<i))
			{
				RXMnSIDL |= (1<<i+5);
			}
			else
				RXMnSIDL |= (1<<i+5);
		}
		for(i=0;i<8;i++)
		{
			if(temp & (1<<(i+3)))
			{
				RXMnSIDH |= (1<<i);
			}
			else
				RXMnSIDH &= ~(1<<i);
		}
	}
	if(RXnMASK0_1==0)
	{
		MCPWriteByte(RXM0SIDH,RXMnSIDH);
		
		//测试代码
		temp = MCPReadByte(RXM0SIDH);
		UART0_SendByte(temp);//0x01
		//测试代码
		
		MCPWriteByte(RXM0SIDL,RXMnSIDH);
		
		//测试代码
		temp = MCPReadByte(RXM0SIDL);
		UART0_SendByte(temp);//0x01
		//测试代码
		
		MCPWriteByte(RXM0EID8,RXMnEID8);
		
		//测试代码
		temp = MCPReadByte(RXM0EID8);
		UART0_SendByte(temp);//0x01
		//测试代码
		
		MCPWriteByte(RXM0EID0,RXMnEID0);
		
		//测试代码
		temp = MCPReadByte(RXM0EID0);
		UART0_SendByte(temp);//0x01
		//测试代码
		
	}
	else
	{
		MCPWriteByte(RXM1SIDH,RXMnSIDH);
		
		//测试代码
		temp = MCPReadByte(RXM1SIDH);
		UART0_SendByte(temp);//0x01
		//测试代码
		
		MCPWriteByte(RXM1SIDL,RXMnSIDH);
		
		//测试代码
		temp = MCPReadByte(RXM1SIDL);
		UART0_SendByte(temp);//0x01
		//测试代码
		
		MCPWriteByte(RXM1EID8,RXMnEID8);
		
		//测试代码
		temp = MCPReadByte(RXM1EID8);
		UART0_SendByte(temp);//0x01
		//测试代码
		
		MCPWriteByte(RXM1EID0,RXMnEID0);
		
		//测试代码
		temp = MCPReadByte(RXM1EID0);
		UART0_SendByte(temp);//0x01

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -