#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;
}
}