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

📄 test_mcp2510.cbackup

📁 ARM9.rar
💻 CBACKUP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
【文  件  名  称】Test_MCP2510.C
【功  能  描  述】三星S3C2410A板demo程序代码
【程  序  版  本】4.0
【创建人及创建日期】icesoar//2002年11月19日19:26
【修改人及修改日期】icesoar//2004-12-8 17:25
****************************************************************************/

//***************************************************************************
#include "def.h"
#include "2410addr.h"
#include "config.h"
#include "board.h"
#include "utils.h"
#include "MCP2510_Reg.h"
#include "MCP2510.h"

/****************************************************************************
MCP2510_CS		GPE11		output
MCP2510_SI		GPB5		output
MCP2510_SO		GPB6		input
MCP2510_SCK		GPB7		output
MCP2510_INT		GPG0		input		(EINT8)
****************************************************************************/
#define DELAY_TIME		150
#define MCP2510_CS_OUT		( rGPECON = rGPECON & (~(3<<22)) | (1<<22) )		//GPE11
#define MCP2510_CS(a)		rGPEDAT = ( rGPEDAT&(~(1<<11)) ) | ((a&1)<<11)

#define MCP2510_SI_OUT		( rGPBCON = rGPBCON & (~(3<<10)) | (1<<10) )		//GPB5
#define MCP2510_SI_PUT(a)		( rGPBDAT = ( rGPBDAT&(~(1<<5)) ) | ((a&1)<<5) )

#define MCP2510_SCK_OUT		( rGPBCON = rGPBCON & (~(3<<14)) | (1<<14) )		//GPB7
#define MCP2510_SCK_PUT(a)		( rGPBDAT = ( rGPBDAT&(~(1<<7)) ) | ((a&1)<<7) )

#define MCP2510_SO_IN		( rGPBCON = rGPBCON & (~(3<<12)) | (0<<12) )		//GPB6
#define MCP2510_SO_GET		( rGPBDAT & 0x40 )	

#define MCP2510_INT_IN		( rGPGCON = rGPGCON & (~(3<<0)) )
#define MCP2510_INT_GET		( rGPGDAT & 0x01 )	

U32 m_CANDRV_aulCANDrvMask[2] = { 0, 0 } ;
U32	m_CANDRV_aulSendingStartTicks[3]={ 0, 0, 0 } ;
CANFILTER   m_CANDRV_aStruRXFilter[6] =
				{
					{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}
				};
CANMESSAGE m_CANDRV_aStruRXMsg0[3], m_CANDRV_aStruRXMsg1[3] ;
//***************************************************************************

/****************************************************************************
【功能说明】
****************************************************************************/
void MCP2510_IO_CS_Init( void ) 
{
   MCP2510_CS_OUT ;
   MCP2510_SI_OUT ;
   MCP2510_SCK_OUT ;
   MCP2510_SO_IN ;
   MCP2510_SCK_PUT( 1 ) ;		//SCK put 1
   { U16 k=0; for( ; k <= DELAY_TIME; k++ ) ;  }  //延时至少300ns
   MCP2510_CS( 0 ) ;			// Select the MCP2510
   { U16 k=0; for( ; k <= DELAY_TIME; k++ ) ;  }  //延时至少300ns
}

/****************************************************************************
【功能说明】
****************************************************************************/
void Spi_Write( U8 Data ) 
{
	U8 m ;

	for( m = 0; m < 8; m++ )
	{
		MCP2510_SCK_PUT( 0 ) ;		//SCK put 0
		{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ;  }  //延时至少300ns
		if( (Data&0x80)==0x80 )
			MCP2510_SI_PUT( 1 );		//SI put 1
		else
			MCP2510_SI_PUT( 0 );		//SI put 0

		{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ;  }  //延时至少300ns
		MCP2510_SCK_PUT( 1 ) ;		//SCK put 1
		Data = Data<<1 ;
		{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ;  }  //延时至少300ns
	}
}

/****************************************************************************
【功能说明】
****************************************************************************/
U8 Spi_Read(U8 mode)
{
	U8 m ;
	U8 data = 0 ;

	for( m = 0; m < 8; m++ )
	{
		MCP2510_SCK_PUT( 0 ) ;		//SCK put 0
		{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ;  }  //延时至少300ns
		data=data<<1;
		if( MCP2510_SO_GET != 0 )
			data |= 0x01 ;
		else
			data &= 0xfe;

		{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ;  }  //延时至少300ns
		MCP2510_SCK_PUT( 1 ) ;		//SCK put 1
		{ U16 k=0; for( ; k <= DELAY_TIME; k++ ) ;  }  //延时至少300ns
	}

	return (data);
}

/****************************************************************************
【功能说明】 Read a register from the MCP2510 via SPI
****************************************************************************/
U8 ReadMCP2510Reg( U8 regaddr )
{
   U8 rreg=0;

   MCP2510_IO_CS_Init() ;		//Initial IO port and CS is select
   Spi_Write(CAN_SPIREAD );	// Send the Read command
   Spi_Write( regaddr );		// Send the register	address
   rreg = Spi_Read( 0 );			// Read back the register
   MCP2510_CS( 1 ) ;			// Deselect the MCP2510
   return( rreg );
}

/****************************************************************************
【功能说明】Read multiple registers from the MCP2510 over SPI
****************************************************************************/
void ReadMCP2510ManyRegS( U8 regaddr, U8 len, U8 *dta   )
{
   U16 x=0;

   MCP2510_IO_CS_Init() ;		//Initial IO port and CS is select
   Spi_Write( CAN_SPIREAD );	// Send the Read command
   Spi_Write( regaddr );		// Send the register	address
   for( x=0; x<len; x++ )
   {
      *dta =Spi_Read( 0 );
      dta++;
   }
   MCP2510_CS( 1 ) ;			// Deselect the MCP2510
}

/****************************************************************************
【功能说明】Write 1 MCP2510 register
****************************************************************************/
void WriteMCP2510Reg( U8 regaddr, U8 regvalue )
{
   MCP2510_IO_CS_Init() ;		//Initial IO port and CS is select
   Spi_Write( CAN_SPIWRITE );	// Send the Write command
   Spi_Write( regaddr );		//send the register address
   Spi_Write( regvalue );
   MCP2510_CS( 1 ) ;			// Deselect the MCP2510
}

/****************************************************************************
【功能说明】Write Many Registers over SPI
****************************************************************************/
void WriteMCP2510ManyRegS( U8 regaddr, U8 len, U8 *dta )
{
   U16 x=0;

   MCP2510_IO_CS_Init() ;		//Initial IO port and CS is select
   Spi_Write( CAN_SPIWRITE );	// Send the Read command
   Spi_Write( regaddr );		// Send the register	address
   for( x=0; x<len; x++ )
   {
      Spi_Write( *dta );
      dta++;
   }
   MCP2510_CS( 1 ) ;			// Deselect the MCP2510
}

/****************************************************************************
【功能说明】 Send Command to MCP2510 via SPI 
****************************************************************************/
void SendCMDMCP2510( U8 CMD )
{
   MCP2510_IO_CS_Init() ;		//Initial IO port and CS is select
   Spi_Write(CMD );
   MCP2510_CS( 1 ) ;			// Deselect the MCP2510
}

/****************************************************************************
【功能说明】              Read often used status
//Status 	 7    	6    	5    	4    	3    	2  	1	0
//		|	|	|	|	|	|	|	|									
//		|	|	|	|	|	|	|	|___CANINTF.RX0IF
//		|	|	|	|	|	|	|_______CANINTF.RX1IF
//		|	|	|	|	|	|___________TXB0CTRL.TXREQ
//		|	|	|	|	|_______________CANINTF.TX0IF
//		|	|	|	|___________________TXB1CTRL.TXREQ
//		|	|	|_______________________CANINTF.TX1IF
//		|	|___________________________TXB2CTRL.TXREQ
//		|_______________________________CANINTF.TX2IF
****************************************************************************/
U8 ReadMCP2510Status( void )
{
	U8 val;

   MCP2510_IO_CS_Init() ;		//Initial IO port and CS is select
   Spi_Write(CAN_SPIREADSTAT);	//Send Read status Command
   val=Spi_Read(0);				//read the often used status
   MCP2510_CS( 1 ) ;			// Deselect the MCP2510
   return (val);
}

/****************************************************************************
【功能说明】Modify MCP2510Reg By Bit
****************************************************************************/
void BitModifyMCP2510Reg(U8 regaddr,U8 Mask,U8 regvalue )
{
   MCP2510_IO_CS_Init() ;		//Initial IO port and CS is select
   Spi_Write(CAN_SPIBITMOD);
   Spi_Write(regaddr);
   Spi_Write(Mask);
   Spi_Write(regvalue);
   MCP2510_CS( 1 ) ;			// Deselect the MCP2510
}

/****************************************************************************
【功能说明】Set the MCP2510 operation mode
1.normal mode 2.sleep mode 3.loop back mode 4.listen only mode 5 configure mode
ClkOutPreScale: 1-CLKOUT=OSC; 2--CLKOUT=OSC/2  4--CLKOUT=OSC/4 8 --CLKOUT=OSC/8
****************************************************************************/
U8 Set_MCP2510_Mode( U8 mode,U8 ClkOutPreScale )
{
	U8 value=0;
	U8 modeval=0;
	U8 modeval1=0;
	U8 ReadBackCNT=0;
	
	if(mode==1) 		modeval=CAN_NORMAL_MODE;
	else if(mode==2) 	modeval=CAN_SLEEP_MODE;
	else if(mode==3)		modeval=CAN_LOOP_MODE;
	else if(mode==4)		modeval=CAN_LISTEN_MODE;
	else if(mode==5)		modeval=CAN_CFG_MOEE;
	else 				;

	modeval1=modeval;
	
	switch(ClkOutPreScale)
	{
	case 1:	modeval=modeval| CLKEN | CLKPRE1 ;
			break;
	case 2:	modeval=modeval| CLKEN | CLKPRE2 ;
			break;
	case 4:	modeval=modeval| CLKEN | CLKPRE4 ;
			break;
	case 8:	modeval=modeval| CLKEN | CLKPRE8 ;
			break;
	default:	modeval=modeval ;
			break;
	}

	WriteMCP2510Reg( CANCTRL,modeval );

	while( ReadBackCNT<5 )
	{
		value=( ReadMCP2510Reg(CANSTAT) & 0xe0 );

		if( value == modeval1 )
		{
			break;
		}
		
		ReadBackCNT++;
	}
	
	if( ReadBackCNT==5 ) 			//Set mcp2510's mode failed,redo it again
	{
		printf( "Set MCP2510 mode failed, redo it!\n" ) ;		//Printf message
		WriteMCP2510Reg( CANCTRL,modeval );		//redo to set mcp2510 mode
		
		Delay( 1 );
	}

	value = ( ReadMCP2510Reg(CANSTAT) & 0xe0 );	//read back mode from CANSTAT Register
	return (value);	
}

/****************************************************************************
【功能说明】Set the Baud Rate for MCP2510 
//BaudIndex:		Baud          Nominal Bit Time
//	0			1000K		1uS
//	1			800K		1.25uS
//	2			500K		2uS
//	3			250K		4uS	
//	4			125K		8uS
//	5			100K		10uS
//	6			50K			20uS
//	7			20K			50uS
//	8			10K			100uS
****************************************************************************/
U8  Set_MCP2510_Baud( U8 BaudIndex )
{
	U8 CNF1Reg,CNF2Reg,CNF3Reg;
	U8 val;
	// For 1000k,500k,250k,125k,100k,50k,20k Tbit=8 TQ
	// For 800k  Tbit=10 TQ
	// For 10k    Tbit=16 TQ
	
	CNF2Reg=0x90;		//PSeg=1 TQ  	PS1=3 TQ
	CNF3Reg=0x02;		//PS2=2 TQ	SYNC=1 TQ	//Tbit=8 TQ
	
	switch(BaudIndex)
	{
		case 0:	CNF1Reg=0x00;		//1000k
				break;			
		case 1:	CNF1Reg=0x00;		//800k	10TQ
				CNF2Reg=0x98;		//PS1=4 TQ	PSeg=1 TQ
				CNF3Reg=0x03;		//PS2=4 TQ	SYNC=1 TQ		
				break;
		case 2:	CNF1Reg=0x01;		//500k
				break;
		case 3:	CNF1Reg=0x03;		//250k
				break;
		case 4:	CNF1Reg=0x07;		//125k
				break;
		case 5:	CNF1Reg=0x09;		//100k
				break;
		case 6:	CNF1Reg=0x13;		//50k
				break;
		case 7:	CNF1Reg=0x31;		//20k
				break;
		case 8:	CNF1Reg=0x31;		//10k	16TQ
				CNF2Reg=0xB0;		//PS1=7 TQ  PSeg=1 TQ
				CNF3Reg=0x06;		//PS2=7 TQ SYNC=1 TQ	 
				break;
	}

	WriteMCP2510Reg( CNF1,CNF1Reg );
	WriteMCP2510Reg( CNF2,CNF2Reg );
	WriteMCP2510Reg( CNF3,CNF3Reg );

	return (val);		
}

/****************************************************************************
【功能说明】Set RXBuffer's Filter
FilterIndex(0---5): 0,1 For RXBuffer0   2,3,4,5 for RXBuffer1
****************************************************************************/
void SetMCP2510Filter( U8 FilterIndex, CANFILTER* Filter  )
{
	U8 ID[4];
	U8 RID1;
	ID[0]=(U8)((Filter->ID & 0xff000000)>>24);
	ID[1]=(U8)((Filter->ID & 0x00ff0000)>>16);
	ID[2]=(U8)((Filter->ID & 0x0000ff00)>>8);
	ID[3]=(U8)((Filter->ID & 0x000000ff));
	
	ID[3]=ID[3]>>3;
	ID[3]=ID[3] |(ID[2]<<5);
	ID[2]=ID[2]>>3;
	ID[2]=ID[2] |(ID[1]<<5);
	RID1=ID[1];
	ID[1]=ID[1]>>3;
	ID[1]=ID[1] & 0x03;
	ID[1]=(RID1 & 0xe0) + ID[1];
	if(Filter->EXFrame)				//concern extend frame 
	{
		ID[1]=ID[1] |0x08;
	}

	m_CANDRV_aStruRXFilter[FilterIndex %6 ].ID = Filter->ID;
	m_CANDRV_aStruRXFilter[FilterIndex %6].EXFrame = Filter->EXFrame;

	if(FilterIndex==0)
	{
		WriteMCP2510ManyRegS(RXF0SIDH,4,ID  );
	}
	else	 if(FilterIndex==1)
	{
		WriteMCP2510ManyRegS(RXF1SIDH,4,ID  );
	}
	else	 if(FilterIndex==2)
	{
		WriteMCP2510ManyRegS(RXF2SIDH,4,ID  );
	}
	else	 if(FilterIndex==3)
	{
		WriteMCP2510ManyRegS(RXF3SIDH,4,ID  );
	}
	else	 if(FilterIndex==4)
	{
		WriteMCP2510ManyRegS(RXF4SIDH,4,ID  );
	}
	else	 if(FilterIndex==5)
	{
		WriteMCP2510ManyRegS(RXF5SIDH,4,ID  );
	}
	else		;

}

/****************************************************************************
【功能说明】Set RXBuffer's Mask
MaskIndex(0---1): 0 For RXBuffer0   1 for RXBuffer1
****************************************************************************/
void SetMCP2510Mask(U8 MaskIndex, U32 mask )
{
	U8 ID[4];
	U8 RID1;
	ID[0]=(U8)((mask & 0xff000000)>>24);
	ID[1]=(U8)((mask & 0x00ff0000)>>16);
	ID[2]=(U8)((mask & 0x0000ff00)>>8);
	ID[3]=(U8)((mask & 0x000000ff));
	
	ID[3]=ID[3]>>3;
	ID[3]=ID[3] |(ID[2]<<5);
	ID[2]=ID[2]>>3;
	ID[2]=ID[2] |(ID[1]<<5);
	RID1=ID[1];
	ID[1]=ID[1]>>3;
	ID[1]=ID[1] &0x03;
	ID[1]=(RID1 & 0xe0 )+ ID[1];

	m_CANDRV_aulCANDrvMask[MaskIndex] = mask;
	
	if(MaskIndex==0)
	{
		WriteMCP2510ManyRegS(RXM0SIDH,4,ID );
	}
	else if(MaskIndex==1)
	{
		WriteMCP2510ManyRegS(RXM1SIDH,4,ID );
	}
	else ;

}

/****************************************************************************
【功能说明】
****************************************************************************/
void ClearTXEmptyFlag( U8 TXBufferIndex   )
{
	U8 mask=0x00;
	if (TXBufferIndex==0)  mask=0x04;
	else if(TXBufferIndex==1) mask=0x08;
	else if(TXBufferIndex==2) mask=0x10;
	else;

	BitModifyMCP2510Reg(CANINTF,mask, 0x00  );
}

/****************************************************************************
【功能说明】Clear Recieve Buffer over flow Flag
****************************************************************************/
void ClearRXBufferOVR(U8 RXBufferIndex  )
{
	U8 mask=0x00;
	if (RXBufferIndex==0)  mask=0x40;
	else if(RXBufferIndex==1) mask=0x80;
	else;
	
	BitModifyMCP2510Reg(EFLG,mask, 0x00 );
}


/****************************************************************************
【功能说明】Before this function was called,you must check the RXBuffer and take the frame data away
Clear the RXBuffer
this result is if RXBuffIndex=0 then CANINTF.RX0IF=0
			 if RXBuffIndex=1 then CANINTF.RX1IF=0
****************************************************************************/
void ClearRXBufferFull(U8 RXBufferIndex  )
{
	U8 mask;
	if(RXBufferIndex==0) 		mask=0x01;
	else if(RXBufferIndex==1)	mask=0x02;
	else							mask=0x00;

	BitModifyMCP2510Reg(CANINTF, mask,0x00 );
}

/****************************************************************************
【功能说明】function:Try to Send a CAN Frame;
if one of the three TX Buffers is empty then CAN Frame was Written into success=1
else  success=0xff indicating that CAN Frame was not wirtten into any TX Buffer and was not transmitted;
****************************************************************************/
U8 SendCANMessage( CANMESSAGE* Msg  )
{
	U8 status,SendData[13];
	U8 success=1;
	U8 ID[4];
	//U8 err;
	U32 ulTemp;
	
	ID[3]=(U8)((Msg->ID & 0xff000000)>>24);
	ID[2]=(U8)((Msg->ID & 0x00ff0000)>>16);
	ID[1]=(U8)((Msg->ID & 0x0000ff00)>>8);
	ID[0]=(U8)((Msg->ID & 0x000000ff));
	

⌨️ 快捷键说明

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