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

📄 mcp2510.c

📁 EMB91SAM7S64开发板(全套资料)
💻 C
字号:
#include "spi.h"
#include "dbgu.h"
#include "MCP2510.h"

void DelayX(unsigned x){
	unsigned i;
	while(--x)	{
		for(i=0;i<1000;i++);
	}
}

/*芯片复位*/
void McpReset(uint num)
{
	SPI_CE(num,0);
	OutByte(RESET);
	SPI_CE(num,1);
}

/*读寄存器数据*/
uchar McpRdByte(uchar Raddr,uint num)
{
	unsigned char val;
	SPI_CE(num,0);
	OutByte(READ);
	OutByte(Raddr);
	val=InByte();
	SPI_CE(num,1);
	return val;
}
/*写寄存器数据*/
void McpWrByte(uchar Raddr,uchar Rdata,uint num)
{
	SPI_CE(num,0);
	OutByte(WRITE);
	OutByte(Raddr);
	OutByte(Rdata);
	SPI_CE(num,1);
}

/*读当前状态*/
uchar ReadStatus(uint num)
{
	unsigned char i,j;
	SPI_CE(num,0);
	OutByte(RD_STAT);
	i=InByte();
	j=InByte();
	SPI_CE(num,1);
	return i;
}
/*请求发送*/
void WriteRTS(uchar cmd,uint num)
{
	SPI_CE(num,0);
	OutByte(cmd);
	SPI_CE(num,1);
}
/*寄存器位改写*/
void BitModify(uchar Raddr,uchar Rmask,uchar Rdata,uint num)
{
	SPI_CE(num,0);
	OutByte(BIT_MOD);
	OutByte(Raddr);
	OutByte(Rdata);
	OutByte(Rmask);	
	SPI_CE(num,1);
}

void InitPorts(uint num)
{

    BitModify( TXRTSCTRL, 0, 0xFF,num );
    // The two pins RX0BF and RX1BF are used to control two LEDs; set them as outputs and
    // set them as 00.
    BitModify( BFPCTRL, 0x3C, 0xFF,num );    
}

uchar GetPort(uint num) 
{
    uchar port;   
    port=McpRdByte(TXRTSCTRL,num);
    // Bits 3..5 are used.
    return ((~port) >> 3) & 0x07;
}

void SetLED(int v,uint num) 
{
    BitModify(BFPCTRL, ~v << 4, 0x30,num);    
}

void McpWriteCanId( uchar mcp_addr,uchar ext,ulong can_id,uint num)
{
int i;
    uint canid;
    uchar tbufdata[4];
    canid = (uint)(can_id & 0x0FFFF);
    if (ext) {
        tbufdata[EID0] = (uchar) (canid & 0xFF);
        tbufdata[EID8] = (uchar) (canid / 0x100);
        canid = (uint)( can_id / 0x10000L );
        tbufdata[SIDL] = (uchar) (canid & 0x03);
        tbufdata[SIDL] += (uchar) ((canid & 0x1C)<<3);
        tbufdata[SIDL] |= TXB_EXIDE_M;
        tbufdata[SIDH] = (uchar) (canid / 32 );
    }
    else {
        tbufdata[SIDH] = (uchar) (canid / 8 );
        tbufdata[SIDL] = (uchar) ((canid & 0x07 )<<5);  //*32
        tbufdata[EID0] = 0;
        tbufdata[EID8] = 0;
    }
    
	SPI_CE(num,0);
	OutByte(WRITE);
	OutByte(mcp_addr);
	
for(i=0;i<4;i++)	
	OutByte(tbufdata[i]);	
	
				
	SPI_CE(num,1);       
}
// Buffer can be 1..2..3
void McpWriteCan( uchar row, uchar ext, ulong can_id,
                    uchar dlc, uchar rtr, uchar* data,uint num)
{
int i;
    uchar mcp_addr = row*16 + 0x21;
    McpWriteCanId(mcp_addr,ext,can_id,num);  	// write CAN id

// write n bytes data in the Mcp2510    

	SPI_CE(num,0);
	OutByte(WRITE);
	OutByte(mcp_addr+5);
	
for(i=0;i<dlc;i++)	
	OutByte(data[i]);	
				
	SPI_CE(num,1);


    if (rtr == 1) dlc |= RTR_MASK;  				// if RTR set bit in byte
// write the RTR and DLC
	McpWrByte((mcp_addr+4),dlc,num);
}
//*----------------------------------------------------------------------------
//* \fn    McpReadCanId
//* \brief Write to one or more registers in the MCP2510, starting at address writedata
//*----------------------------------------------------------------------------
void McpReadCanId( uchar mcp_addr,uchar* ext,ulong* can_id,uint num)
{
int i;
    uchar tbufdata[4];
    *ext = 0;
    *can_id = 0;
	
	SPI_CE(num,0);
	OutByte(READ);
	OutByte(mcp_addr);
for(i=0;i<4;i++)	
	tbufdata[i]=InByte();
	SPI_CE(num,1);	
	
		
	*can_id = (tbufdata[SIDH]<<3) + (tbufdata[SIDL]>>5);
    if ( (tbufdata[SIDL] & TXB_EXIDE_M) ==  TXB_EXIDE_M ) 
    {
        *can_id = (*can_id<<2) + (tbufdata[SIDL] & 0x03);
        *can_id <<= 16;
        *can_id = *can_id +(tbufdata[EID8]<<8) + tbufdata[EID0];
        *ext = 1;
    }
}

// Buffer can be 4..5
void McpReadCan( uchar buffer, uchar* ext, ulong* can_id,
                   uchar* dlc, uchar* rtr, uchar* data,uint num )
{ 
int i;   
    uchar mcp_addr = buffer*16 + 0x21, ctrl,data_size;
    McpReadCanId( mcp_addr, ext, can_id,num );
//read RXBnCTRL
	ctrl=McpRdByte(mcp_addr-1,num);    
    
//read RXBnDLC
	data_size=McpRdByte(mcp_addr+4,num);
    if (ctrl & 0x08) {
        *rtr = 1;
     } 
    else {
        *rtr = 0;
     }
    *dlc =(data_size & DLC_MASK);

	SPI_CE(num,0);
	OutByte(READ);
	OutByte(mcp_addr+5);
for(i=0;i<(*dlc);i++)	
	data[i]=InByte();
	SPI_CE(num,1);
}

/*CAN控制器初始化函数*/
//void CanInit(unsigned char BroadCast,unsigned char OriginType,unsigned char OriginNum,unsigned char TargetType,unsigned char TargetNum)
void MCP2510Init(uint num)
//unsigned char TargetType,unsigned char TargetNum)
{
    uchar data,a;
	unsigned char i,j;               //暂不关心数据源只是目标是自己即可
	McpReset(num);
    DelayX(70);		
	/*1.设置操作模式*/
	McpWrByte(CANCTRL,MODE_CONFIG,num);
	/*2.确认操作模式*/
	do
	{
		i=McpRdByte(CANSTAT,num);
		i=i&(0xE0);
	}while(i!=MODE_CONFIG);
	/*3.设置位定时:125K波特率*/
	McpWrByte(CNF1,(SJW1 + BRP3),num);
	McpWrByte(CNF2,(BTLMODE_CNF3+SEG4*8+SEG7),num);
	McpWrByte(CNF3,SEG4,num);
	/*4.设置中断使能*/
	McpWrByte(CANINTE,RX0IE,num);
	//CanWrByte(CANINTE,0xbf);
	/*5.设置TXn引脚功能*/
    // Mark all filter bits as don't care:
    McpWriteCanId(RXM0SIDH, 0, 0, num);//add,ext,id,cs
    McpWriteCanId(RXM1SIDH, 0, 0, num);
    // Anyway, set all filters to 0:
    McpWriteCanId(RXF0SIDH, 0, 0, num);
    McpWriteCanId(RXF1SIDH, 0, 0, num);
    McpWriteCanId(RXF2SIDH, 0, 0, num);
    McpWriteCanId(RXF3SIDH, 0, 0, num);
    McpWriteCanId(RXF4SIDH, 0, 0, num);
    McpWriteCanId(RXF5SIDH, 0, 0, num);	
	
	/*7.设置操作模式*/
	McpWrByte(CANCTRL,MODE_NORMAL +CLKEN+CLK4,num);
	/*8.确认操作模式*/
	do
	{
		i=McpRdByte(CANSTAT,num);
		i=i&(0xE0);
	}while(i!=MODE_NORMAL);
    // Clear, deactivate the three transmit buffers
    data = 0;
    a = TXB0CTRL;
    
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 14; j++) {
            McpWrByte(a,data,num);
            a++;
        }
        a += 2; // We did not clear CANSTAT or CANCTRL
    }    	
	
	/*9.设置接收控制寄存器*/
    data=0x00;		
	McpWrByte(RXB0CTRL,data,num);
	//屏蔽掉接收滤波寄存器和接收屏蔽滤波器
	McpWrByte(RXB1CTRL,data,num);
    AT91F_DBGU_Printk("\n\rMCP2510 Init Completed\n\r");	
}



⌨️ 快捷键说明

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