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