打印
[国产单片机]

51单片机多机通信

[复制链接]
3387|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hanzhenfei|  楼主 | 2011-8-10 22:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
主机接收从机数据
主机:
/*
主从通信基本步骤:
1. 主机从机初始化为方式2或者3,从机都置SM2=1,允许中断
2. 主机置TB8=1,发送从机地址
3. 所有从机均接收主机发送要寻址的从机地址
4. 被寻址的从机确认地址后,置本机SM2=0,向主机返回地址,供主机核对
5. 核对无误后,主机向被寻址的从机发送命令,通知从机接受或者发送数据。
6. 本次通信结束后,主从机重置SM2=1,主机可再对其他从机寻址
*/
/*
   ★数据的传递主机发送信息,可以传送到各个从机或指定从机,各从机发送的信息只能被主机接收。
   ★多机通信(关键是地址帧的识别)
     ◇ 主机发送:地址帧、数据帧的鉴别是通过第9位数据确定:
        TB8=1,地址帧
        TB8=0,数据帧
     ◇从机接收:
      各从机串行口工作在方式2、方式3下;
      多机通信标志SM2(SCON.5)=1;
      检查接收到的第9位RB8(SCON.2),当:
      RB8=1:地址帧,将地址装入SBUF,置位RI,发出接收中断请求;判断主机发送地址是否与本机相符,若相符,则将从机SM2清0(变成直通方式),准备接收其后传送来的数据。
      RB8=0:数据帧,对SM2=1,RB8=0的从机,接收数据丢弃,而对SM2=0的从机:直通方式,不论RB8是0还是1,都将接受到的数据送SBUF,并发出中断请求。
      多机通信的过程总结如下:
    (1)全部从机串行口工作方式初始化为2或3,置位SM2,允许中断;
    (2)主机置位TB8,发送要寻址的从机地址;
    (3)所有的从机均接收主机发送的地址,进入中断进行地址比较;
    (4)确认寻址从机,自身SM2清0,向主机返回地址供主机核对;
    (5)主机核对无误,向被寻址从机发送发送命令,通知从机进行一对一数据通信。
*/
#include<reg52.h>
#define BN  16
#define uchar  unsigned char
#define uint  unsigned int
uchar slave=0x00;
uchar idata rdata[16];
uchar idata tdata[16]={"abcdefghijklmnop"};
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
void delay(uint n)
{
        uint i;
        uchar j;
        for(i=n;i>0;i--)
           for(j=110;j>0;j--);
}
/**************************************************/
void send(uchar dat)
{
     SBUF=dat;
while(!TI);
TI=0;
}
/****************** c********************************/
void error(void)
{
     SBUF=0xff;
while(!TI);
TI=0;
}
/**************************************************/
void master(uchar address,uchar command)
{               
  uchar command_temp,i,p;
while(1)
{
   
  TB8=1;    //置地址标志位
      send(slave);     //发送地址;
  while(RI!=1);     /*等待从机发送地址*/
  RI=0;
  if(SBUF!=address)  //地址不符合发送0xff
  error();
      else           //地址相符合;
  {   
      led1=0;
      TB8=0;     //发送数据标志位
          send(command);
              while(RI!=1);
      RI=0;
      command_temp=SBUF;
      if((command_temp&0x80)==0x80)   //命令不正确发送复位信号
   {
    TB8=1;
    error();
   }   
      else     
      {   
            led2=0;
    //delay(1000);
    if(command==0x02)
        {
     
    if((command_temp&0x02)==0x02)    //从机准备好发送
    {
       while(1)
     {
      p=0;
      for(i=0;i<2;i++)
      {
       while(RI!=1);
       RI=0;
       rdata[i]=SBUF;
       p+=rdata[i];
      
      }      
      while(RI!=1);
          RI=0;
      if(SBUF==p)
      {
         
           send(0x00);
           led3=0;
           //delay(1000);
       break;
      }
           
      else
      {
        send(0xff);
      }
      }
      
      while(RI!=1);
      RI=0;
      P2=SBUF;  
                  TB8=1;      /*置地址标志位1*/   
    }        
    }
     }   
      }
     }  
}
/*******************************
1.定时器1,工作模式2;
2.装入初值,波特率;
3.启动定时器/计数器1;
4.串行工作方式1,8位UATR;
5.开启总中断;
6.开启串行中断;
*******************************/
void main()
{

   TMOD=0x20;  //定时器1,工作模式2
   TH1=0xfd;   //载入波特率,9600kps,晶振11.0592MHz
   TL1=0xfd;   
   TR1=1;   //开启定时器1
   PCON=0x00;  //允许接收
   SCON=0xf0;  //SM0=1,SM1=1,SM2=1,REN=1,串行工作方式3
   EA=1;   //开总中断
   ES=1;   //开串行中断
   
     while(1)
   {
    master(slave,0x02);/*向从机0x00接收数据*/;
   }

                                                                                                                                                                                                                                                                                                                                     从机 : #include<reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define slave 0x00
#define BN    16
bit   tready;   //发送准备标志
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
uchar idata tdata[16];
  void  delayms(uint xms)
{
  uchar i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
uchar code table[]={
        0xc0,0xf9,0xa4,0xb0,
       0x99,0x92,0x82,0xf8,
       0x80,0x90,0x88,0x83,
                       0xc6,0xa1,0x86,0x8e
      };
void send(uchar keynum)
{
   //SBUF=keynum;
SBUF=table[keynum];
while(!TI);
TI=0;
}
/**********************************/         
  void sent()    //向主机发送数据
{

uchar p,i;
tready=0;
do
{
  p=0;
  for(i=0;i<2;i++)
  {
   
   tdata[i]=SBUF;
   p+=tdata[i];
   while(!TI);TI=0;
  }
  SBUF=p;
      while(!TI);TI=0;
  while(!RI);RI=0;
} while(SBUF!=0);
      led3=0;
  SM2=1;
  ES=1;
}      
/*******************************
定时器1,工作模式2;
装入初值,波特率;
启动定时器/计数器1;
串行工作方式1,8位UATR;
开启总中断;
开启串行中断;
*******************************/
void main()
{
  TMOD=0x20;
  TH1=0xfd;
  TL1=0xfd;
  TR1=1;
  PCON=0x00;
  SCON=0xf0;
  EA=1;
  ES=1;
  while(1)
  {
      keyscan();
     tready=1;
  }
}
/********************************/
void ssio() interrupt 4 using 1
{
void sent();
uchar a,x;
RI=0;
ES=0;
if(SBUF!=slave)
{
  ES=1;
  goto reti;
}              
led1=0;
SM2=0;
SBUF=slave;
while(!TI);TI=0;
while(!RI);RI=0;
led2=0;    //地址标志位
if(RB8==1)
{
  SM2=1;
  ES=1;
  goto reti;
}
  a=SBUF;  
     if(a==0x02)
  {   
      
  if(tready==1)      
    SBUF=0x02;
   else
        SBUF=0x00;
   while(!TI);TI=0;
   while(!RI);RI=0;
       if(RB8==1)
   {
    SM2=1;
    ES=1;
    goto reti;
   }
   led2=0;  
  
   sent();
  
  }
  else
  {
    SBUF=0x80;
   while(!TI);TI=0;
   SM2=1;
   ES=1;
  }

     reti: ;  
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               }
主机却接收不到数据

相关帖子

沙发
hanzhenfei|  楼主 | 2011-8-10 22:25 | 只看该作者
为什么啊????????????

使用特权

评论回复
板凳
hanzhenfei|  楼主 | 2011-8-10 22:26 | 只看该作者
我调试了没有错误

使用特权

评论回复
地板
hanzhenfei|  楼主 | 2011-8-11 08:07 | 只看该作者
恩。是没有错误,但是从机好貌似不能向主机发送数据。我用了几个发光二极管的亮灭表示传输情况,流水灯不亮

使用特权

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

本版积分规则

0

主题

147

帖子

1

粉丝