#include <reg51f.h>
#include <absacc.h>
#include <intrins.h>
#define BYTE unsigned char
#define uint unsigned int
#define uchar unsigned char
#define baseadd 0x8000
#define baseadd1 0x1000
uchar m;
uchar rec_flg;
uchar time_50ms;
uchar readdram_over;
uchar txbuf[8]={0};
uchar rxbuf[8]={0,0,0,0,0,0,0,0};
uchar buf[36]={5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0};
sbit t1=P1^5;
sbit t2=P1^6;
sbit t3=P1^7;
void readdram( );
void delay(uint us);
void init_can( );
uchar CANsend(uchar portadd,uchar *value,uchar id1,uchar id2);
BYTE readdata(uchar portaddr);
void writedata(uchar portaddr,uchar value);
void main( )
{
TMOD=0x21;
TH0=0x4C;
TL0=0x00;//定時計數器0工作在定時方式1,50定時初裝。
ET0=1;
TR0=1;
IT1=0;//外部中斷為電平觸發方式。
EX1=1;//使能外部中斷1。
EA=1;
t1=0;
t2=0;
t3=0;
delay(5);
init_can( );
while(1)
{
if(time_50ms==1)
{
m=rxbuf[0];
time_50ms=0;
if(rec_flg==1)
{
rec_flg=0;
readdram();
}
if(readdram_over==1)
{
readdram_over=0;
CANsend(19,buf,1,m);
delay(25);
CANsend(19,buf+6,2,m);
delay(25);
CANsend(19,buf+12,3,m);
delay(25);
CANsend(19,buf+18,4,m);
delay(25);
CANsend(19,buf+24,5,m);
delay(25);
CANsend(19,buf+30,6,m);
delay(25);
rxbuf[0]=0xff;
t1=~t1;
}
}
}
}
/********************SJA1000讀函數**************************/
BYTE readdata(uchar portaddr)
{
return XBYTE[baseadd+portaddr];
}
/********************SJA1000寫函數**************************/
void writedata(uchar portaddr,uchar value)
{
XBYTE[baseadd+portaddr]=value;
}
/******************SJA1000初始化函數************************/
void init_can( )
{
uchar mode;
mode=readdata(0);
mode|=0x01;
do
{
delay(5);
writedata(baseadd,mode);
}
while(!(readdata(baseadd)&1));
delay(5);
writedata(31,0xc4);//將CAN置為pelican,clk引腳2MHZ。
writedata(16,0x00);
writedata(17,0x00);
writedata(18,0x00);
writedata(19,0x00);//驗收代碼寄存器置為0;
writedata(20,0xff);
writedata(21,0xff);
writedata(22,0xff);
writedata(23,0xff);//驗收屏蔽寄存器配置為1
writedata(6,0x00);
writedata(7,0x1C);//配置總線波特率為500K
writedata(8,0xaa);//寫輸出控制寄存器
writedata(4,7);//中斷使能
do
{
delay(5);
mode=0x08;
writedata(0,mode);
}
while(!readdata(0));
}
/*********************延時函數*****************************/
void delay(uint us) //一個時間單位大約20us。
{
while(us--)
{
_nop_( );
}
}
/*********************SJA1000中斷接收函數*****************/
void CANrec(void) interrupt 2
{
uchar IR,i;
EX1=0;
IE1=0;
IR=readdata(3);
if(IR&0x01)
{
for(i=0;i<8;i++)
{
rxbuf[i]=readdata(19+i);
}
delay(15);
writedata(1,0x04);
}
rec_flg=1;
EX1=1;
}
/*************************SJA1000發送函數********************/
uchar CANsend(uchar portadd,uchar *value,uchar id1,uchar id2)
{
uchar i;
writedata(16,0x08);
writedata(17,0x10);
writedata(18,0x00);
XBYTE[baseadd+portadd]=id1;
XBYTE[baseadd+portadd+1]=id2;
for(i=0;i<6;i++)
{
XBYTE[baseadd+portadd+2+i]=*(value+i);
}
writedata(1,1);
//while(!readdata(2));
return 1;
}
/*************************定時器0中斷函數************************/
void time0( ) interrupt 1
{
time_50ms=1;
ET0=0;
TR0=0;
TH0=0x4C;
TL0=0x00;
delay(1);
ET0=1;
TR0=1;
}
/**************************單片機讀雙口RAM*********************/
void readdram( )
{
uchar i;
if(rxbuf[0]==0x20)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0x40+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x21)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0x80+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x22)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0xC0+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x23)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0x100+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x24)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0x140+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x25)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0x180+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x26)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0x1C0+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x27)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0x200+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x28)
{
for(i=0;i<32;i++)
{
buf[i]=XBYTE[baseadd1+0x240+i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x10)
{
for(i=0;i<8;i++)
{
XBYTE[baseadd1+0x280+i]=txbuf[i];
}
readdram_over=1;
}
else if(rxbuf[0]==0x29)
{
for(i=0;i<8;i++)
{
buf[i]=XBYTE[baseadd1+0x2C0+i];
}
readdram_over=1;
}
else
{
readdram_over=0;
}
}