?? mcp2515.c
字號(hào):
#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引腳設(shè)定--------------------*/
void MCP2515_SPI_PORT_SET(void)
{
//rGPGCON=((rGPGCON&0xff3fffcf) | 0x10 | (1<<22));
//rGPGDAT = rGPGDAT & (0<<2) & (0<<11);
}
/*--------------------SPI發(fā)送單字節(jié)數(shù)據(jù)--------------------*/
void MCP2515_SPI_SendByte(unsigned char data)
{
#ifdef MCP2515_SPI_0
rSPTDAT0 = data;
while(!(rSPSTA0&0x1));
#else
rSPTDAT1 = data;
while(!(rSPSTA1&0x1));
#endif
}
/*--------------------SPI接收單字節(jié)數(shù)據(jù)--------------------*/
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
}
/*--------------------片選信號(hào)控制--------------------*/
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復(fù)位操作--------------------*/
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讀單個(gè)寄存器數(shù)據(jù)--------------------*/
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讀多個(gè)寄存器數(shù)據(jù)--------------------*/
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);
}
/*--------------------讀狀態(tài)--------------------*/
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狀態(tài)--------------------*/
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寫單個(gè)寄存器數(shù)據(jù)--------------------*/
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寫多個(gè)寄存器數(shù)據(jù)--------------------*/
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);
}
/*-------------------設(shè)置波特率---------------*/
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);
}
/*-------------------設(shè)置工作模式-------------*/
//0x00正常模式,0x80配置模式,0x40環(huán)回模式,
//0x60監(jiān)聽模式, 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();
//////////////////////////////進(jìn)入配置模式:
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
///////////////設(shè)置通訊波特率//////////////////////////
CAN_SetBaudRate(0x00,0x9e,0x03); //500kpbs
//CAN_SetBaudRate(0x01,0x9e,0x03); //250kbps
//中斷
CAN_Write(CANINTE, 0x00); //中斷禁止 //P.50
CAN_Write(CANINTF, 0x00); //清中斷標(biāo)志 //P.51
//發(fā)送
CAN_Write(TXRTSCTRL, 0x07); //芯片發(fā)送引腳使能設(shè)置 //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
//濾波(數(shù)據(jù)幀)和屏蔽(接受所有報(bào)文)
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關(guān)閉屏蔽和濾波,接受所有報(bào)文 //0x01 滾存
//0x00正常屏蔽濾波
CAN_Write(RXB0CTRL, 0x21); //若RXB0滿,滾存至RXB1 //0x64 //P.27
CAN_Write(RXB1CTRL, 0x20); //只接收符合濾波條件的擴(kuò)展、標(biāo)準(zhǔn)的有效報(bào)文
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); //中斷使能
//進(jìn)入正常模式
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};
//標(biāo)準(zhǔn)標(biāo)識(shí)符 or 擴(kuò)展標(biāo)識(shí)符
//數(shù)據(jù)幀 or 遠(yuǎn)程幀
//標(biāo)準(zhǔn)標(biāo)識(shí)符+擴(kuò)展標(biāo)識(shí)符+數(shù)據(jù)幀+數(shù)據(jù)長度8
//U8 cmd[6]={0xaa,0xaa,0xaa,0xaa,0x08}; //擴(kuò)展幀
U8 cmd[6]={0x69,0x20,0x00,0x00,0x08}; //標(biāo)準(zhǔn)幀
CAN_Write_Data(TXB0SIDH, cmd, 5);
CAN_Write_Data(TXB0D0, data, 8);
CAN_CMD(CMD_TXB0); //啟動(dòng)發(fā)送
}
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;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -