找回密码
 立即注册

QQ登录

只需一步,快速开始

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

自己在网上搜资料做了一个51单片机双机通讯的程序,发现数据传输有问题,帮忙看看。

[复制链接]
跳转到指定楼层
楼主
本来是想着用1602把接收到的数据显示出来,可是只显示白块。这是程序,希望大家可以帮忙看看。

单片机主机程序:
  1. #include <REGX51.H>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit lcdrw=P2^5;
  6. sbit lcdrs=P2^6;
  7. sbit lcden=P2^7;
  8. uchar kkk[6];
  9. uchar code table[6]={"123456"};        //6
  10. uchar num;
  11. void delayms(uchar xms)
  12. {
  13.   uint i,j;
  14.   for(i=xms;i>0;i--)
  15.      for(j=110;j>0;j--);
  16. }
  17. //1602显示
  18. void write_com(uchar com)
  19. {
  20.   lcdrs=0;
  21.   lcdrw=0;
  22.   P0=com;
  23.   delayms(5);
  24.   lcden=1;
  25.   lcden=0;
  26. }
  27. void write_date(uchar date)
  28. {
  29.   lcdrs=1;
  30.   lcdrw=0;
  31.   P0=date;
  32.   delayms(5);
  33.   lcden=1;
  34.   lcden=0;
  35. }
  36. void init()
  37. {
  38.   lcdrs=1;
  39.   lcdrw=0;
  40.   write_com(0x38);
  41.   write_com(0x0c);
  42.   write_com(0x06);
  43.   write_com(0x01);
  44.   write_com(0x80);
  45. }
  46. //////////////////////////////////////////////////
  47. void err()
  48. {
  49.   SBUF=0xff;
  50.   while(TI!=1);
  51.   TI=0;
  52. }
  53. uchar kkkk(uchar addr,uchar comm)
  54. {
  55.   uchar aa,p,i;
  56.   while(1)
  57.   {
  58.     SBUF=0x02;                        //发呼叫地址
  59.         while(TI!=1);
  60.               TI=0;
  61.         while(RI!=1);
  62.               RI=0;                                //等待回应
  63.         if(SBUF!=addr)                        
  64.            err();                                //若地址发错,发复位信号
  65.         else
  66.         {                                                //若地址相符
  67.           TB8=0;                                //清地址标记
  68.           SBUF=comm;                        //发命令
  69.           while(TI!=1);                        
  70.                 TI=0;
  71.           while(RI!=1);
  72.                 RI=0;
  73.           aa=SBUF;                                //接受状态
  74.           if((aa&0x08)==0x08)        //若命令未被接受,发送复位信号
  75.           {
  76.             TB8=1;
  77.                 err();
  78.           }
  79.           else
  80.           {
  81.             if(comm==0x01)                //是发送命令
  82.                 {
  83.                   if((aa&0x01)==0x01)         //从机已做好接受准备
  84.                   {
  85.                     do
  86.                         {
  87.                           p=0;                                //清校验和
  88.                           for(num=0;num<6;num++)
  89.               {
  90.                 SBUF=table[num];                  //发送一位数据
  91.                     p+=table[num];
  92.                     while(!TI);
  93.                     TI=0;
  94.               }
  95.                           SBUF=p;                                         //发送校验和
  96.                           while(TI!=1);
  97.                                 TI=0;
  98.                           while(RI!=1);
  99.                                 RI=0;
  100.                         }
  101.                         while(SBUF!=0);                          //接收不正确,重新发送
  102.                         TB8=1;                                          //置地址标志
  103.                         return(0);
  104.                   }
  105.                  else
  106.                   {
  107.                     if((aa&0x02)==0x02)                  //接收信号,从机准备发送
  108.                         {
  109.                           while(1)
  110.                           {
  111.                             p=0;                                  //清校验和
  112.                                 for(i=0;1<6;i++)
  113.                                 {
  114.                                   while(RI!=1);
  115.                                         RI=0;
  116.                                                 kkk[i]=SBUF;  //接收一位数据
  117.                                                 p+=kkk[i];
  118.                                 }
  119.                                 while(RI!=1);
  120.                                           RI=0;
  121.                                 if(SBUF==p)
  122.                                 {
  123.                                   SBUF=0x00;                 //校验和相同发00
  124.                                   while(TI!=1);
  125.                                         TI=0;
  126.                                                 break;
  127.                                 }
  128.                                 else
  129.                                 {
  130.                                   SBUF=0xff;                //校验和不同发0ff重新接受
  131.                                   while(TI!=1);
  132.                                         TI=0;
  133.                                 }
  134.                           }
  135.                           TB8=1;                                //重置地址标记
  136.                           return(0);
  137.                         }
  138.                   }
  139.                 }
  140.           }
  141.         }
  142.   }
  143. }
  144. void main()
  145. {

  146.   init();
  147.   TMOD=0x20;
  148.   TH1=0xfd;
  149.   TL1=0xfd;
  150.   PCON=0x00;
  151.   TR1=1;
  152.   SCON=0xf0;
  153.   /*SM0=0;
  154.   SM1=1;
  155.   EA=1;
  156.   ES=1;*/                           
  157.    write_com(0x80);
  158.    for(num=0;num<6;num++)
  159.    {
  160.      write_date(table[num]);
  161.          delayms(6);
  162.    }
  163.          kkkk(0x02,0x01);           
  164.   while(1);

  165. }


  166. 从机程序:
  167. #include <REGX51.H>
  168. #define uchar unsigned char
  169. #define uint unsigned  int
  170. void str(void);
  171. void sre(void);
  172. uchar kkk[6];
  173. bit   tready;
  174. bit   rready;
  175. sbit  lcdrw=P2^6;
  176. sbit  lcdrs=P2^5;
  177. sbit  lcden=P2^7;
  178. uchar kkkk[6];
  179. void delayms(char xms)
  180. {
  181.   uint i,j;
  182.   for(i=xms;i>0;i--)
  183.       for(j=110;j>0;j--);
  184. }
  185. // 1602显示
  186. void write_com(uchar com) //写数据
  187. {
  188.   lcdrs=0;
  189.   lcdrw=0;
  190.   P0=com;
  191.   delayms(5);
  192.   lcden=1;
  193.   lcden=0;
  194. }
  195. void write_date(uchar date)                  //读数据
  196. {
  197. lcdrs=1;
  198. lcdrw=0;
  199. P0=date;
  200. delayms(5);
  201. lcden=1;
  202. lcden=0;
  203. }
  204. void init1()   //初始化
  205.   {
  206.   lcdrs=1;
  207.   lcdrw=0;
  208.   write_com(0x38);
  209.   write_com(0x0c);
  210.   write_com(0x06);
  211.   write_com(0x01);
  212.   write_com(0x80);
  213. }
  214. void main()
  215. {
  216.   init1();
  217.   TMOD=0x20;                  //方式二
  218.   TH1=0xfd;                          //设初值
  219.   TL1=0xfd;
  220.   PCON=0x00;
  221.   TR1=1;
  222.   SCON=0xf0;                  //方式三
  223.   EA=1;
  224.   ES=1;                                 //开串行口中断
  225.   while(1)
  226.   {        
  227.           uchar j;
  228.     tready=1;
  229.         rready=1;                 //假定准备好发送与接收
  230.     for(j=0;j<6;j++)
  231.     {
  232.           write_com(0x80+j);
  233.           write_date(kkkk[j]);
  234.     }
  235.   }
  236. }
  237. void ser() interrupt 4
  238. {
  239.   /*uchar ddd;
  240.   RI=0;
  241.   ddd=SBUF;
  242.   write_com(0x80);
  243.   write_date(ddd);
  244. */
  245.   uchar a;
  246.   RI=0;
  247.   ES=0;                                 //关串行口中断
  248.   if(SBUF!=0x02)
  249.   {
  250.     ES=1;
  251.         goto reti;
  252.   }                                         
  253.   SM2=0;
  254.   SBUF=0x02;
  255.   while(TI!=1);
  256.         TI=0;
  257.   while(RI!=1);
  258.         RI=0;
  259.   if(RB8==1)
  260.   {
  261.     SM2=1;
  262.         ES=1;
  263.         goto reti;
  264.   }
  265.   a=SBUF;                          //接受命令
  266.   if(a==0x01)                  //判断从主机接受的命令
  267.   {
  268.     if(rready==1)
  269.           SBUF=0x01;          //接受准备好,发送状态
  270.         else
  271.           SBUF=0x00;
  272.         while(TI!=1);
  273.               TI=0;
  274.         while(RI!=1);
  275.               RI=0;
  276.         if(RB8==1)
  277.         {
  278.           SM2=1;
  279.           ES=1;
  280.           goto reti;
  281.         }
  282.         sre();                          //接收数据
  283.   }
  284.   else
  285.   {
  286.     if(a==0x02)                  //从机向主机发送数据
  287.         {
  288.           if(tready==1)
  289.              SBUF=0x02;           //准备好发送状态
  290.           else
  291.              SBUF=0x00;
  292.           while(TI!=1);
  293.                 TI=0;
  294.           while(RI!=1);
  295.                 RI=0;
  296.           if(RB8==1)
  297.           {
  298.             SM2=1;
  299.                 ES=1;
  300.                 goto reti;
  301.           }
  302.           str();                  //发送数据
  303.         }
  304.         else
  305.         {
  306.           SBUF=0x80;         //命令非法,发状态
  307.           while(TI!=1);
  308.                 TI=0;
  309.                         SM2=1;
  310.                         ES=1;         //继续监听
  311.         }
  312.   }
  313.   reti:;
  314. }
  315. void  str(void)                //发送数据块
  316. {
  317.   uchar p,i;
  318.   tready=0;
  319.   do
  320.   {
  321.     p=0;
  322.         for(i=0;i<6;i++)
  323.         {
  324.           SBUF=kkk[6];                                //发一位数据
  325.           p+=kkk[6];
  326.           TI=0;
  327.         }
  328.         SBUF=p;                                                //发送校验和
  329.         while(TI!=1);
  330.               TI=0;
  331.         while(RI!=1);
  332.               RI=0;
  333.   }
  334.   while(RI!=1);                                  //主机接受不正确,重新发送
  335.   SM2=1;
  336.   ES=1;
  337. }
  338. void sre(void)                                  //接收模块
  339. {
  340.   uchar p,i;
  341.   rready=0;
  342.   while(1);
  343.   {
  344.     p=0;                                         //清校验和
  345.         for(i=0;i<6;i++)
  346.         {
  347.           while(RI!=1);
  348.                 RI=0;
  349.           kkkk[i]=SBUF;                         //接收数据
  350.           p+=kkkk[i];
  351.         }
  352.         while(RI!=1);
  353.               RI=0;
  354.         if(SBUF==p)
  355.         {
  356.           SBUF=0x00;                         //校验和相同发00
  357.         }
  358.         else
  359.         {
  360.           SBUF=0xff;                        //不同发0ff,重新接收
  361.           while(TI==0);
  362.                 TI=0;
  363.         }
  364.   }
  365.   SM2=1;
  366.   ES=1;
  367. }
复制代码



已经整了好几天了,资料啥的都找过了,也没找出个眉目来,希望大家可以帮忙找找问题所在。

IMG_20190526_111901.jpg (3.8 MB, 下载次数: 43)

现象如图所示

现象如图所示

IMG_20190526_153710.jpg (4.4 MB, 下载次数: 45)

这是第二种方法,将数据拆分,一位一位的发送,但实际情况如图

这是第二种方法,将数据拆分,一位一位的发送,但实际情况如图
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:149451 发表于 2019-5-26 13:03 | 只看该作者
两个单片机控制一个LCD1602 ?那不乱套!主机控制即可,从机数据处理后通过串口等于主机联系,由主机控制显示及刷新
回复

使用道具 举报

板凳
ID:478845 发表于 2019-5-26 13:19 | 只看该作者
千万不要沉啊,自顶一下
回复

使用道具 举报

地板
ID:478845 发表于 2019-5-26 13:43 | 只看该作者
w1179benp 发表于 2019-5-26 13:03
两个单片机控制一个LCD1602 ?那不乱套!主机控制即可,从机数据处理后通过串口等于主机联系,由主机控制显 ...

只有小板子控制1602,大板子上面的没有1602(拆走了,虽然有写1602的程序),两个板子是相互独立的,除了数据传输
回复

使用道具 举报

5#
ID:478845 发表于 2019-5-26 14:13 | 只看该作者
w1179benp 发表于 2019-5-26 13:03
两个单片机控制一个LCD1602 ?那不乱套!主机控制即可,从机数据处理后通过串口等于主机联系,由主机控制显 ...

不是两个控制一个,是小的单片机从大的哪里获得数据,并用1602显示出来。
回复

使用道具 举报

6#
ID:478845 发表于 2019-5-26 15:39 | 只看该作者
我又试了试一个新的方式,将数据拆分,一位一位的发送。虽然能够显示了,但是从机显示的数据与主机显示数据完全不符。
回复

使用道具 举报

7#
ID:478845 发表于 2019-5-26 15:43 | 只看该作者
我又试了试别的方法,将数据拆分,一位一位的发送,虽然能够显示,但从机与主机显示的数据有很大的误差。
回复

使用道具 举报

8#
ID:478845 发表于 2019-5-27 18:16 | 只看该作者
请大家给我一点指导
回复

使用道具 举报

9#
ID:478845 发表于 2019-6-2 14:26 | 只看该作者
问题已经解决了,两个单片机的晶振不一样,导致波特率不同,所以在数据传输过程中,使得数据发生了偏差。
回复

使用道具 举报

10#
ID:507927 发表于 2019-6-5 20:25 | 只看该作者
xoxojojo 发表于 2019-6-2 14:26
问题已经解决了,两个单片机的晶振不一样,导致波特率不同,所以在数据传输过程中,使得数据发生了偏差。

楼主你好,默认晶振都是12MHz吗,只要一样就可以对吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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