打印

多机通讯失败鸟,请大家来拍,有图有程序

[复制链接]
2365|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一顿乱Q|  楼主 | 2008-1-30 09:06 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
 我试图用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--;
   }

}

}

相关帖子

沙发
zgl7903| | 2008-1-30 16:39 | 只看该作者

使用定时器作了超时检查,但是没有赋值给定时器

因此每次进入等待的时间不同,况且C8051是单指令处理器,需要给传统的单片机留足够长的时间

使用特权

评论回复
板凳
zhang123| | 2008-1-30 18:29 | 只看该作者

*吗?

使用特权

评论回复
地板
mapleyang| | 2008-1-30 22:43 | 只看该作者

在中断里使用查询?

程序结构比较差,建议学习一下人家的串口程序是如何实现的。

使用特权

评论回复
5
一顿乱Q|  楼主 | 2008-1-31 08:48 | 只看该作者

回楼上各位

zgl7903:
貌似我没有使用定时器
mapleyang:
且先别管它结构差,请告诉我关键的错误在哪里?使得通讯失败?

使用特权

评论回复
6
stycx| | 2008-1-31 11:24 | 只看该作者

先用pc机的串口助手调试一下吧

使用特权

评论回复
7
dai_weis| | 2008-1-31 11:31 | 只看该作者

从机的TXD与主机的RXD不能这样连接

因该使用二极管作隔离,除非你保证一个从机发数据时候另一个从机的TXD端口是高阻或者OC类,不能是强上拉,否则要用二极管隔离
程序没有看,有些长,或者先断开一个从机看看是否正确

使用特权

评论回复
8
一顿乱Q|  楼主 | 2008-1-31 14:02 | 只看该作者

回楼上

stycx:
用串口调试工具试了一下,貌似主机从机各自都正常,让它们互相通讯就是不行。
dai_weis:
用二极管作隔离??请具体点说说看,兄弟云里雾里

使用特权

评论回复
9
dai_weis| | 2008-1-31 15:45 | 只看该作者

用两个二极管例如 1N 4148

两个二极管的阳极连接到主机的RXD端,阴极分别接到各自分机的TXD端,用来隔离分机发出的TXD信号
呵呵,懒得画图

使用特权

评论回复
10
一顿乱Q|  楼主 | 2008-2-1 11:45 | 只看该作者

回dai_weis

dai_weis :你的意思是主机的RX和分机的TX之间接二极管?那样的话是不是会使得分机无法向主机发送信息?

使用特权

评论回复
11
qinyp| | 2008-2-1 12:30 | 只看该作者

re

这是一个232和485共存的电路,可以参考一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

66

帖子

0

粉丝