看起来,SJA1000的BASIC模式没有自测试方式,也就是独立节点的BASIC模式由于没有STM位的设置而不能产生发送中断。这样,一旦节点启动发送,就将不停地重发,使TXERR超过127而产生EI中断,进入迟缓状态,仍然重发不停。
AT命令可以终止节点的重发状态,清除TR,使TBS发送缓冲器状态SR.2由锁定变为释放,这正是一个发送中断触发条件!
因此,下面这段程序,利用AT(CMR=02)命令产生发送中断,并且在中断程序中进行接收。由于CAN控制器的特殊结构,发送的帧信息必然进入接收缓存,所以调试时,观察SJA1000地址20的内容,一定与10内容一样。否则就是软件/硬件(很少故障)设置有问题,主要查OCR寄存器设置内容,......
程序与PELI自测试功能比较,缺陷为不能测试ACR/AMR的作用/设置正确与否。
#pragma SMALL #include<reg51.h> #include<sjaregb.h>
#define uchar unsigned char
uchar xdata *SJA_Adr=0x7f00; #define can_read(RegAdr) SJA_Adr[RegAdr] #define can_write(RegAdr,Val) SJA_Adr[RegAdr]=Val
uchar Tbuffer[10]={0x55,0x08,0x41,0x42,0x43,0x44,0x45,0x48,0x49},Rbuffer[10];
bdata uchar TK; bdata uchar RK; bdata uchar MK; sbit ANold=TK^0;
sbit RBF=MK^1;
sbit ANnew=RK^0;
sbit AN=P1^3; sbit LED0=P1^0; sbit LED1=P1^1; sbit LED2=P1^2;
void initial() { uchar c; can_write(CR,0x41); //复位模式 can_write(CDR,0x4f); can_write(OC,0x1a); can_write(BTR0,0x05); can_write(BTR1,0xff); can_write(ACR,0x55); can_write(AMR,0x00);
can_write(CR,0x04); //操作模式,发送中断允许,关闭EI中断。
void send() //发送函数 { uchar j,TBS; TBS=10; for (j=0;j<10;j++) { can_write(TBS++,TXdata[j]); } can_write(CMR,0x01); }
void receive() //接收函数 { uchar j,RBS; RBS=20; for (j=0;j<10;j++) { RXdata[j]=can_read(RBS++); } can_write(CMR,4); RBF=0; }
void delay(uchar abc) { while(--abc); }
void main(void) { uchar c; LED0=0; RBF=0; ANold=AN; initial(); TCON=0x05; IE=0x81;
while(1) { while(AN==ANold); //按键变化一次,发送一次 delay(20); //消抖动 ANold=AN; Tbuffer[4]=TK;
send(); //发送 delay(10); can_write(CMR,0x02); // AT命令产生发送中断 } }
void int0(void) interrupt 0 using 0 { uchar c; LED1=!LED1; c=can_read(IR); // 清除中断 RBF=1; receive(); 接收 RK=Rbuffer[4]; LED2=ANnew; } |