找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4201|回复: 3
打印 上一主题 下一主题
收起左侧

单片机多机通信互传数据仿真+代码(1602显示从机信息)

[复制链接]
跳转到指定楼层
楼主
功能说明:主机功能:按下key1,从机1灯亮,lcd显示从机1发送的数据,按下key2,从机1灯。按下key3,从机2灯亮,lcd显示从机2发送的数据;按下key4,从机2灯灭,按下key5,从机1和从机2灯灭;按下key6,从机1和从机2灯灭;
proteus仿真图:


主机部分单片机代码:
  1. /*******************************************************************************
  2. *  标题:                        多机通信                                       *
  3. *  时间                      2019年3月11日16:14:33                                                           *                                                                                                                                          
  4. *                                                                              *                                                                        
  5. *  实验说明:主机功能:按下key1,从机1灯亮,lcd显示从机1发送的数据,按下key2,   *
  6. 从机1灯。按下key3,从机2灯亮,lcd显示从机2发送的数据;按下key4,从机2灯灭,按下*
  7. key5,从机1和从机2灯灭;按下key6,从机1和从机2灯灭;                           *                                                               
  8. ********************************************************************************
  9. * 实验心得:1.例如发送的字符串数组是buff[]={0x01,0x02,0x03},那么接收端前三位收到*
  10. 的数据就是0x01,0x02,0x03,之后也是有数据发送过来,但是数据的值不是字符串赋的值  *
  11. 2.check=check^Buff[i];这句话的意思是check和buff的值进行二进制或与,相同为0,   *
  12. 不同为1,按这个进行主机与从机数据的校验                                        *
  13. ********************************************************************************/
  14. #include<reg51.h>
  15. #include<string.h>
  16. #include "lcd.h"
  17. #define _SUCC_   0x0f//数据传送成功
  18. #define _ERR_    0xf0//数据传送失败
  19. unsigned char aa=0xff;//主机与从机之间通信标志
  20. unsigned char temp=0xff;
  21. unsigned char Buff[20];//数据缓冲区
  22. unsigned char recive[6];         //用于保存从机发送的数据
  23. sbit KEY1=P1^3;
  24. sbit KEY2=P1^2;
  25. sbit KEY3=P1^1;
  26. sbit KEY4=P1^0;
  27. sbit KEY5=P3^2;
  28. sbit KEY6=P3^3;

  29. //sbit KEY5=P1^4;
  30. //sbit KEY6=P1^5;
  31. //延时1ms函数
  32. void delay_1ms(unsigned int i)
  33. {
  34.      unsigned int x,y;
  35.      for(x=i;x>0;x--)
  36.          for(y=110;y>0;y--);
  37. }
  38. //串口初始化函数
  39. void init()
  40. {
  41.      TMOD=0x20; //定时器1工作于方式2
  42.      TH1=0xfd;  
  43.      TL1=0xfd; //波特率为9600
  44.      PCON=0;
  45.      SCON=0xd0;  //串口工作于方式3
  46.      TR1=1;  //开启定时器
  47.      TI=0;
  48.      RI=0;
  49. }


  50. //发送数据函数
  51. void SEND_data(unsigned char *Buff)
  52. {
  53.      unsigned char i,lenth,check;
  54.      lenth=strlen(Buff);      //计算数据长度
  55.      check=lenth;
  56.      TI=0;         //发送数据长度
  57.      TB8=0;       //发送数据帧
  58.      SBUF=lenth;
  59.      while(!TI);
  60.      TI=0;
  61.          
  62.      for(i=0;i<lenth;i++)  //发送数据
  63.     {
  64.         check=check^Buff[i];
  65.         TB8=0;
  66.         SBUF=Buff[i];      
  67.         while(!TI);
  68.         TI=0;
  69.     }
  70.       TB8=0;      //发送校验字节
  71.       SBUF=check;   
  72.       while(!TI);
  73.       TI=0;     
  74. }

  75. //接收数据函数
  76. unsigned char RECE_data(unsigned char *Buff)
  77. {
  78.      unsigned char i;
  79.      unsigned char lenth;
  80.      unsigned char check;
  81.      RI=0;     //接收数据长度
  82.      while(!RI);
  83.      if(RB8==1)
  84.          {
  85.                  RI = 0;   
  86.              return 0xfe;  //若接收到地址帧,则返回0xfe
  87.          }
  88.      lenth=SBUF;
  89.      RI=0;     
  90.      check=lenth;
  91.      for(i=0;i<lenth;i++) //接收数据
  92.     {
  93.         while(!RI);
  94.         if(RB8==1)   //若接收到地址帧,则返回0xfe
  95.         return 0xfe;
  96.         Buff[i]=SBUF;   
  97.         check=check^(Buff[i]);
  98.         RI=0;
  99.     }
  100.      while(!RI);    //接收校验字节
  101.      if(RB8==1)    //若接收到地址帧,则返回0xfe
  102.      return 0xfe;
  103.      temp=SBUF;
  104.      RI=0;
  105.      check=temp^check;  //将从主机接收到的校验码与自己计算的校验码比对
  106.      if(check!=0)   //校验码不一致,表明数据接收错误,向主机发送错误信号,函数返回0xff
  107.      {
  108.         TI=0;
  109.         TB8=0;
  110.         SBUF=_ERR_;
  111.         while(!TI);
  112.         TI=0;
  113.         return 0xff;
  114.      }
  115.      TI=0;           //校验码一致,表明数据接收正确,向主机发送成功信号,函数返回0x00
  116.      TB8=0;
  117.      SBUF=_SUCC_;            
  118.      while(!TI);
  119.      TI=0;
  120.      return 0;
  121. }                                 

  122. //发送从机地址
  123. void ADDR_data(unsigned addr)
  124. {
  125. while(temp!=addr) //主机等待从机返回其地址作为应答信号
  126. {
  127.   TI=0;    //发送从机地址
  128.   TB8=1;    //发送地址帧
  129.   SBUF=addr;
  130.   while(!TI);
  131.   TI=0;
  132.   
  133.   RI=0;
  134.   while(!RI);
  135.   temp=SBUF;
  136.   RI=0;
  137. }
  138. }

  139. void keyscan()
  140. {
  141.   
  142.   if(KEY1==0)
  143.   {
  144.      delay_1ms(5);
  145.      if(KEY1==0)
  146.     {
  147.       while(!KEY1);
  148.       ADDR_data(0x01);//发送从机地址
  149.       temp=_ERR_;   //主机等待从机数据接收成功信号
  150.       while(temp!=_SUCC_)
  151.       {
  152.           unsigned char Buff[]={0xfe};
  153.           SEND_data(Buff);//发送数据
  154.           RI=0;
  155.           while(!RI);
  156.           temp=SBUF;
  157.           RI=0;
  158.       }
  159.           SM2=0;       //接收数据帧
  160.       aa=0xff;    //从机接收数据,并将数据保存到数据缓冲区
  161.       while(aa==0xff)
  162.       {
  163.           aa=RECE_data(Buff);
  164.                   P0 = 0xff;
  165.       }
  166.           P0 = 0xfe;
  167.       recive[0] = Buff[0];
  168.           recive[1] = Buff[1];
  169.           recive[2] = Buff[2];
  170.          
  171.     }
  172.   }

  173.   if(KEY2==0)
  174.   {
  175.      delay_1ms(5);
  176.      if(KEY2==0)
  177.      {
  178.         while(!KEY2);
  179.         ADDR_data(0x01);
  180.         temp=_ERR_;   //主机等待从机数据接收成功信号
  181.         while(temp!=_SUCC_)
  182.        {
  183.           unsigned char Buff[]={0xff};
  184.           SEND_data(Buff);
  185.           RI=0;
  186.           while(!RI);  
  187.           RI=0;
  188.                   temp=SBUF;
  189.        }
  190.      }
  191.   }

  192.   if(KEY3==0)
  193.   {
  194.      delay_1ms(5);
  195.      if(KEY3==0)
  196.      {
  197.          while(!KEY3);
  198.          ADDR_data(0x02);
  199.              temp=_ERR_;   //主机等待从机数据接收成功信号
  200.          while(temp!=_SUCC_)
  201.         {
  202.            unsigned char Buff[]={0xfe};
  203.            SEND_data(Buff);
  204.            RI=0;
  205.            while(!RI);
  206.            temp=SBUF;
  207.            RI=0;
  208.         }
  209.                 SM2=0;       //接收数据帧
  210.                 aa=0xff;    //从机接收数据,并将数据保存到数据缓冲区
  211.                 while(aa==0xff)
  212.                 {
  213.                         aa=RECE_data(Buff);
  214.                         P0 = 0xff;
  215.                 }
  216.                 P0 = 0xfe;
  217.                 recive[3] = Buff[0];
  218.                 recive[4] = Buff[1];
  219.                 recive[5] = Buff[2];
  220.      }
  221.   }

  222.   if(KEY4==0)
  223.   {
  224.       delay_1ms(5);
  225.       if(KEY4==0)
  226.      {
  227.          while(!KEY4);
  228.          ADDR_data(0x02);
  229.               temp=_ERR_;   //主机等待从机数据接收成功信号
  230.          while(temp!=_SUCC_)
  231.         {
  232.              unsigned char Buff[]={0xff};
  233.              SEND_data(Buff);
  234.              RI=0;
  235.              while(!RI);
  236.              temp=SBUF;
  237.              RI=0;
  238.         }
  239.      }
  240.   }
  241.   if(KEY5==0)
  242.   {
  243.       delay_1ms(5);
  244.       if(KEY5==0)
  245.      {
  246.          while(!KEY5);
  247.          ADDR_data(0x01);
  248.               temp=_ERR_;   //主机等待从机数据接收成功信号
  249.          while(temp!=_SUCC_)
  250.         {
  251.              unsigned char Buff[]={0xff};
  252.              SEND_data(Buff);
  253.              RI=0;
  254.              while(!RI);
  255.              temp=SBUF;
  256.              RI=0;
  257.         }
  258.          ADDR_data(0x02);
  259.               temp=_ERR_;   //主机等待从机数据接收成功信号
  260.          while(temp!=_SUCC_)
  261.         {
  262.              unsigned char Buff[]={0xff};
  263.              SEND_data(Buff);
  264.              RI=0;
  265.              while(!RI);
  266.              temp=SBUF;
  267.              RI=0;
  268.         }
  269.      }
  270.   }
  271.   if(KEY6==0)
  272.   {
  273.       delay_1ms(5);
  274.       if(KEY6==0)
  275.      {
  276.          while(!KEY6);
  277.          ADDR_data(0x01);
  278.               temp=_ERR_;   //主机等待从机数据接收成功信号
  279.          while(temp!=_SUCC_)
  280.         {
  281.              unsigned char Buff[]={0xff};
  282.              SEND_data(Buff);
  283.              RI=0;
  284.              while(!RI);
  285.              temp=SBUF;
  286.              RI=0;
  287.         }
  288.          ADDR_data(0x02);
  289.               temp=_ERR_;   //主机等待从机数据接收成功信号
  290.          while(temp!=_SUCC_)
  291.         {
  292.              unsigned char Buff[]={0xff};
  293.              SEND_data(Buff);
  294.              RI=0;
  295.              while(!RI);
  296.              temp=SBUF;
  297.              RI=0;
  298.         }
  299.      }
  300.   }

  301. }      
  302. void main()
  303. {
  304.      init();
  305.          LcdInit();                         //初始化LCD1602
  306.      LcdWriteCom(0x01);
  307.      while(1)
  308.      {
  309.         keyscan();
  310.                 LcdWriteData(recive[0]);
  311.             LcdWriteData(recive[1]);
  312.                 LcdWriteData(recive[2]);
  313.             LcdWriteData(recive[3]);
  314.                 LcdWriteData(recive[4]);
  315.             LcdWriteData(recive[5]);
  316.                 LcdWriteCom(0x80);
  317.      }
  318. }
复制代码
从机1部分代码:
  1. #include<reg51.h>
  2. #include<string.h>
  3. #define addr     0x01//从机1的地址
  4. #define _SUCC_   0x0f//数据传送成功
  5. #define _ERR_    0xf0//数据传送失败
  6. unsigned char aa=0xff;//主机与从机之间通信标志
  7. unsigned char Buff[20];//数据缓冲区
  8. unsigned char ceshi[] = {0x77,0x78,0x56};                //传递给主机的信息
  9. unsigned char tp;
  10. //串口初始化函数
  11. void init()
  12. {
  13.      TMOD=0x20; //定时器1工作于方式2
  14.      TH1=0xfd;  
  15.      TL1=0xfd; //波特率为9600
  16.      PCON=0;
  17.      SCON=0xd0;  //串口工作于方式3
  18.      TR1=1;  //开启定时器         
  19.      TI=0;
  20.      RI=0;
  21. }

  22. //发送数据函数
  23. void SEND_data(unsigned char *Buff)
  24. {
  25.      unsigned char i,lenth,check;
  26.      lenth=strlen(Buff);      //计算数据长度
  27.      check=lenth;
  28.      TI=0;         //发送数据长度
  29.      TB8=0;       //发送数据帧
  30.      SBUF=lenth;
  31.      while(!TI);
  32.      TI=0;
  33.          
  34.      for(i=0;i<lenth;i++)  //发送数据
  35.     {
  36.         check=check^Buff[i];
  37.         TB8=0;
  38.         SBUF=Buff[i];      
  39.         while(!TI);
  40.         TI=0;
  41.     }
  42.       TB8=0;      //发送校验字节
  43.       SBUF=check;   
  44.       while(!TI);
  45.       TI=0;     
  46. }

  47. //接收数据函数
  48. unsigned char RECE_data(unsigned char *Buff)
  49. {
  50.      unsigned char i,temp;
  51.      unsigned char lenth;
  52.      unsigned char check;
  53.      RI=0;     //接收数据长度
  54.      while(!RI);
  55.      if(RB8==1)
  56.          {
  57.                  RI = 0;   
  58.              return 0xfe;  //若接收到地址帧,则返回0xfe
  59.          }
  60.      lenth=SBUF;
  61.      RI=0;     
  62.      check=lenth;
  63.      for(i=0;i<lenth;i++) //接收数据
  64.     {
  65.         while(!RI);
  66.         if(RB8==1)   //若接收到地址帧,则返回0xfe
  67.         return 0xfe;
  68.         Buff[i]=SBUF;   
  69.         check=check^(Buff[i]);
  70.         RI=0;
  71.     }
  72.      while(!RI);    //接收校验字节
  73.      if(RB8==1)    //若接收到地址帧,则返回0xfe
  74.      return 0xfe;
  75.      temp=SBUF;
  76.      RI=0;
  77.      check=temp^check;  //将从主机接收到的校验码与自己计算的校验码比对
  78.      if(check!=0)   //校验码不一致,表明数据接收错误,向主机发送错误信号,函数返回0xff
  79.      {
  80.         TI=0;
  81.         TB8=0;
  82.         SBUF=_ERR_;
  83.         while(!TI);
  84.         TI=0;
  85.         return 0xff;
  86.      }
  87.      TI=0;           //校验码一致,表明数据接收正确,向主机发送成功信号,函数返回0x00
  88.      TB8=0;
  89.      SBUF=_SUCC_;            
  90.      while(!TI);
  91.      TI=0;
  92.      return 0;
  93. }                                 
  94. void main()
  95. {
  96.     init();
  97.     while(1)
  98.    {
  99.        SM2=1;              //处于接收地址帧状态
  100.        while(aa!=addr)  //从机等待主机请求自己的地址
  101.       {
  102.            RI=0;
  103.            while(!RI);
  104.            aa=SBUF;
  105.            RI=0;
  106.       }
  107.       TI=0;     //一旦被请求,从机返回自己的地址作为应答,等待接收数据
  108.       TB8=0;
  109.       SBUF=addr;
  110.       while(!TI);
  111.       TI=0;
  112.       SM2=0;       //接收数据帧
  113.       aa=0xff;    //从机接收数据,并将数据保存到数据缓冲区
  114.       while(aa==0xff)
  115.       {
  116.           aa=RECE_data(Buff);
  117.       }
  118.       if(aa==0xfe)
  119.          continue;
  120.       P2=Buff[0];      //查看接收到的数据
  121.           tp = _ERR_;
  122.           if(Buff[0] == 0xfe)
  123.           {
  124.                   while(tp!=_SUCC_)
  125.                   {
  126.                           SEND_data(ceshi);
  127.                         RI=0;
  128.                         while(!RI);  
  129.                         RI=0;
  130.                         tp=SBUF;
  131.                   }
  132.           }
  133.    }
  134. }
复制代码

从机2部分代码:
  1. #include<reg51.h>
  2. #include<string.h>
  3. #define addr     0x02//从机2的地址
  4. #define _SUCC_   0x0f//数据传送成功
  5. #define _ERR_    0xf0//数据传送失败
  6. unsigned char aa=0xff;//主机与从机之间通信标志
  7. unsigned char ceshi[] = {0x6b,0x6c,0x2b};
  8. unsigned char tp;
  9. unsigned char Buff[20];//数据缓冲区
  10. //串口初始化函数
  11. void init()
  12. {
  13.      TMOD=0x20; //定时器1工作于方式2
  14.      TH1=0xfd;  
  15.      TL1=0xfd; //波特率为9600
  16.      PCON=0;
  17.      SCON=0xd0;  //串口工作于方式3
  18.      TR1=1;  //开启定时器
  19.      TI=0;
  20.      RI=0;
  21. }

  22. //发送数据函数
  23. void SEND_data(unsigned char *Buff)
  24. {
  25.      unsigned char i,lenth,check;
  26.      lenth=strlen(Buff);      //计算数据长度
  27.      check=lenth;
  28.      TI=0;         //发送数据长度
  29.      TB8=0;       //发送数据帧
  30.      SBUF=lenth;
  31.      while(!TI);
  32.      TI=0;
  33.          
  34.      for(i=0;i<lenth;i++)  //发送数据
  35.     {
  36.         check=check^Buff[i];
  37.         TB8=0;
  38.         SBUF=Buff[i];      
  39.         while(!TI);
  40.         TI=0;
  41.     }
  42.       TB8=0;      //发送校验字节
  43.       SBUF=check;   
  44.       while(!TI);
  45.       TI=0;     
  46. }

  47. //接收数据函数
  48. unsigned char RECE_data(unsigned char *Buff)
  49. {
  50.      unsigned char i,temp;
  51.      unsigned char lenth;
  52.      unsigned char check;
  53.      RI=0;     //接收数据长度
  54.      while(!RI);
  55.      if(RB8==1)    //若接收到地址帧,则返回0xfe
  56.      return 0xfe;
  57.      lenth=SBUF;
  58.      RI=0;     
  59.      check=lenth;
  60.      for(i=0;i<lenth;i++) //接收数据
  61.     {
  62.         while(!RI);
  63.         if(RB8==1)   //若接收到地址帧,则返回0xfe
  64.         return 0xfe;
  65.         Buff[i]=SBUF;   
  66.         check=check^(Buff[i]);
  67.         RI=0;
  68.     }
  69.      while(!RI);    //接收校验字节
  70.      if(RB8==1)    //若接收到地址帧,则返回0xfe
  71.      return 0xfe;
  72.      temp=SBUF;
  73.      RI=0;
  74.      check=temp^check;  //将从主机接收到的校验码与自己计算的校验码比对
  75.      if(check!=0)   //校验码不一致,表明数据接收错误,向主机发送错误信号,函数返回0xff
  76.      {
  77.         TI=0;
  78.         TB8=0;
  79.         SBUF=_ERR_;
  80.         while(!TI);
  81.         TI=0;
  82.         return 0xff;
  83.      }
  84.      TI=0;           //校验码一致,表明数据接收正确,向主机发送成功信号,函数返回0x00
  85.      TB8=0;
  86.      SBUF=_SUCC_;
  87.      while(!TI);
  88.      TI=0;
  89.      return 0;
  90. }
  91. void main()
  92. {
  93.     init();
  94.     while(1)
  95.    {
  96.        SM2=1;              //接收地址帧
  97.        while(aa!=addr)  //从机等待主机请求自己的地址
  98.       {
  99.            RI=0;
  100.            while(!RI);
  101.            aa=SBUF;
  102.            RI=0;
  103.       }
  104.       TI=0;     //一旦被请求,从机返回自己的地址作为应答,等待接收数据
  105.       TB8=0;
  106.       SBUF=addr;
  107.       while(!TI);
  108.       TI=0;
  109.       SM2=0;                  //接收数据帧
  110.       aa=0xff;    //从机接收数据,并将数据保存到数据缓冲区
  111.       while(aa==0xff)
  112.       {
  113.           aa=RECE_data(Buff);
  114.       }
  115.       if(aa==0xfe)
  116.          continue;
  117.       P2=Buff[0];      //查看接收到的数据
  118.           tp = _ERR_;
  119.           if(Buff[0] == 0xfe)
  120.           {
  121.                   while(tp!=_SUCC_)
  122.                   {
  123.                           SEND_data(ceshi);
  124.                         RI=0;
  125.                         while(!RI);  
  126.                         RI=0;
  127.                         tp=SBUF;
  128.                   }
  129.           }
  130.    }
  131. }
复制代码

全套代码可以下载附件


注意这个仿真只能用Proteus7.8版本打开,经过测试其他版本均无反应:
多机通信-1602显示从机信息.zip (194.84 KB, 下载次数: 134)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:509233 发表于 2019-4-27 17:14 | 只看该作者
请问下如果我不进行校验的话代码可以怎么改?比如说我只接受两个从机的八位数据
回复

使用道具 举报

板凳
ID:289218 发表于 2023-1-24 16:23 | 只看该作者
反馈:8.13版本运行,按下任何按钮均无反应。
回复

使用道具 举报

地板
ID:717459 发表于 2023-5-8 15:49 | 只看该作者
效果不行
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表