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

📄 mcp2515.c

📁 车用液晶仪表中s3c2410的can接口程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <string.h>
#include "2410addr.h"
#include "2410lib.h"
#include "mcp2515.h"
#include "def.h"
#include "main.h"
#include "sp706.h"

////////////////////////////////////////////////////////////////////
/*--------------------SPI初始化--------------------*/
void MCP2515_SPI_Init(void)
{
    #ifdef MCP2515_SPI_0
    rGPECON=((rGPECON&0xf03fffff)|0xa800000);
    rGPGCON=((rGPGCON&0xffffffcf)|0x10); // Master(GPIO_Output)
    rGPGDAT|=0x4; // Activate nSS
    
    
    rSPPRE0=0x19;	//if PCLK=50Mhz,SPICLK=1Mhz
    rSPCON0=(0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);//int,en-SCK,master,high,A,normal
    //rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//int,en-SCK,master,low,B,normal
    rSPPIN0=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
    
    //rGPGDAT&=0xfffffffb; // Activate nSS 
    #else
    rGPGCON=((rGPGCON&0xffff03f3) | (0xf<<12) | (3<<10) | (1<<2));  //SPIMOSI1,SPIMISO1,SPICLK1
    rGPGDAT|=0x2; //EINT9 AS THE CS 
    
    rSPPRE1=0x19;	//if PCLK=50Mhz,SPICLK=1Mhz
    rSPCON1=(0<<5)|(1<<4)|(1<<3)|(0<<2)|(0<<1)|(0<<0);//int,en-SCK,master,high,A,normal
    //rSPCON0=(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);//int,en-SCK,master,low,B,normal
    rSPPIN1=(0<<2)|(1<<1)|(0<<0);//dis-ENMUL,SBO,release
    #endif
}

/*--------------------SPI引脚设定--------------------*/
void MCP2515_SPI_PORT_SET(void)
{
	//rGPGCON=((rGPGCON&0xff3fffcf) | 0x10 | (1<<22));
	//rGPGDAT =  rGPGDAT & (0<<2) & (0<<11);
}

/*--------------------SPI发送单字节数据--------------------*/
void MCP2515_SPI_SendByte(unsigned char data)
{
	#ifdef MCP2515_SPI_0
	rSPTDAT0 = data;
	while(!(rSPSTA0&0x1));
	
	#else
	
	rSPTDAT1 = data;
	while(!(rSPSTA1&0x1));
	#endif
}

/*--------------------SPI接收单字节数据--------------------*/
unsigned char MCP2515_SPI_ReadByte(void)
{
    #ifdef MCP2515_SPI_0
    rSPTDAT0 = 0xff;
    while(!(rSPSTA0&0x1));
    return(rSPRDAT0);
    
    #else
    
    rSPTDAT1 = 0xff;
    while(!(rSPSTA1&0x1));
    return(rSPRDAT1);
    #endif
}

/*--------------------片选信号控制--------------------*/
void MCP2515_CS(unsigned char data)
{
    #ifdef MCP2515_SPI_0
    if(data == 0)
    	rGPGDAT = rGPGDAT & ~(1<<2);
    else
        rGPGDAT |= 0x4;
    
    #else
    if(data == 0)
    	rGPGDAT = rGPGDAT & ~(1<<1);
    else
        rGPGDAT |= 0x2;
    #endif
}

/*--------------------CAN复位操作--------------------*/
void CAN_Reset(void)            //reset CAN controler
{
	MCP2515_CS(0);
	
	MCP2515_SPI_SendByte(CMD_RESET);
	
	MCP2515_CS(1);
}

/*--------------------CAN单命令操作--------------------*/
void CAN_CMD(U8 cmd)            //can command control
{
	MCP2515_CS(0);
	
	MCP2515_SPI_SendByte(cmd);
	
	MCP2515_CS(1);
}

/*--------------------CAN读单个寄存器数据--------------------*/
unsigned char CAN_Read(unsigned char reg_addr)     //read one byte data from register
{   unsigned char temp;
	MCP2515_CS(0);
	
	MCP2515_SPI_SendByte(CMD_READ);        //read command;
	MCP2515_SPI_SendByte(reg_addr);        //read reg address;
	
	temp=MCP2515_SPI_ReadByte();
	MCP2515_CS(1);
	return(temp);
	
	
}

/*--------------------CAN读多个寄存器数据--------------------*/
void CAN_Read_Data(U8 reg_addr, U8* data, U8 d_long)
{
	int ii;
	
	MCP2515_CS(0);
	
	MCP2515_SPI_SendByte(CMD_READ);        //read command;
	MCP2515_SPI_SendByte(reg_addr);        //read reg address;
	
	for(ii=0;ii<d_long;ii++)
	{
		data[ii] = MCP2515_SPI_ReadByte();
	}
	
	MCP2515_CS(1);
}

/*--------------------读状态--------------------*/
unsigned char CAN_Read_State(void)
{   
	unsigned char temp;
    MCP2515_CS(0);
    
    MCP2515_SPI_SendByte(CMD_STATE);          //0xa0
    
    temp=MCP2515_SPI_ReadByte();
    MCP2515_CS(1);
    return (temp);
}

/*--------------------读RX状态--------------------*/
unsigned char CAN_Read_RXState(void)
{   
    unsigned char temp;
    MCP2515_CS(0);
    
    MCP2515_SPI_SendByte(CMD_RXSTATE);       //0xb0
    temp=MCP2515_SPI_ReadByte();
    MCP2515_CS(1);
    return (temp);
}

/*--------------------CAN写单个寄存器数据--------------------*/
void CAN_Write(unsigned char reg_addr, unsigned char data)    //write one byte data to register
{
    MCP2515_CS(0);
    
    MCP2515_SPI_SendByte(CMD_WRITE);
    MCP2515_SPI_SendByte(reg_addr); 
    MCP2515_SPI_SendByte(data);
    
    MCP2515_CS(1);
}

/*--------------------CAN写多个寄存器数据--------------------*/
void CAN_Write_Data(U8 reg_addr, U8* data, U8 d_long)
{
	int ii;
	
	MCP2515_CS(0);
	
	MCP2515_SPI_SendByte(CMD_WRITE);
    MCP2515_SPI_SendByte(reg_addr); 
    
    for(ii=0;ii<d_long;ii++)
    {
    	MCP2515_SPI_SendByte(data[ii]);
    }
	
	MCP2515_CS(1);
}

/*-------------------设置波特率---------------*/
void CAN_SetBaudRate(U8 cnf1, U8 cnf2, U8 cnf3)
{   
    //Baudrate Sync Prop Phase1 Phase2 BRP CNF1 CNF2 CNF3
    //10Kpbs   
    //25Kpbs  
    //50Kpbs     1    9     5     5     7    
    //125Kpbs    1    7     4     4     3  0x03 0x9e 0x03 
    //250Kpbs    1    7     4     4     1  0x01 0x9e 0x03
    //500Kps     1    7     4     4     0  0x00 0x9e 0x03
    //800Kps     1    5     2     2     0  0x00 0x8c 0x01
    //1000Kps    1    3     2     2     0  0x00 0x8a 0x01
    //
    //( 6 <= Tq <= 25 ) 
    //Tq = 1/((Sync+Prop+Phasel+Phase2)*Baudrate)   
    //Tq = 2*(BRP+1)/Fosc
    //BRP = Fosc/(2*Baudrate*(Sync+Prop+Phasel+Phase2))
    //Fosc = 16*10e6     
      
    CAN_Write(CNF1, cnf1); //CNF1
    CAN_Write(CNF2, cnf2); //CNF2
    CAN_Write(CNF3, cnf3); //CNF3   
}

/*-------------------位修改------------------*/
void CAN_Bit_cmd(U8 add, U8 mask, U8 data)
{
    MCP2515_CS(0);
    
    MCP2515_SPI_SendByte(CMD_BIT);
    MCP2515_SPI_SendByte(add);
    MCP2515_SPI_SendByte(mask);
    MCP2515_SPI_SendByte(data);
    
    MCP2515_CS(1);
}

/*-------------------设置工作模式-------------*/
//0x00正常模式,0x80配置模式,0x40环回模式, 
//0x60监听模式, 0x20休眠模式
void CAN_SetMode(U8 workmode)
{
     U8  state;
          
     CAN_Bit_cmd(CANCTRL, 0xe0, workmode);
     state = CAN_Read(CANSTAT);
     
     while(!((state & 0xe0) == workmode))
     {
         state = CAN_Read(CANSTAT);	 
         Delay(1);
     }   
}

void CAN_Init(void)
{
	//int i;
	//U8 dat[30]={0};
	
	MCP2515_SPI_Init();
	MCP2515_FM_Set();
	//////////////////////////////进入配置模式:
	CAN_Reset();
	//CAN_Write(0x0f,0x80);
	CAN_SetMode(CONFIG_MODE);
	//Uart_SendString("config mode!!\n");
	//Uart_Printf("result1 is 0x%x\n",CAN_Read(CANSTAT));
	//////////////////////////////////////
	CAN_Bit_cmd(CANCTRL, 0x1f, 0x00);           //P.58
	///////////////设置通讯波特率//////////////////////////
	CAN_SetBaudRate(0x00,0x9e,0x03);   //500kpbs
	//CAN_SetBaudRate(0x01,0x9e,0x03);   //250kbps
	
	//中断
    CAN_Write(CANINTE, 0x00);       //中断禁止     //P.50
    CAN_Write(CANINTF, 0x00);       //清中断标志   //P.51
	
	//发送
    CAN_Write(TXRTSCTRL, 0x07);          //芯片发送引脚使能设置  //P.19
    CAN_Bit_cmd(TXB0CTRL, 0x03, 0x03);   //TXB0 higher           //P.18
    CAN_Bit_cmd(TXB1CTRL, 0x03, 0x02);   //TXB1 middle
    CAN_Bit_cmd(TXB2CTRL, 0x03, 0x01);   //TXB2 lower
	
	//滤波(数据帧)和屏蔽(接受所有报文)
    CAN_Write_Data(RXF0SIDH, F_M_data0, 12);       //P.34
    CAN_Write_Data(RXF3SIDH, F_M_data1, 12);
    CAN_Write_Data(RXM0SIDH, F_M_data2, 8);
	
	//接受
    //0x60关闭屏蔽和滤波,接受所有报文  //0x01 滚存
    //0x00正常屏蔽滤波
    CAN_Write(RXB0CTRL, 0x21);  //若RXB0满,滚存至RXB1  //0x64  //P.27
    CAN_Write(RXB1CTRL, 0x20);  //只接收符合滤波条件的扩展、标准的有效报文
	
	CAN_Write(BFPCTRL, 0x00);   //接收引脚控制使能   //P.29
	
	//Uart_Printf("result0 is 0x%x\n",CAN_Read(RXM0SIDH));
	//Uart_Printf("result0 is 0x%x\n",CAN_Read(RXM0SIDL));
	//CAN_Write(CANINTE, 0x03); //中断使能
	//进入正常模式
    CAN_SetMode(NORMAL_MODE);
	
	CAN_Write(CANINTE,0x03); //中断使能  CANINTE,0x23
	CAN_Write(CANINTE,0x03); //中断使能
	//CAN_Write(CANINTE,0x03); //中断使能
}

void MCP2515_test(void)
{
	//CAN_Init();
	
	U8 data[8] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01};
	//标准标识符 or 扩展标识符
    //数据帧 or 远程帧
    //标准标识符+扩展标识符+数据帧+数据长度8
	//U8 cmd[6]={0xaa,0xaa,0xaa,0xaa,0x08};    //扩展帧
	U8 cmd[6]={0x69,0x20,0x00,0x00,0x08};    //标准帧
    
    CAN_Write_Data(TXB0SIDH, cmd, 5);
	CAN_Write_Data(TXB0D0, data, 8);
	
	CAN_CMD(CMD_TXB0);   //启动发送
	
}

void MCP2515_FM_Set(void)
{
	F_M_data0[0] = (RXF0>>3) & 0xff;
	F_M_data0[1] = (RXF0 & 0x7)<<5;
	
	F_M_data0[4] = (RXF1>>3) & 0xff;
	F_M_data0[5] = (RXF1 & 0x7)<<5;
	
	F_M_data0[8] = (RXF2>>3) & 0xff;
	F_M_data0[9] = (RXF2 & 0x7)<<5;
	
	F_M_data1[0] = (RXF3>>3) & 0xff;
	F_M_data1[1] = (RXF3 & 0x7)<<5;
	
	F_M_data1[4] = (RXF4>>3) & 0xff;
	F_M_data1[5] = (RXF4 & 0x7)<<5;
	
	F_M_data1[8] = (RXF5>>3) & 0xff;
	F_M_data1[9] = (RXF5 & 0x7)<<5;
	

⌨️ 快捷键说明

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