找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机多机通信,数码管显示通信信息,C语言代码+proteus仿真

  [复制链接]
跳转到指定楼层
楼主
一个主机,三个从机,拨码开关前三个是选择想要通信的从机,矩阵键盘是  将0-F  16个字符输入到主机,在发送到从机,数码管显示

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)



主机代码
#include <reg51.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
#define SUCC 0x2A                // 接收成功
#define ERR 0xF0                // 接收错误
#define MAXLEN 64            // 缓冲区最大长度
#define KEY P2

uchar buf;
uchar addr;         
uchar code duanma[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,};        

void delay(uint t)         // 延时t毫秒
{
            uint i,j;        
                for (i=0;i<t;i++)
                for (j=0;j<125;j++);        
}
void senddata(uchar buf)        //发送数据函数
{
                TI = 0;
                TB8 = 0;                                // 发送数据帧
                SBUF =buf;        
                while(!TI);
                TI = 0;
}

void init_serial()                    // 串口初始化函数
{
        TMOD = 0x20;                        
        {
        
        };
                // 定时器T1使用工作方式2
        TH1 = 250;
        TL1 = 250;
        TR1 = 1;                                        // 开始计时
        PCON = 0x80;                                // SMOD = 1
        SCON = 0xd0;                                // 工作方式3,9位数据位,波特率9600kbit/s,允许接收SM2=0
}
uchar keyscan()          //键盘处理函数
{
        uchar a,b,c;
        KEY=0x0f;               //键盘口置00001111
        if(KEY!=0x0f)      //查询键口值是否变化
        {
                delay(20);       //去抖
                if(KEY!=0x0f)    //        有键按下
                {
                        a=KEY;       //键值放在寄存器a中               
                }
                 KEY=0xf0;                //将键盘口置11110000
                 c=KEY;         //将第二次取得值放入寄存器c中
                 a=a|c;         //将两个数据融合
                 switch(a)      //对比数据值
                 {
                         case  0xee  :  b=0;break;
                        case  0xde  :  b=1;break;
                        case  0xbe  :  b=2;break;
                        case  0x7e  :  b=3;break;
                        case  0xed  :  b=4;break;
                        case  0xdd  :  b=5;break;
                        case  0xbd  :  b=6;break;
                        case  0x7d  :  b=7;break;
                        case  0xeb  :  b=8;break;
                        case  0xdb  :  b=9;break;
                        case  0xbb  :  b=10;break;
                        case  0x7b  :  b=11;break;
                        case  0xe7  :  b=12;break;
                        case  0xd7  :  b=13;break;
                        case  0xb7  :  b=14;break;
                        case  0x77  :  b=15;break;
                        default:break;   //键值错误处理
                 }
        }
        return(b);   //将b作为返回值
}

void main()
{
        while(1)
    {
               
                 buf=keyscan();
                  P1=duanma[keyscan()];
            /* 通过P0口读要访问的从机地址 */
          P0 = 0xff;
          addr = P0&0x0f;
          init_serial();                // 串口初始化

          EA = 1;                                // 打开所有中断
        
          TI = 0;
          TB8 = 1;                                // 发送地址帧        
          SBUF = addr;
          while(!TI);
          TI = 0;
          senddata(buf);          // 发送数据
         
        }
        
}
从机代码
#include <reg51.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
#define SUCC 0x2A                // 接收成功
#define ERR 0xF0                // 接收错误
#define MAXLEN 64            // 缓冲区最大长度

uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
uchar buf;                        //数据寄存
uchar addr;                    //地址寄存

sbit led= P3^4;                // 此引脚控制发光管

/* 延时t毫秒 */
void delay(uint t)
{
        uint i,j;
                for (i=0;i<t;i++)
                for (j=0;j<125;j++);
}

/* 接受数据函数 */
uchar recvdata()
{

        /* 接收数据 */
                while(!RI);
                if (RB8==1)
                        return 0xee;                // 若接收的为地址帧,则返回0xee
                buf = SBUF;        
                RI = 0;        
        return 0;                                        // 返回0
}

/* 串口初始化函数 */
void init_serial()
{
        TMOD = 0x20;                                // 定时器T1使用工作方式2
        TH1 = 250;
        TL1 = 250;
        TR1 = 1;                                        // 开始计时
        PCON = 0x80;                                // SMOD = 1
        SCON = 0xd0;                                // 工作方式,9位数据位,波特率9600kbit/s,允许接收
}

/* 主程序 */
void main()
{
        uchar i = 0;
        uchar tmp = 0xff;
        P1= 0xff;
        addr = P1&0x0f;                                // 获取本机地址
        led = 1;                                        // 发光管不亮
        
        init_serial();                                // 串口初始化

        EA = 1;                                                // 打开所有中断
        

        while(1)                    //进入从机应答
        {
                SM2 = 1;                                // 只接收地址帧
               
                while (tmp!=addr)        // 如果接收到的地址帧不是本机地址,则继续等待
                 {
                         P0=0XFF;            //如果不是本机,就关掉数码管
                        RI = 0;
                        while(!RI)
                        tmp = SBUF;
                        RI = 0;
                 }        
                    SM2 = 0;                                // 允许接收数据
                                
            tmp = recvdata();    // 数据接收  
            
                     if (tmp==0x00)           
                     {                 
                          P0=table[buf];

                            led = 0;                        
                            delay(30);
                            led = 1;
                        
                     }            
        // 如果接收数据时发现地址帧,则重新开始整个接收过程        
        }
}


如果打开运行出错,请重新添加下hex文件,就可以了的。
全部资料51hei下载地址:
多机通信.zip (98.09 KB, 下载次数: 93)






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

使用道具 举报

沙发
ID:431611 发表于 2019-7-25 01:09 | 只看该作者
下载下来试了一下,提示错误,仿真不呢能够正常运行
回复

使用道具 举报

板凳
ID:247623 发表于 2019-8-7 08:27 | 只看该作者
楼主,请教一下,我用的proteus7.8和proteus8.0都无法打开你的仿真文件,是哪里出问题了吗
回复

使用道具 举报

地板
ID:559790 发表于 2019-8-21 10:58 | 只看该作者
yilinghai 发表于 2019-8-7 08:27
楼主,请教一下,我用的proteus7.8和proteus8.0都无法打开你的仿真文件,是哪里出问题了吗

请用最新的版本,proteus8.6的就可以打开
回复

使用道具 举报

5#
ID:559790 发表于 2019-8-21 11:01 | 只看该作者
yinxiangxv 发表于 2019-7-25 01:09
下载下来试了一下,提示错误,仿真不呢能够正常运行

上面三个是从机,请添加从机hex文件,就下面一个是主机,要添加主机hex文件。压缩包里有两个hex文件的
回复

使用道具 举报

6#
ID:508562 发表于 2019-11-18 14:02 | 只看该作者
楼主 你丛机P1的值是干嘛用啊  看你的仿真电路图 P1口又没用
回复

使用道具 举报

7#
ID:745845 发表于 2020-5-15 15:52 | 只看该作者
仿真以后按开关没反应
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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