我试图用F020的目标板加上2片AT89C2051搭建一个多机串口试验板。电路请看图。大概的设想是:C8051F020和AT89C2051都使用12MHz晶振,方式2固定波特率。F020为主机,2051为子机。初始化阶段各子机SM2=1。主机与某分机通讯前先广播地址帧(TB8=1),子机接受后判断地址是否与自己相同,不相同则忽略,相同者把SM2=0并送回自己的地址供主机确认。主机确认后开始发送数据帧(TB8=0),于是,仅目标子机相应并接受数据帧。
试验发现各子机能正确识别地址信号并接受数据帧。问题是似乎每次都要发送2次才引起一次子机的响应,并却子机无法正确识别数据帧(每次LED只闪烁一次)。
主机程序:
void SYSCLK_Init(void) { unsigned int i; OSCXCN=0x67; for(i=0;i<256;i++) ; while(!(OSCXCN&0x80)) ; OSCICN=0x88; }
void UART0_Init(void) { SCON0=0x98; //串口方式2,SM2=0,TB=1,REN=1 }
void PORT_Init(void) { XBR2=0x40; P1MDOUT=0xFF; P0MDOUT=0x02; }
void Moto(unsigned char iMotoID,unsigned int iSteps) { // unsigned int W_times; unsigned char MotoID; MotoID=iMotoID; XBR2|=0x40;//交叉开关使能 XBR0|=0x04;//UART0联到P00,P01 //地址帧TB8=1; Send_SUBID:SCON0=0x98; //串口方式2,SM2=0(忽略RB8无条件接收),TB=1,REN=1 RI0=0; // RI清零 SBUF0=MotoID;
while(!TI0); TI0=0; while(!RI0);//等待子机回应 RI0=0; ACC=SBUF0; //子机回应码送ACC if(ACC!=MotoID) goto Send_SUBID; //如果子机回应码不符,则重发 TB80=0; //数据帧TB8=0; SBUF0=0x05;//------此处试图发送数据5给子机,让子机闪烁5次
while(!TI0); TI0=0; }
void main(void) {
SYSCLK_Init(); WDTCN=0xde; WDTCN=0xad; PORT_Init();
Delay(2000);
Moto(1,2);
while(1) {}
}
子机程序:
#define SUB_ID 0x02 //子机ID 子机1为0X01 子机2为0X02
unsigned char Datas; //数据字节
void ISR_T0(void)interrupt 1 using 1
{
.....
}
void ISR_T1(void)interrupt 3 using 2
{
..........
}
void ISR_UART(void)interrupt 4 using 0 { ACC=SBUF; //地址帧送ACC RI=0; //RI清零 if (ACC==SUB_ID) //是呼叫本机则响应 { SM2=0;// 准备接收数据帧 SBUF=SUB_ID;//对主机反馈子机ID供主机核对
while(!TI); TI=0; while(!RI) ;//等待主机数据帧 ACC=SBUF; Datas=ACC; }//end of if (ACC==SUB_ID) //是呼叫本机则响应 RI=0; SM2=1; //准备接收地址帧 }
main() { TMOD=0x11;//t0,t1均为TR0/1软启动定时器,方式1(16位定时) EA=1; ET0=1; ET1=1; ES=1; //串口中断开启 SCON=0xb0;//方式2,SM2=1(RB8=1则接收,否则放弃),REN=1(接收允许) //TR0=1; //TR1=1;
Datas=0x00;
while(1)
{
while(Datas!=0) { LED=0; DelayL(100); LED=1; DelayL(100); Datas--; }
}
} |