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