找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 19060|回复: 18
收起左侧

单片机双机串口通信原理图,proteus仿真以及程序

  [复制链接]
ID:140725 发表于 2017-4-5 01:33 | 显示全部楼层 |阅读模式

给大家分享一个51单片机双机通信,用串口实现,有单片机主机程序和丛机程序的源代码。
下面是proteus仿真原理图:
0.png


主机程序:
  1. #include<reg51.h>
  2. unsigned char i=1;
  3. unsigned char ACK=1;
  4. void delay()                               //延时函数
  5. {
  6.    unsigned char i,j;
  7.    for(i=255;i>0;i--)
  8.    for(j=100;j>0;j--){}
  9. }

  10. unsigned char kbscan()          //键盘扫描函数
  11. {
  12.    unsigned char sccode,recode;  //定义行、列
  13.    P1=0xf0;                       //高四位作为输入先写1
  14.    if((P1&0xf0)!=0xf0)                          //判断是否按键按下
  15.       {                                                 
  16.             delay();                                  //延时消抖
  17.                 if((P1&0xf0)!=0xf0)                  //再次判断判断有没有按键按下
  18.                   {
  19.                     sccode=0xfe;
  20.                     while((sccode&0x10)!=0)
  21.                          {
  22.                           P1=sccode;
  23.                           if((P1&0xf0)!=0xf0) //判断当前行是否有按键按下
  24.                            {
  25.                             recode=P1&0xf0;   //保留高四位输入值
  26.                                 sccode=sccode&0x0f; //保留第低四位的值
  27.                                 return(recode+sccode);
  28.                            }
  29.                            else
  30.                             sccode=(sccode<<1)|0x01;
  31.                          }
  32.                   }
  33.           }
  34.           return 0;
  35. }
  36. send()interrupt 4      //串行口通信中断
  37. {
  38.   if(TI==1&&ACK==1)
  39.   {
  40.     TI=0;
  41.     if(i==0||i==0x22||i==0x44||i==0x66||i==0x88||i==0xaa||i==0xcc||i==0xdd||i==0xee)                        //有按键按下,需要修改波特率
  42.     {
  43.           ACK=0;
  44.           SBUF=i;                //发送数据
  45.         }
  46.     else if(i==11)                         //循环发送,发了十一个字符后重新发
  47.         {
  48.        i=1;
  49.            SBUF=1;
  50.         }
  51.         else
  52.         {
  53.       i++;
  54.       SBUF=i;                     //发送数据
  55.     }
  56.   }
  57.   else if(RI==1)                         //接收回应的信号
  58.     {
  59.            RI=0;
  60.            ACK=SBUF;                         //接收回应信号 修改初值 触发串口通信中断
  61.            TI=1;
  62.            TH1=TL1=i;
  63.            i=1;
  64.         }
  65. }
  66. void main()
  67. {
  68.   TMOD=0x20;
  69.   TH1=0x00;TL1=0x00;   //置初值
  70.   TR1=1;EA=1;ES=1;    //使T1开始工作;开总中断、串行中断
  71.   SCON=0x50;          //使T1工作在工作方式1
  72.   SBUF=i;  
  73.   while(1)
  74.   {
  75.     while(kbscan())
  76.            {
  77.             switch(kbscan())                                        //不同的按键对应不同的波特率
  78.                 {
  79.             case 0xeb:i=0x00;break;
  80.                 case 0xdb:i=0x22;break;
  81.                 case 0xbb:i=0x44;break;
  82.                 case 0xed:i=0x66;break;
  83.                 case 0xdd:i=0x88;break;
  84.                 case 0xbd:i=0xaa;break;
  85.                 case 0xee:i=0xcc;break;
  86.                 case 0xde:i=0xdd;break;
  87.                 case 0xbe:i=0xee;break;
  88.           }
  89.         }
  90.   }
  91. }
复制代码

丛机程序:
  1. #include<reg51.h>
  2. #define LCD_DATA P0
  3. sbit LCD_BUSY=LCD_DATA^7;
  4. sbit LCD_RW=P3^3;
  5. sbit LCD_RS=P3^2;
  6. sbit LCD_EN=P3^4;
  7. sbit P20=P2^0;
  8. sbit P21=P2^1;
  9. sbit P22=P2^2;
  10. sbit P23=P2^3;
  11. sbit P24=P2^4;
  12. sbit P25=P2^5;
  13. sbit P26=P2^6;
  14. sbit P27=P2^7;
  15. sbit P30=P3^0;
  16. sbit P31=P3^1;
  17. sbit P32=P3^2;
  18. sbit P33=P3^3;
  19. sbit P34=P3^4;
  20. sbit P35=P3^5;
  21. sbit P36=P3^6;
  22. sbit P37=P3^7;

  23. unsigned char i=0;
  24. void LCD_check_busy(void)        //检测LCD状态
  25. {
  26.   while(1)
  27.   {
  28.    
  29.    LCD_RS=0;
  30.    LCD_RW=1;
  31.    LCD_EN=0;
  32.    LCD_DATA=0xff;
  33.    LCD_EN=1;
  34.    if(!LCD_BUSY)break;
  35.    LCD_EN=0;
  36.   }
  37. }

  38. void LCD_cls(void)  //LCD清屏
  39. {
  40.   LCD_check_busy();
  41.   LCD_EN=0;
  42.   LCD_RS=0;
  43.   LCD_RW=0;
  44.   LCD_DATA=0x01;
  45.   LCD_EN=1;
  46.   LCD_EN=0;
  47. }

  48. void LCD_write_instruction(unsigned char LCD_instruction)//写指令到LCD
  49. {
  50. LCD_check_busy();
  51. LCD_EN=0;
  52. LCD_RS=0;
  53. LCD_RW=0;
  54. LCD_DATA=LCD_instruction;
  55. LCD_EN=1;
  56. LCD_EN=0;
  57. }

  58. void LCD_write_data(unsigned char LCD_data)//输出一个字节数据到LCD
  59. {
  60.   LCD_check_busy();
  61.   LCD_EN=0;
  62.   LCD_RS=1;
  63.   LCD_RW=0;
  64.   LCD_DATA=LCD_data;
  65.   LCD_EN=1;
  66.   LCD_EN=0;
  67. }

  68. void LCD_initial()
  69. {
  70.    LCD_write_instruction(0x38);          //两行显示
  71.    LCD_write_instruction(0x0C);                 //显示开
  72.    LCD_write_instruction(0x06);             //光标加1
  73.    LCD_write_instruction(0x01);                  //清屏
  74. }

  75. re() interrupt 4                                   //串行口通信中断
  76. {
  77.   if(RI==1)
  78.   {
  79.     RI=0;
  80.     i=SBUF;                                                   // 接收数据
  81.     if(i==0||i==0x22||i==0x44||i==0x66||i==0x88||i==0xaa||i==0xcc||i==0xdd||i==0xee)
  82.     {
  83.           SBUF=1;                                           //接收发过来 要修改的初值
  84.        
  85.     }
  86.     else                                                   //接收正常通信的数据
  87.     {
  88.       LCD_write_instruction(0x80+i);
  89.       LCD_write_data('0'+i);
  90.       if(i==11)LCD_initial();
  91.     }
  92.   }
  93.   else if(TI==1)
  94.   {
  95.     TI=0;
  96.         TH1=i;TL1=i;                                 //发送确认信号后 修改初值
  97.   }
  98. }
  99. void main()
  100. {
  101.   TMOD=0x20;
  102.   TH1=0x00;TL1=0x00;   //置初值
  103.   TR1=1;EA=1;ES=1;    //使T1开始工作;开总中断、串行中断
  104.   SCON=0x50;          //使T1工作在工作方式1

  105. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


0.png


下载:
串口通信仿真.zip (90.41 KB, 下载次数: 359)

评分

参与人数 1黑币 +3 收起 理由
单车有风 + 3 很给力!

查看全部评分

回复

使用道具 举报

ID:231632 发表于 2017-11-22 23:12 | 显示全部楼层
大牛,没毛病,太感谢了。
单片机I/O口不过够用了,正好用这个程序。
回复

使用道具 举报

ID:268531 发表于 2018-1-2 15:59 | 显示全部楼层
太厉害了,我这两天做这个就卡住了
回复

使用道具 举报

ID:274160 发表于 2018-1-10 10:40 | 显示全部楼层
厉害啊,楼主无敌
回复

使用道具 举报

ID:348220 发表于 2018-6-9 21:24 | 显示全部楼层
好厉害
回复

使用道具 举报

ID:419206 发表于 2018-11-5 16:41 | 显示全部楼层
非常好,解决了学校的单片机作业问题
回复

使用道具 举报

ID:735584 发表于 2020-5-13 22:28 | 显示全部楼层
不知为何LCD没反应
回复

使用道具 举报

ID:735584 发表于 2020-5-13 22:29 | 显示全部楼层
不知为何LCD没反应
回复

使用道具 举报

ID:751401 发表于 2020-5-14 09:50 | 显示全部楼层
很有用,谢谢分享。
回复

使用道具 举报

ID:495287 发表于 2020-5-14 10:59 | 显示全部楼层
谢谢楼主指点分享。
回复

使用道具 举报

ID:777083 发表于 2020-6-13 09:00 | 显示全部楼层
有点小好奇,为什么按动加减乘除键对数字的显示速度没有改变
回复

使用道具 举报

ID:790996 发表于 2020-6-27 15:35 | 显示全部楼层
楼主厉害
回复

使用道具 举报

ID:495287 发表于 2020-7-26 22:42 | 显示全部楼层
串口双线连两片,
主从耐心等中断;
扫描按键得指令,
BUF承担来回链,
再看仿真电路线,
两片共用接地源?

回复

使用道具 举报

ID:789537 发表于 2020-11-15 11:40 来自手机 | 显示全部楼层
大佬,是全双工的吗
回复

使用道具 举报

ID:425494 发表于 2021-3-19 12:36 | 显示全部楼层
这个仿真好
回复

使用道具 举报

ID:28992 发表于 2021-3-20 04:36 | 显示全部楼层
实在是感激不尽,谢谢啦!
回复

使用道具 举报

ID:937856 发表于 2021-6-16 11:47 | 显示全部楼层
真的很好,看了之后收获很多!
回复

使用道具 举报

ID:937856 发表于 2021-6-16 11:48 | 显示全部楼层
太好了太好了,看了之后有好像知道该怎么做了
回复

使用道具 举报

ID:995918 发表于 2021-12-22 22:54 | 显示全部楼层
学习了大佬的程序,真的受益匪浅。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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