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

📄 mcp2515.c

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


	//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 + -