📄 ican-mcp251500.c
字号:
////////////////////////
#include "includes.h"
#include"ytep.h"
#include"can.h"
////////////////////////
//------------------------------------
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");
Set_bit(IO_mSCK,mSCK); //mSCK = 1; //Pulse clock // mSCK = 0; //
asm("nop");
asm("nop");
asm("nop");
asm("nop");
Clr_bit(IO_mSCK,mSCK);
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;
if(Get_bit(IO_mSO,mSO))DataIn|=1;
else DataIn&=0xfe;
DataIn = (DataIn << 1);
Clr_bit(IO_mSCK,mSCK); //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,Int16U *p)
{
unsigned char x,y;
CANS->SiIDH=*(p+C_PrductADD);//发送的标准标识符滤波10-3
CANS->SiIDL=0;
if(CANx->SiIDH&0X20)CANS->SiIDL|=0x20;//标准标识符滤波位0,IDH的b5与IDL的b5
CANS->SiIDL|=8; //mcp2515报文滤波用于0=标准帧1=扩展帧//本应用中为扩展帧
x=(CANx->SiIDH&0X18);//扩展符16/17
x>>=3;
CANS->SiIDL|=x;//目标节点b4b3位
x=CANx->SiIDH&0X7;
x<<=5;
CANS->EIDM=0;
CANS->EIDM|=x; //目标节点低3位放入EID8中
CANS->EIDM|=0x10;//应答
CANS->EIDM|=CANx->CANFUN;//功能码
CANS->EIDL=CANx->EIDL; //资源节点 8位 //CAN.EIDL start address ,CAN.DATA[0] len
CANS->DLC=0;
x=CANx->EIDL*2; //起始地址
p+=x;
for(x=0;(x<4)&&(CANx->DATA[0]!=0);x++)//CAN.DATA[0]数据长度
{
CANS->DLC++;
y=2*x;
CANS->DATA[y]=*p/256;
CANS->DATA[y+1]=*p&0xff;
x++,p++;
CANx->EIDL++;
CANx->DATA[0]--;
}
if(CANx->DATA[0]==0)CANS->SiIDL|=0xc0; // 数据发完时C0
}
//---------------------------------------------------------
//---------------------------------------------------------
WriteCAN(CAN_BUS *WCAN,unsigned char c)
{
unsigned char c1,c2;
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]);
SPIByteWrite(TXB0CTRL,8);
}
/////////////////////////////////////////////////////////////
void Init2515(void)
{
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,0xA0);//验收滤波器H位
SPIByteWrite(RXF0SIDL,0xe8);//验收滤波器L位
SPIByteWrite(RXF0EID8,0xff);//验收滤波器扩展8~15位
SPIByteWrite(RXF0EID0,0xa8);//验收滤波器扩展0-7位
//Set CNF1
SPIByteWrite(CNF1,CAN_10kbps);//分频
//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); //
i = SPIByteRead(TXB0SIDH);//中断代码
delay_nop(100);
//Set NORMAL mode
SPIByteWrite(CANCTRL,REQOP_NORMAL | CLKOUT_ENABLED);//正常工作+时钟开
//Verify device entered Normal mode
i = SPIByteRead(CANSTAT);//中断代码
if (OPMODE_NORMAL != (i && 0xE0))
SPIByteWrite(CANCTRL,REQOP_NORMAL | CLKOUT_ENABLED);
SPIByteWrite(TXB0CTRL, 0);//无报文,清0
while(SPIByteRead(CAN_RD_STATUS)&0x54)WWDG_ClearFlag();//快速读,清空发
}
//-----------------------------------------------------------
void Read2551(unsigned char *R)
{
*R=SPIByteRead(RXB0SIDH);
*++R=SPIByteRead(RXB0SIDL);
*++R=SPIByteRead(RXB0EID8);
*++R=SPIByteRead(RXB0EID0);
*++R=SPIByteRead(RXB0DLC);
*++R=SPIByteRead(RXB0D0);
*++R=SPIByteRead(RXB0D1);
*++R=SPIByteRead(RXB0D2);
*++R=SPIByteRead(RXB0D3);
*++R=SPIByteRead(RXB0D4);
*++R=SPIByteRead(RXB0D5);
*++R=SPIByteRead(RXB0D6);
*++R=SPIByteRead(RXB0D7);
}
//-----------------------------------------------------------------------------
// 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,Int16U *p)//发送操作
{
unsigned char x,xdata;
xdata=SPIByteRead(CAN_RD_STATUS);//读指令,快速读
if(CANx->CANFUN==1)return 0;
if(1)//CANx.CANFUN==2)
{
if((xdata&0x54)==0x54)return 0xff;
if((xdata&4)==0)
{
ConfCAN(CANx,CANS,p);
WriteCAN(CANS,TXB0SIDH);
return 0;
}
if((xdata&0x10)==0)
{
ConfCAN(CANx,CANS,p);
WriteCAN(CANS,TXB1SIDH);
}
if((xdata&0x40)==0)
{
ConfCAN(CANx,CANS,p);
WriteCAN(CANS,TXB2SIDH);
}
if(CANx->CANlen==0)return 0;
else return 1;
}
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();
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;
}
//------------------------------------------------
unsigned char ReadCAN(CAN_BUS CANx,unsigned char FLAG)
{
unsigned char x;
unsigned int xdata;
xdata=SPIByteRead(CAN_RD_STATUS);//读指令,快速读
if(xdata&0x1)
{
SPIByteWrite(CANINTF,0);
Read2551(&CANx.SiIDH);
x=CANx.CANFUN;
if(x>=0x0f)CANx.EIDM=0X0F,CANx.EIDL=0X1;
if((x==1)||(x==2))
{
xdata=CANx.EIDL+(CANx.CANlen);
if(xdata>c_max_len)
{
CANx.EIDM|=0XF,CANx.EIDL=0XFE;
}
}
return 1;
}else
return FLAG;
}
//-----------------------------------------------------------
//UART
//-----------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -