📄 ican-mcp2515.c.bak
字号:
////////////////////////
#include "includes.h"
#include"ytep.h"
#include"can.h"
const Int8U CAN_BAUD[]={1,4,18};
////////////////////////
//------------------------------------
void WriteSPI(unsigned char DataOut)
{
unsigned char n;
Clr_bit(IO_mSCK,mSCK) ; //Make sure clock is low
for(n=0; n<8; n++)
{
if((DataOut << n) & 0x80)Set_bit(IO_mSI,mSI); //mSII = 1;
else Clr_bit(IO_mSI,mSI) ; //Clock a 0
asm("nop");
asm("nop");
asm("nop");
Set_bit(IO_mSCK,mSCK); //mSCK = 1; //Pulse clock // mSCK = 0; //
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
Clr_bit(IO_mSCK,mSCK);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
Clr_bit(IO_mSI,mSI) ;
}
}
/********************************************************************/
unsigned char ReadSPI( void )
{
unsigned char n, DataIn = 0;
Clr_bit(IO_mSCK,mSCK); //mSCK = 0; //Make sure clock is low
for(n=0; n<7; n++)
{
Set_bit(IO_mSCK,mSCK) ; //mSCK = 1;
asm("nop");
asm("nop");
if(Get_bit(IO_mSO,mSO))DataIn|=1;
else DataIn&=0xfe;
DataIn = (DataIn << 1);
Clr_bit(IO_mSCK,mSCK);
asm("nop");
asm("nop");//mSCK = 0;
}
Set_bit(IO_mSCK,mSCK); //mSCK = 1;
if(Get_bit(IO_mSO,mSO))DataIn|=1;
else DataIn&=0xfe; //DataIn = DataIn + mSI;
Clr_bit(IO_mSCK,mSCK); // mSCK = 0;
return DataIn;
}
//-------------------------------------------------------------
//-------------------------------------------------------------------------
// SPIByteWrite()
//-------------------------------------------------------------------------
void SPIByteWrite(unsigned char addr, unsigned char value )
{
Clr_bit(IO_CS,mCS) ; //mCS = LOW;
WriteSPI(CAN_WRITE);
WriteSPI(addr);
WriteSPI(value);
Set_bit(IO_CS,mCS); //mCS = HIGH;;
}
//-----------------------------------------------------------------------------
// SPIByteRead()
//-----------------------------------------------------------------------------
unsigned char SPIByteRead(unsigned char addr)
{
unsigned char tempdata;
Clr_bit(IO_CS,mCS); //mCS = LOW;;
WriteSPI(CAN_READ);
WriteSPI(addr);
tempdata = ReadSPI();
Set_bit(IO_CS,mCS); //mCS = HIGH;;
return tempdata;
}
//-----------------------------------------------------------------------------
// SPIReset()
//-----------------------------------------------------------------------------
void SPIReset(void)
{
Clr_bit(IO_CS,mCS);//mCS = LOW;
WriteSPI(CAN_RESET);
Set_bit(IO_CS,mCS);
}
//-----------------------------------------------------------------------------
//----------------------------------------------------
void ConfCAN(CAN_BUS *CANx,volatile CAN_BUS *CANS,const Int16U *p)
{
unsigned char x,y;
CANS->SiIDH=*(p+C_PrductADD);//发送的标准标识符滤波10-3 ,产品地址
CANS->SiIDL=0;
if(CANx->SiIDL&0Xe0)CANS->SiIDL|=0xe0;//功能码.标准标识符滤波位0,IDH的b5与IDL的b5
CANS->SiIDL|=8; //mcp2515报文滤波用于0=标准帧1=扩展帧//本应用中为扩展帧
CANS->EIDM=CANx->EIDM&0xc0;//通讯类型
CANS->EIDM|=CANx->SiIDH&0X3F;
CANS->EIDL=CANx->EIDL;
//CAN.EIDL start address ,CAN.DATA[0] len
CANS->DLC=0;
x=CANx->EIDL; //起始地址
p+=x;
for(x=0;(x<4)&&(CANx->DATA[0]!=0);x++)//CAN.DATA[0]数据长度
{
y=2*x;
CANS->DATA[y]=*p/256,CANS->DLC++;;
CANS->DATA[y+1]=*p&0xff,CANS->DLC++;;
p++;
CANx->EIDL++;
if(CANx->DATA[0]>=1)CANx->DATA[0]--;
else CANx->DATA[0]=0;
}
if(CANx->DATA[0]==0)CANS->SiIDL|=0x3; // 数据发完时C0
else CANS->SiIDL|=0X1;
#if 0
CANS->SiIDH=0XAA;
CANS->EIDM=0XAA;
CANS->EIDL=0X1;
CANS->DLC=0;
CANS->DATA[0]=0XBB;
CANS->DATA[1]=0X7F;
CANS->DATA[2]=0X7F;
CANS->DATA[3]=0X7F;
CANS->DATA[4]=0X7F;
CANS->DATA[5]=0X7F;
CANS->DATA[6]=0X7F;
CANS->DATA[7]=0X7F;
CANS->SiIDL=8;
#endif
}
//---------------------------------------------------------
//---------------------------------------------------------
WriteCAN(const CAN_BUS *WCAN,unsigned char c)
{
unsigned char c1,c2,c3;
c3=c;
SPIByteWrite(c,WCAN->SiIDH);
SPIByteWrite(++c,WCAN->SiIDL);
SPIByteWrite(++c,WCAN->EIDM);
SPIByteWrite(++c,WCAN->EIDL);
SPIByteWrite(++c,WCAN->DLC);
c1=WCAN->DLC&0xf;
for(c2=0;c2<c1;c2++)
SPIByteWrite(++c,WCAN->DATA[c2]);
if(c3==TXB0SIDH)SPIByteWrite(TXB0CTRL,8);
else if(c3==TXB1SIDH)SPIByteWrite(TXB1CTRL,8);
else if(c3==TXB2SIDH)SPIByteWrite(TXB2CTRL,8);
}
/////////////////////////////////////////////////////////////
void Init2515(Int8U m)
{
Int8U i;
SPIReset();
delay_nop(100);
SPIByteWrite(RXB0CTRL,0x00);//清RXB0
//Clear masks to RX all messages
SPIByteWrite(RXM0SIDH,0x00);//标准标识低位
SPIByteWrite(RXM0SIDL,0x00);//标准标识高位
//Clear filter... really only concerned to clear EXIDE bit
SPIByteWrite(RXF0SIDH,0x00);//验收滤波器H位
SPIByteWrite(RXF0SIDL,0x08);//验收滤波器L位
SPIByteWrite(RXF0EID8,0x3F);//验收滤波器扩展8~15位
SPIByteWrite(RXF0EID0,0x0);//验收滤波器扩展0-7位
//Set CNF1
m=CAN_RATE_TAB[m];
SPIByteWrite(CNF1,m);//分频CAN_125kbps
//Set CNF2
SPIByteWrite(CNF2,0x80 | PHSEG1_3TQ | PRSEG_1TQ);
//Set CNF3
SPIByteWrite(CNF3, PHSEG2_3TQ);
//Set TXB0 DLC and Data for a "Write Register" Input Message to the MCP25020
SPIByteWrite(TXB0SIDH,0xA0); //发送器标识符高位
SPIByteWrite(TXB0SIDL,0xe8); //
SPIByteWrite(TXB0EID8,0XFF); //发送器扩展8-15位
SPIByteWrite(TXB0EID0,0XA8);
SPIByteWrite(TXB0DLC,DLC_3);// 发送数据字节长度,0-8字节
SPIByteWrite(TXB0D0,0x6); //发送器发送数据D0
SPIByteWrite(TXB0D1,0xff); //D1 = Mask = 0x10
SPIByteWrite(TXB0D2,0xff);
//Set TXB1 DLC and Data for a "READ I/O IRM"
SPIByteWrite(TXB1SIDH,0x50); //Set TXB0 SIDH
SPIByteWrite(TXB1SIDL,0x00); //Set TXB0 SIDL
SPIByteWrite(TXB1DLC,0x40 | DLC_8); //Set DLC = 3 bytes and RTR bit
//Interrupt on RXB0 - CANINTE
SPIByteWrite(CANINTE,0x01); //
delay_nop(100);
i=SPIByteRead(RXF0EID8);
SPIByteWrite(CANCTRL,REQOP_NORMAL | CLKOUT_DISABLE);//正常工作+时钟开
i = SPIByteRead(CANSTAT);//中断代码
SPIByteWrite(TXB0CTRL, 0);//无报文,清0
while(SPIByteRead(CAN_RD_STATUS)&0x54)WWDG_ClearFlag();//快速读,清空发
SPIByteWrite(CANINTF,0);
}
//-----------------------------------------------------------
void Read2551(CAN_BUS *RCAN,unsigned char x)
{
RCAN->SiIDH=SPIByteRead(x);
RCAN->SiIDL=SPIByteRead(++x);
RCAN->EIDM=SPIByteRead(++x);
RCAN->EIDL=SPIByteRead(++x);
RCAN->DLC=SPIByteRead(++x);
RCAN->DATA[0]=SPIByteRead(++x);
RCAN->DATA[1]=SPIByteRead(++x);
RCAN->DATA[2]=SPIByteRead(++x);
RCAN->DATA[3]=SPIByteRead(++x);
RCAN->DATA[4]=SPIByteRead(++x);
RCAN->DATA[5]=SPIByteRead(++x);
RCAN->DATA[6]=SPIByteRead(++x);
RCAN->DATA[7]=SPIByteRead(++x);
}
//-----------------------------------------------------------------------------
// RTS(buffer)
// buffer = CAN_RTS_TXBn; where 'n' = 0, 1, 2
// buffer = CAN_RTS; followed by | 0 - 7 (e.g., CAN_RTS | 7)
//发送操作,buffer分出是那个发送器
//-----------------------------------------------------------------------------
Boolean RTS(CAN_BUS *CANx,CAN_BUS *CANS,const Int16U *p)//发送操作
{
unsigned char x,xdata;
xdata=SPIFastRead(CAN_RD_STATUS);//读指令,快速读
CANx->SiIDL=0;
if((CANx->CANFUN)==C_CAN_READ)
{
if((xdata&0x04)==0x04)return 0xff;
ConfCAN(CANx,CANS,p);
if((xdata&4)==0)WriteCAN(CANS,TXB0SIDH);
else if((xdata&0x10)==0)WriteCAN(CANS,TXB1SIDH);
else if((xdata&0x40)==0)WriteCAN(CANS,TXB2SIDH);
x=CANx->CANlen;
if(x==0)return 0;
else return 1;
}
if((CANx->CANFUN)==C_CAN_WRITE)
{
}
if((CANx->CANFUN)==C_CAN_ERROR&&(xdata&4)==0)
{
CANS->SiIDH=*(p+C_PrductADD);//发送的标准标识符滤波10-3 ,产品地址
CANS->SiIDL=0xE0;//功能码.标准标识符滤波位0,IDH的b5与IDL的b5
CANS->SiIDL|=8; //mcp2515报文滤波用于0=标准帧1=扩展帧//本应用中为扩展帧
CANS->SiIDL|=1;
CANS->EIDM=CANx->EIDM&0x80;//通讯类型
CANS->EIDM|=CANx->SiIDH&0X7F;
CANS->EIDL=CANx->EIDL; //CAN.EIDL start address ,CAN.DATA[0] len
CANS->DLC=0;
if((xdata&4)==0)WriteCAN(CANS,TXB0SIDH);
else if((xdata&0x10)==0)WriteCAN(CANS,TXB1SIDH);
else if((xdata&0x40)==0)WriteCAN(CANS,TXB2SIDH);
return 0;
}
if((CANx->CANFUN)==3)
{
}
if((CANx->CANFUN)==4)
{
if(xdata&4) return 0xff;
CANS->SiIDL=0;
if(CANx->SiIDH&0X20)CANS->SiIDL|=0x20;
CANS->SiIDL|=8;
x=(CANx->SiIDH&0X18);
x>>=3;
CANS->SiIDL|=x;
x=CANx->SiIDH&0X7;
x<<=5;
CANS->EIDM=0;
CANS->EIDM|=x;
CANS->EIDM|=0x10;
CANS->EIDM|=(CANx->CANFUN);
CANS->EIDL=0XF7;
CANS->DLC=1;
WriteCAN(CANS,TXB0SIDH);
return 0;
}
if((CANx->CANFUN)==5);
if(((CANx->CANFUN)==6)||((CANx->CANFUN))==0XF)
{
if(xdata&4) return 0xff;
Init2515(_YT._Rate);
CANS->SiIDL=0;
if(CANx->SiIDH&0X20)CANS->SiIDL|=0x20;
CANS->SiIDL|=8;
x=(CANx->SiIDH&0X18);
x>>=3;
CANS->SiIDL|=x;
x=CANx->SiIDH&0X7;
x<<=5,CANS->EIDM=0;
CANS->EIDM|=x;
CANS->EIDM|=0x10;
CANS->EIDM|=(CANx->CANFUN); //6 or 0X0F
CANS->EIDL=CANx->EIDL; //F7 FE
CANS->DLC=1;
if((xdata&4)==0)
WriteCAN(CANS,TXB0SIDH);
return 0;
}
if((CANx->CANFUN)==7);
{
}
return 0;
}
SPIFastRead(unsigned char m)
{
unsigned char tempdata;
Clr_bit(IO_CS,mCS); //mCS = LOW;;
WriteSPI(m);
tempdata = ReadSPI();
Set_bit(IO_CS,mCS); //mCS = HIGH;;
return tempdata;
}
SPIFastWrite()
{
}
//------------------------------------------------
unsigned char ReadCAN(CAN_BUS *CANx,unsigned char FLAG,const unsigned char address)
{
unsigned char x;
unsigned int xdata;
if(Get_bit(mIO_INT,mINT))return FLAG; //周立功的有个bug,扩展帧b0-7在发04时无法发正确
xdata=SPIFastRead(CAN_RD_STATUS);//读指令,快速读
SPIByteWrite(CANINTF,0);
if((xdata&1)==0)return FLAG;
x=SPIByteRead(RXB0EID8);//扩展b8-15
x&=0x7f;
if(x!=address)return FLAG;
Read2551(CANx,RXB0SIDH);
x=(CANx->CANFUN);
x>>=5;
if((x==1)||(x==0))//Read and write
{
xdata=CANx->EIDL+(CANx->CANlen);//EIDL起始地址值
if(xdata>c_max_len)
{
CANx->SiIDL|=0XE0,CANx->EIDL=0XFE;
}
}
if(((CANx->DLC&7)==0)&&(x<2))CANx->SiIDL|=0XE0,CANx->EIDL=0XFE;
return 1;
return FLAG;
}
//-----------------------------------------------------------
//UART
//-----------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -