打印

STC51单片机双机通信(UART)求解!!!

[复制链接]
2021|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
JOKER21|  楼主 | 2015-9-6 19:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位前辈,帮忙看一下这两段程序(分别是主机和从机),要实现的功能是两单片机进行握手通信,成功后发送字符串,并在从机的数码管上显示出来,过程中会在程序的不同的位置点亮LED灯作为指示。


/*本例是单片机双机通信主机程序*/
/*预定义及全局变量*/
#include<reg52.h>
#include<string.h>
#define uchar unsigned char
/*握手信号宏定义*/
#define _RDY_ 0x06
#define _BUSY_ 0x15
#define _OK_ 0x00
#define _SUCC_ 0x0f
#define _ERR_ 0xf0
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;
uchar code str[]="520";
uchar len=0,CheckNum=0;
/*函数声明*/
void init();
void SendAChar(uchar);
void SendData(uchar *);
uchar ReceiveAChar();
void communication();
/*主函数*/
void main()
{
uchar ReplyFromGuest_main=0;
/*初始化*/
init();
while(1)
{
  /*握手通信*/
  communication();
  /*发送数据*/
  ReplyFromGuest_main=_ERR_;
  while(ReplyFromGuest_main!=_SUCC_)
  {
   /*发送长度*/
   len=strlen(str);
   SendAChar(len);
   led1=0;
   /*发送数据*/
   SendData(str);
   led2=0;
   /*发送校验码*/
   SendAChar(CheckNum);
   led3=0;
   /*等待从机反馈*/
   ReplyFromGuest_main=ReceiveAChar();
   led4=0;
  }
  
  led5=0;
}
}
/*函数实现*/
void init()
{
/*波特率设置*/
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
PCON=0x00;
TR1=1;
/*串口初始化*/
SCON=0x50;//工作方式1,可接收
}
void SendAChar(uchar ch)
{
TI=0;
SBUF=ch;
while(TI==0);
TI=0;
}
void SendData(uchar *p)
{
uchar i;
for(i=0;i<len;i++)
{
  CheckNum=CheckNum^(*p);
  SendAChar(*p);
  p++;
}
}
uchar ReceiveAChar()
{
uchar ReplyFromGuest_FuncRec;

RI=0;
while(RI==0);
ReplyFromGuest_FuncRec=SBUF;
RI=0;
return  ReplyFromGuest_FuncRec;
}
void communication()
{
uchar ReplyFromGuest_FuncCom;
ReplyFromGuest_FuncCom=_BUSY_;
while(ReplyFromGuest_FuncCom!=_OK_)
{
  /*发送_RDY_到从机,询问是否可以接收*/
  TI=0;
  SBUF=_RDY_;//可以直接用SendAChar(_RDY_)吗?
  while(TI==0);
  TI=0;
  /*等待从机回复*/
  ReplyFromGuest_FuncCom=ReceiveAChar();
}
led0=0;
}
:):):):):):):):):):):):):):):):)
:):):):):):):):):):):):):):):):)
/*本例是单片机双机通信从机程序*/
/*预定义及全局变量*/
#include<reg52.h>
#define uchar unsigned char
/*握手信号宏定义*/
#define _RDY_ 0x06
#define _BUSY_ 0x15
#define _OK_ 0x00
#define _SUCC_ 0x0f
#define _ERR_ 0xf0
sbit dula=P2^6;
sbit wela=P2^7;
sbit led0=P1^0;
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;
uchar code table[]={//此处只给出0-9的数码
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};
uchar code BUF[10];
uchar len=0,CheckNum=0;
/*函数声明*/
void init();
uchar ReceiveAChar();
void ReceiveData(uchar *p);
void SendAChar(uchar);
/*主函数*/
void main()
{
uchar ReplyFromHost,ReplyFromGuest_ReceiveData;
/*初始化*/
init();
while(1)
{
  /*接收握手信号_RDY_*/
  ReplyFromHost=_RDY_-1;//确保能够进入下面的循环
  while(ReplyFromHost!=_RDY_)
  {
   ReplyFromHost=ReceiveAChar();
   led0=0;
  }
  led1=0;
  /*向主机发送已经准备好的信号_OK_*/
  SendAChar(_OK_);
  led2=0;
  /*接收数据*/
  ReplyFromGuest_ReceiveData=0xff;
  while(ReplyFromGuest_ReceiveData==0xff)
  {
   /*接收长度*/
   len=ReceiveAChar();
   led3=0;
   /*接收数据*/
   ReceiveData(BUF);
   led4=0;
   /*接收校验码*/
   ReplyFromHost=ReceiveAChar();
   led5=0;
   /*进行校验*/
   if(CheckNum==ReplyFromHost)
   {
    SendAChar(_SUCC_);
    ReplyFromGuest_ReceiveData=0x00;
   }
   else
   {
    SendAChar(_ERR_);
    ReplyFromGuest_ReceiveData=0xff;
   }  
  }
  led6=0;
  P1=BUF[0];
}
}
/*函数实现*/
void init()
{
/*波特率设置*/
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
PCON=0x00;
TR1=1;
/*串口初始化*/
SCON=0x50;//工作方式1,可接收
}
uchar ReceiveAChar()
{
uchar ReplyFromHost;

RI=0;
while(RI==0);
ReplyFromHost=SBUF;
RI=0;
return  ReplyFromHost;
}
void ReceiveData(uchar *p)
{
uchar i;
for(i=0;i<len;i++)
{
  *p=ReceiveAChar();
  CheckNum=CheckNum^(*p);
  p++;
}
*p='\0';
}
void SendAChar(uchar ch)
{
TI=0;
SBUF=ch;
while(TI==0);
TI=0;
}

相关帖子

沙发
JOKER21|  楼主 | 2015-9-6 19:51 | 只看该作者
怎么都不出现应该出现的现象,逻辑上感觉没问题,请大家教我。

使用特权

评论回复
板凳
dirtwillfly| | 2015-9-7 08:49 | 只看该作者
好长的代码

使用特权

评论回复
地板
dirtwillfly| | 2015-9-7 08:50 | 只看该作者
建议两个mcu分别调试,成功了再进行通讯。
那么长的代码,很少有人有那么多时间来读的

使用特权

评论回复
5
JOKER21|  楼主 | 2015-9-7 20:36 | 只看该作者
dirtwillfly 发表于 2015-9-7 08:50
建议两个mcu分别调试,成功了再进行通讯。
那么长的代码,很少有人有那么多时间来读的 ...

这个程序是2机同时调试才可能有现象的啊,单机怎么调试呢?
之前用过串口调试助手,但发送的第一个数据_OK_,也就是0x06,在串口调试助手上就是乱码。

使用特权

评论回复
6
dirtwillfly| | 2015-9-7 21:00 | 只看该作者
JOKER21 发表于 2015-9-7 20:36
这个程序是2机同时调试才可能有现象的啊,单机怎么调试呢?
之前用过串口调试助手,但发送的第一个数据_O ...

通过串口调试助手分别调试,都成功了再让两个mcu进行联合调试

使用特权

评论回复
7
溪水向西| | 2015-9-16 16:12 | 只看该作者
先用串口助手向电脑发数据,看看主机这边的串口函数有没有写错,然后再从电脑向从机发数据,看能不能显示,可以查从机的函数有没有错

使用特权

评论回复
8
元方义城| | 2015-9-28 09:53 | 只看该作者
JOKER21 发表于 2015-9-7 20:36
这个程序是2机同时调试才可能有现象的啊,单机怎么调试呢?
之前用过串口调试助手,但发送的第一个数据_O ...

用串口助手看发送的主机发过来的数据,你发送的是字符串那就看发送来的字符,发送的是16进制你就让串口助手看16进制,发送成功了。用串口助手模拟主机发送给从机,看从机给不给你反馈。一般联机都必须这么弄的。不然原因找不到,慢慢试那到何年马月。

使用特权

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

本版积分规则

1

主题

3

帖子

0

粉丝