我现在在做一个CAN的通信卡,上位机通过CAN发送数据信息,下位机AT89C51根据收到的信息显示不同的数据.由于须控制三片点阵显示,51的口线不够用,需要用8255扩展. 现在的问题是,只要上位机一发信息下来,8255就不能使用,我猜是总线冲突的原因,但找了两天都找不出解决的办法,只好请各位高手帮忙看一下.谢谢了 我大概把我的电路接法说一下 8255和CAN的 D0~D7跟51单片机相连,读 写信号也是直接跟单片机相连. P2.3作为SJA1000的片选,P2.2,P2.1作为8255的A1A0,P2.0是8255的片选. CAN的接收是采用中断 下面是我的程序,望各位高手帮我看看 谢谢了 #include <REG51.H> #include <INTRINS.H> #include <ABSACC.H>
sbit P1_0=P1^0; sbit P1_1=P1^1; sbit P1_2=P1^2; sbit P1_3=P1^3; sbit P1_4=P1^4; sbit P1_5=P1^5; sbit P1_6=P1^6; sbit P1_7=P1^7;
unsigned char DPTR,DAMR[4]={0xff,0xFF,0xFF,0xFF}; unsigned char DACR[4]={0x80,0x00,0x00,0x00}; unsigned char REC_DATA[11]; unsigned char k; #define uint unsigned int #define uchar unsigned char #define ulong unsigned long #define MODE 0X00; #define CMR 0x01; #define SR 0x02; #define IR 0x03; #define IER 0x04; #define ALC 0x0b; #define ECC 0x0c; #define EWLR 0x0d; #define RXERR 0x0e; #define TXERR 0x0f; #define CANTXB 0x10; #define CANRXB 0x10; #define ACR 0x10; #define AMR 0x14; #define RMC 0x1d; #define RBSA 30; #define BTR0 6; #define BTR1 7; #define OCR 8; #define CDR 31; uchar uptable1[]={0x10,0x38,0x7c,0x10,0x10,0x10,0x10}; uchar uptable2[]={0x38,0x7c,0x10,0x10,0x10,0x10,0x10}; uchar uptable3[]={0x7c,0x10,0x10,0x10,0x10,0x10,0x38}; uchar uptable4[]={0x10,0x10,0x10,0x10,0x10,0x38,0x7c}; uchar uptable5[]={0x10,0x10,0x10,0x10,0x38,0x7c,0x10}; uchar uptable6[]={0x10,0x10,0x10,0x38,0x7c,0x10,0x10}; uchar uptable7[]={0x10,0x10,0x38,0x7c,0x10,0x10,0x10};
void int0 () interrupt 0 using 0 { uchar i,j,buffer_data; EA=0; DPTR=IR; buffer_data=XBYTE[DPTR]; if(buffer_data&0x08) { DPTR=CMR; XBYTE[DPTR]=0x0C; goto recout; } if(buffer_data&0x04) { goto out; } if(buffer_data&0x1) { DPTR=CANRXB; REC_DATA[0]=XBYTE[DPTR]; if(REC_DATA[0]&0x40) { DPTR=CMR; XBYTE[DPTR]=0x04; goto recout; } j=(REC_DATA[0]&0x0F)+2; for(i=0;i<j;i++) { DPTR++; REC_DATA[i+1]=XBYTE[DPTR]; } DPTR=CMR; XBYTE[DPTR]=0x04; recout:EA=1; DPTR=ALC; buffer_data=XBYTE[DPTR]; DPTR=ECC; buffer_data=XBYTE[DPTR]; out: _nop_();
}
} void IO_initial() { int k; for(k=0;k<6;k++) { P1_0=0; P1_1=0; P1_0=1;
} }
void delay(void) { unsigned long i; for(i=0;i<50;i++); }
void disp_up(void) { int i; for(i=0;i<7;i++) { int k; for(k=0;k<5;k++) { P1_0=0; P1_1=1; P1_0=1; P1=P1|uptable1; delay(); P1=0; P1_0=0; P1_1=0; P1_0=1; P1=P1|uptable2; delay(); P1=0; P1_0=0; P1_1=0; P1_0=1; P1=P1|uptable3; delay(); P1=0; P1_0=0; P1_1=0; P1_0=1; P1=P1|uptable4; delay(); P1=0; P1_0=0; P1_1=0; P1_0=1; P1=P1|uptable5; delay(); P1=0; P1_0=0; P1_1=0; P1_0=1; P1=P1|uptable6; delay(); P1=0; P1_0=0; P1_1=0 ; P1_0=1; P1=P1|uptable7; delay(); } } } void initial(void) {unsigned char i,buffer_data=0; //89c51的初始化 EA=0;//关中断
//以下是对SJA1000的初始化 SJA1000_CS=1;//选通SJA1000
DPTR=MODE;//方式寄存器 XBYTE[DPTR]=0x09;//进入复位模式,对SJA1000进行初始化 k=XBYTE[DPTR];
DPTR=CDR;//时钟分频寄存器 XBYTE[DPTR]=0x88;//选择PeliCAN模式,关闭时钟输出(CLKOUT) //k=XBYTE[DPTR];
DPTR=IER;//中断允许寄存器 XBYTE[DPTR]=0xF;//开放接收和发送中断、溢出中断、错误警告中断 k=XBYTE[DPTR];
DPTR=AMR;//验收屏蔽寄存器 for(i=0;i<4;i++) { XBYTE[DPTR]=DAMR; k=XBYTE[DPTR]; DPTR++; }
DPTR=ACR;//验收代码寄存器????????????????????????????????????? for(i=0;i<4;i++) { XBYTE[DPTR]=DACR; _nop_(); DACR=XBYTE[DPTR]; k=XBYTE[DPTR]; DPTR++; }
DPTR=BTR0;//总线时序寄存器0 XBYTE[DPTR]=0X03; k=XBYTE[DPTR]; DPTR=BTR1;//总线时序寄存器1 XBYTE[DPTR]=0X8d;//16MHz ;晶振情况下设置波特率为80kbps. k=XBYTE[DPTR];
DPTR=OCR; //输出控制寄存器 XBYTE[DPTR]=0XAA; k=XBYTE[DPTR];
DPTR=RBSA;//接收寄存器FIFO的起始地址 XBYTE[DPTR]=0x00; k=XBYTE[DPTR];
DPTR=TXERR;//发送错误计数器 XBYTE[DPTR]=0x00; k=XBYTE[DPTR];
DPTR=RXERR;//接收错误计数器 XBYTE[DPTR]=0x00; k=XBYTE[DPTR];
DPTR=ECC;//错误代码捕捉寄存器 buffer_data=XBYTE[DPTR];
DPTR=ALC;//仲裁丢失捕捉寄存器 buffer_data=XBYTE[DPTR];
DPTR=CMR; XBYTE[DPTR]=0X04;//释放接收缓冲区 buffer_data=XBYTE[DPTR];
DPTR=MODE; XBYTE[DPTR]=0X08; buffer_data=XBYTE[DPTR]; }
void send(void) {;}
void alarm(void) {;}
void main(void) {initial(); EA=1; //中断总允许 EX0=1;//允许外部中断0 IT0=1;//电平触发方式,低电平有效
IO_initial();
while(1) { receive(); while((REC_DATA[0]&0x80)==0x00) { disp_up(); receive(); } P1=0; } }
|