📄 mcp2515.c
字号:
#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 + -