基于51的双机通信系统

        最近在做关于双机通信系统的课设,遇到了一些问题,查了好几个小时也没找到原因,郁闷了半天,老师要求主机在发送数据的时候显示数据,从机接受数据并对数据进行处理后显示数据。因为没有要求数据具体是什么,是几位的数据,所以刚开始搭建仿真时使用的是单位数码管。仿真如下图:

 当按键K1按下,乙机向甲机发送数据并显示该数据,甲机接受数据后对数据加一显示。

效果如下:

 代码如下:

发送端(乙机):

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit K1 = P1^7;//按键口
uchar NumX = 5;//发送端数码管要显示的数
uchar code DSY_CODE[]=//显示数组(共阴)
{
     0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};

void Delay(uint x)//延时
{
     uchar i,j;
    for(i=x;i>0;i--)
         for(j=110;j>0;j--);
}
void main()
{
    P2 = 0x00; //初始化
    SCON = 0x50;//串口方式1
    TMOD = 0x20;//定时器工作方式2
    PCON = 0x00;//波特率正常
    TH1  = 0xfd;//T1定时器装初值
    TL1  = 0xfd;
    TR1 = 1;//启动T1定时器 
    EA=1;//开总中断
    ES=1;//开启串口中断
   
    while(1)
    {
        if(K1==0);//按键按下
        {
            Delay(3);//消抖
             if (K1==0)//按键按下
             {
                     SBUF = NumX;//发送出去
                      P2 = DSY_CODE[NumX];//显示
                      Delay(20);
                      P2 = 0x00;
                      while(!T1);//等待是否发送完毕
                       TI = 0;
                      while(!K1);//等待按键释放
              }
        }
    }
}

接收端(甲机):

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uint num;
uchar code DSY_CODE[]=//显示数组(共阴)
{
     0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};

void Delay(uint x)//延时
{
     uchar i,j;
    for(i=x;i>0;i--)
         for(j=110;j>0;j--);
}

void main()
{
     P2 = 0x00; //初始化
    SCON = 0x50;//串口方式1
    TMOD = 0x20;//定时器工作方式2
    PCON = 0x00;//波特率正常
    TH1  = 0xfd;//T1定时器装初值
    TL1  = 0xfd;
    TR1 = 1;//启动T1定时器 
    EA=1;//开总中断
    ES=1;//开启串口中断


    while(1)
    {

    }
}

void Serial_INT() interrupt 4//中断显示
{
     if(RI)
    {
         RI = 0;
        num=SBUF+1;
        if(num>=0&&num<=9)
        {
            P2 = DSY_CODE[num];//显示
            Delay(60);
            P2 = 0x00;
        }
        else
            P2 = 0x00;//不显示
    }
}

注:中断里最好不要加延时,延时太长,你中断还没执行完,又被新的中断打断, 最终一层层嵌套,就出不来了(用是因为没有想到好的办法让接受端的数码管亮了又灭)

本来以为课设就到此为止了,只要到时候老师把器件一发,按照仿真搭好板子就结束了,没想到老师发的是四位共阳极数码管,四位数码管只显示一个数字确实有些浪费,所以就又开始改仿真图和代码。

仿真图如下:

 效果如下:

 发送端代码(乙机):

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit K1 = P1^7;//按键
sbit W1 = P2^0;
sbit W2 = P2^1;
sbit W3 = P2^2;
sbit W4 = P2^3;
int ge,shi,bai,qian;
int NumX = 158;//发送端数码管要显示的数
uchar code DSY_CODE[]=//显示数组(共阳)
{
     0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
};

void Delay(uint x)//延时
{
     uchar i,j;
    for(i=x;i>0;i--)
         for(j=110;j>0;j--);
}

void LED2_StaticDisplay(int number,int val)//位选,段选函数
{
     switch(number) 
      {    
       case(0):
       W1=1;W2=0;W3=0;W4=0;break; 

       case(1):
       W1=0;W2=1;W3=0;W4=0;break; 

       case(2):
       W1=0;W2=0;W3=1;W4=0;break; 

       case(3):
       W1=0;W2=0;W3=0;W4=1;break; 
      }
    P0 = DSY_CODE[val]; 
    }

void main()
{
    P0 = 0x00;//初始化
    P2 = 0x00; //初始化
    SCON = 0x50;//串口方式1
    TMOD = 0x20;//定时器工作方式2
    PCON = 0x00;//波特率正常
    TH1  = 0xfd;//T1定时器装初值
    TL1  = 0xfd;
    TR1 = 1;//启动T1定时器 
    EA=1;//开总中断
    ES=1;//开启串口中断
    while(1)
    {
        if(K1==0);//按键按下
        {
        Delay(3);//消抖
             if (K1==0)//按键按下
             {
                  SBUF = NumX;//发送出去
                  bai  = NumX/100;
                  shi  = NumX%100/10;
                  ge   = NumX%10;
                LED2_StaticDisplay(0,0);
                Delay(10);
                LED2_StaticDisplay(1,bai);
                Delay(10);
                LED2_StaticDisplay(2,shi);
                Delay(10);
                LED2_StaticDisplay(3,ge);
                Delay(10);
                P2 = 0x00;
                while(!T1);//等待是否发送完毕
                   TI = 0;
                while(!K1);//等待按键释放
       } 
        }
            
    }
}

接受端代码(甲机):

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit K1 = P1^7;
sbit W1 = P2^0;
sbit W2 = P2^1;
sbit W3 = P2^2;
sbit W4 = P2^3;
int ge,shi,bai;
int num;
uchar code DSY_CODE[]=//显示数组(共阳)
{
     0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90
};
void Delay(uint x)//延时函数
{
     uchar i,j;
    for(i=x;i>0;i--)
         for(j=110;j>0;j--);
}

void LED2_StaticDisplay(int number,int val)//位选,段选函数
{
     switch(number) 
      {    
      case(0):
       W1=1;W2=0;W3=0;W4=0;break; 

       case(1):
       W1=0;W2=1;W3=0;W4=0;break; 

       case(2):
       W1=0;W2=0;W3=1;W4=0;break; 

       case(3):
       W1=0;W2=0;W3=0;W4=1;break; 
    }
   P0 = DSY_CODE[val]; 
}


void main()
{

    P0 = 0x00;//初始化
    P2 = 0x00; //初始化
    SCON = 0x50;//串口方式1
    TMOD = 0x20;//定时器工作方式2
    PCON = 0x00;//波特率正常
    TH1  = 0xfd;//T1定时器装初值
    TL1  = 0xfd;
    TR1 = 1;//启动T1定时器 
    EA=1;//开总中断
    ES=1;//开启串口中断
    while(1)
    {

    }
}

void uart() interrupt 4//中断显示
{
     if(RI)
    {
         RI = 0;    
        num = SBUF+1;
        bai  = num/100;
        shi  = num%100/10;
        ge   = num%10;
        LED2_StaticDisplay(0,0);
        Delay(10);
        LED2_StaticDisplay(1,bai);
        Delay(10);
        LED2_StaticDisplay(2,shi);
        Delay(10);
        LED2_StaticDisplay(3,ge);
        Delay(10);
        P2 = 0x00;
    }
}

实物图:

         实物出来后,数码管的亮度不够,特别暗,上图是在晚上拍的,所以看着还比较明显,查了一下原因,是因为单片机的驱动能力有限导致。可通过外接驱动或者加三极管放大器或者更换大驱动电流单片机实现亮度增加。

  • 20
    点赞
  • 160
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
单片机双机通信涉及到两个单片机之间的实时数据传输和显示,而LCD(液晶显示器)则是一种常用的显示设备。在单片机双机通信中,可以通过将数据通过串口(例如UART)发送到另一个单片机,然后再由另一个单片机将接收到的数据经过处理后显示在LCD上。 首先,需要在两个单片机之间建立双向通信。可以使用串口通信,其中一个单片机作为发送方,另一个单片机作为接收方。发送方和接收方需要通过相同的波特率进行设置,以确保数据的正确传输。发送方将要传输的数据发送到串口,接收方通过串口接收到数据。 其次,接收方单片机需要对接收到的数据进行处理,以便在LCD上显示。这可以通过使用适当的程序进行解析和处理。例如,如果要显示的数据是字符串,可以使用适当的字符串处理函数将接收到的字符转换为字符串,并将其存储在适当的变量中。之后,可以使用LCD显示函数将这些数据显示在LCD上。 需要注意的是,双机通信中的通信协议和数据格式需要在两个单片机之间事先约定好。这样可以确保发送方和接收方之间能够正确地解析和处理数据,以便准确地在LCD上显示。 综上所述,单片机双机通信LCD既涉及到实时数据传输,也涉及到LCD的显示。通过使用串口通信和适当的程序处理,可以实现在两个单片机之间传输数据并在LCD上显示。这样可以实现实时数据的双向传输和显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值