就算感觉我的问题太小白 也骂我两下当帮顶呀
贴上我加了校验后的程序: #define Motobus P6 //步进电机指令线数据/地址口
sbit MotoR_W=P0^2; //步进电机读/写线,=1为主机读,=0为主机写 sbit MotoD_A=P0^3; //步进电机数据/地址线,=1为数据,=0为地址 sbit MotoClock=P0^4; //步进电机指令口指令跳变信号
void PORT_Init(void) { XBR2=0x40; P1MDOUT=0x00; P0MDOUT=0x00; P2MDOUT=0x01; P3MDOUT=0xf0; P74OUT=0x00; }
void Mwait(unsigned int t) { unsigned int i=0; unsigned char n; for(i=0;i<t;i++) { for(n=0;n<50;n++) { if((MotoR_W==1)&&(MotoD_A==1)) {n=50;i=t;} //子机反馈则跳出等待 } } }
Moto(步数、方向、子机ID等参数) { bit iEA; iEA=EA; EA=0; //为了防止中断的干扰,禁中断 ....... ...... ......//根据参数赋值给数组计算Cdata[0]~Cdata[5]
//计算Cdata[0]~Cdata[5]中1的总数,赋值给Cdata[6] CUN=0; for(i=0;i<=5;i++) { ACC=Cdata; tmp=1; for(ii=1;ii<=8;ii++) { ACC=Cdata; CCY=ACC&tmp;if(CCY==1) CUN++; tmp*=2; } } Cdata[6]=CUN; //校验字 Cdata[7]=0xee;//结束字
//正式开始发送 for(CUN=1;CUN<=10;CUN++) //发送次数计数,最多发送10次,10次仍发送失败返回失败码 { Motobus=Cdata[0]; _nop_();_nop_();
//写地址 MotoR_W=0; MotoD_A=0; MotoClock=0; SmotoDelay(100);
MotoClock=!MotoClock; SmotoDelay(100); Motobus=Cdata[1];
SmotoDelay(100); //写数据 MotoR_W=0; MotoD_A=1; for(i=1;i<=7;i++) //持续发送Cdata[1]~Cdata[7] { Motobus=Cdata; _nop_();_nop_(); MotoClock=0; SmotoDelay(30); MotoClock=1; SmotoDelay(30); } Mwait(200); //等待子机回应,一段时间(Mwait(200))内子机没有回应则不再等待 tmp=Motobus; //读子机返回的信息,看是否发送成功 if(tmp==MotoID) //如果子机返回码正确,跳出发送过程,否则再发送,直到10次 {RE=1;CUN=11;} }//end of for(CUN=1;CUN<=10;CUN++) EA=iEA; return RE; }
子机:
void ISR_T0(void)interrupt 1 using 1 { ... ...//递增步数,发送步进脉冲 }
void ISR_T1(void)interrupt 3 using 2 { ... ...//递增步数,发送步进脉冲 }
void main(void) { .. ..//初始化等
while(1) { if(ReCON()) { ... ...//如果函数ReCON()返回真,则表明主机发来新指令,处理指令后开启计时 ...//器启动步进电机。 } } }
bit ReCON(void) { unsigned char i,ii,P1BUS,tmp,CCY,CUN,CData[8],XX; bit RR=0; if((MotoR_W==0)&&(MotoD_A==0)&&(MotoClock==0)) { LED1=1; LED2=1; P1BUS=P1; if((P1BUS==SLAVE0)||(P1BUS==SLAVE1)) { EA=0;//地址符合,准备接受指令字节,关中断。 if(P1BUS==SLAVE0) LocalID=0; if(P1BUS==SLAVE1) LocalID=1; CData[0]=P1BUS; while(MotoD_A==0) ; for(i=1;i<=7;i++) //接收CData[1]~CData[7]7个字节 { while(MotoClock==1) ;//等待指令跳变信号(本字节写定) _nop_();_nop_(); P1BUS=P1; CData=P1BUS; while(MotoClock==0) ;//等待指令跳变信号(下一字节开始) } //end of for(i=1;i<=7;i++) CUN=0; for(i=0;i<=5;i++) { XX=CData; tmp=1; for(ii=1;ii<=8;ii++) { XX=CData; CCY=XX&tmp;if(CCY==1) CUN++; tmp*=2; }//end of for(ii=1;ii<=8;ii++) }//end of for(i=0;i<=5;i++) LED2=0; //测试点2 if(CData[6]==CUN) { LED1=0; //测试点1 ConSteps=CData[1]; ConSteps=ConSteps<<8; ConSteps&=0xff00; ConSteps+=CData[2];
//从特殊控制字判断方向参数,暂时特殊控制字不含其它信息 if(CData[3]==0xff) ConDIR=1; else ConDIR=0; ConSpeedH=CData[4]; //接收的速度高字节 ConSpeedL=CData[5]; //接收的速度低字节 RR=1; MotoR_W=1;MotoD_A=1; P1=CData[0]; }//end of if(CData[6]==CData[0]) }//end of if((P1BUS==SLAVE0)||(P1BUS==SLAVE1)) } EA=1; return RR; }
当子机程序中有“P1=CData[0];”语句后,上电后主机第一次发指令子机可以进入“if(CData[6]==CUN) ”里的语句,但主机此后再发则子机只执行到“if(CData[6]==CUN)”前。这个情况是通过“LED1=0; //测试点1”及“ LED2=0; //测试点2”确认的。实在晕了,硬件的问题没头绪,软件现在也不知道怎么出来这么个奇怪的问题
|