基于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;
    }
}

实物图:

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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值