找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 21467|回復(fù): 18
收起左側(cè)

單片機(jī)雙機(jī)串口通信原理圖,proteus仿真以及程序

  [復(fù)制鏈接]
ID:140725 發(fā)表于 2017-4-5 01:33 | 顯示全部樓層 |閱讀模式

給大家分享一個(gè)51單片機(jī)雙機(jī)通信,用串口實(shí)現(xiàn),有單片機(jī)主機(jī)程序和叢機(jī)程序的源代碼。
下面是proteus仿真原理圖:
0.png


主機(jī)程序:
  1. #include<reg51.h>
  2. unsigned char i=1;
  3. unsigned char ACK=1;
  4. void delay()                               //延時(shí)函數(shù)
  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()          //鍵盤掃描函數(shù)
  11. {
  12.    unsigned char sccode,recode;  //定義行、列
  13.    P1=0xf0;                       //高四位作為輸入先寫1
  14.    if((P1&0xf0)!=0xf0)                          //判斷是否按鍵按下
  15.       {                                                 
  16.             delay();                                  //延時(shí)消抖
  17.                 if((P1&0xf0)!=0xf0)                  //再次判斷判斷有沒有按鍵按下
  18.                   {
  19.                     sccode=0xfe;
  20.                     while((sccode&0x10)!=0)
  21.                          {
  22.                           P1=sccode;
  23.                           if((P1&0xf0)!=0xf0) //判斷當(dāng)前行是否有按鍵按下
  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;                //發(fā)送數(shù)據(jù)
  45.         }
  46.     else if(i==11)                         //循環(huán)發(fā)送,發(fā)了十一個(gè)字符后重新發(fā)
  47.         {
  48.        i=1;
  49.            SBUF=1;
  50.         }
  51.         else
  52.         {
  53.       i++;
  54.       SBUF=i;                     //發(fā)送數(shù)據(jù)
  55.     }
  56.   }
  57.   else if(RI==1)                         //接收回應(yīng)的信號(hào)
  58.     {
  59.            RI=0;
  60.            ACK=SBUF;                         //接收回應(yīng)信號(hào) 修改初值 觸發(fā)串口通信中斷
  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())                                        //不同的按鍵對(duì)應(yīng)不同的波特率
  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. }
復(fù)制代碼

叢機(jī)程序:
  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)        //檢測(cè)LCD狀態(tài)
  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)//輸出一個(gè)字節(jié)數(shù)據(jù)到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);             //光標(biāo)加1
  73.    LCD_write_instruction(0x01);                  //清屏
  74. }

  75. re() interrupt 4                                   //串行口通信中斷
  76. {
  77.   if(RI==1)
  78.   {
  79.     RI=0;
  80.     i=SBUF;                                                   // 接收數(shù)據(jù)
  81.     if(i==0||i==0x22||i==0x44||i==0x66||i==0x88||i==0xaa||i==0xcc||i==0xdd||i==0xee)
  82.     {
  83.           SBUF=1;                                           //接收發(fā)過來 要修改的初值
  84.        
  85.     }
  86.     else                                                   //接收正常通信的數(shù)據(jù)
  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;                                 //發(fā)送確認(rèn)信號(hào)后 修改初值
  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. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼


0.png


下載:
串口通信仿真.zip (90.41 KB, 下載次數(shù): 363)

評(píng)分

參與人數(shù) 1黑幣 +3 收起 理由
單車有風(fēng) + 3 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:231632 發(fā)表于 2017-11-22 23:12 | 顯示全部樓層
大牛,沒毛病,太感謝了。
單片機(jī)I/O口不過夠用了,正好用這個(gè)程序。
回復(fù)

使用道具 舉報(bào)

ID:268531 發(fā)表于 2018-1-2 15:59 | 顯示全部樓層
太厲害了,我這兩天做這個(gè)就卡住了
回復(fù)

使用道具 舉報(bào)

ID:274160 發(fā)表于 2018-1-10 10:40 | 顯示全部樓層
厲害啊,樓主無敵
回復(fù)

使用道具 舉報(bào)

ID:348220 發(fā)表于 2018-6-9 21:24 | 顯示全部樓層
好厲害
回復(fù)

使用道具 舉報(bào)

ID:419206 發(fā)表于 2018-11-5 16:41 | 顯示全部樓層
非常好,解決了學(xué)校的單片機(jī)作業(yè)問題
回復(fù)

使用道具 舉報(bào)

ID:735584 發(fā)表于 2020-5-13 22:28 | 顯示全部樓層
不知為何LCD沒反應(yīng)
回復(fù)

使用道具 舉報(bào)

ID:735584 發(fā)表于 2020-5-13 22:29 | 顯示全部樓層
不知為何LCD沒反應(yīng)
回復(fù)

使用道具 舉報(bào)

ID:751401 發(fā)表于 2020-5-14 09:50 | 顯示全部樓層
很有用,謝謝分享。
回復(fù)

使用道具 舉報(bào)

ID:495287 發(fā)表于 2020-5-14 10:59 | 顯示全部樓層
謝謝樓主指點(diǎn)分享。
回復(fù)

使用道具 舉報(bào)

ID:777083 發(fā)表于 2020-6-13 09:00 | 顯示全部樓層
有點(diǎn)小好奇,為什么按動(dòng)加減乘除鍵對(duì)數(shù)字的顯示速度沒有改變
回復(fù)

使用道具 舉報(bào)

ID:790996 發(fā)表于 2020-6-27 15:35 | 顯示全部樓層
樓主厲害
回復(fù)

使用道具 舉報(bào)

ID:495287 發(fā)表于 2020-7-26 22:42 | 顯示全部樓層
串口雙線連兩片,
主從耐心等中斷;
掃描按鍵得指令,
BUF承擔(dān)來回鏈,
再看仿真電路線,
兩片共用接地源?

回復(fù)

使用道具 舉報(bào)

ID:789537 發(fā)表于 2020-11-15 11:40 來自觸屏版 | 顯示全部樓層
大佬,是全雙工的嗎
回復(fù)

使用道具 舉報(bào)

ID:425494 發(fā)表于 2021-3-19 12:36 | 顯示全部樓層
這個(gè)仿真好
回復(fù)

使用道具 舉報(bào)

ID:28992 發(fā)表于 2021-3-20 04:36 | 顯示全部樓層
實(shí)在是感激不盡,謝謝啦!
回復(fù)

使用道具 舉報(bào)

ID:937856 發(fā)表于 2021-6-16 11:47 | 顯示全部樓層
真的很好,看了之后收獲很多!
回復(fù)

使用道具 舉報(bào)

ID:937856 發(fā)表于 2021-6-16 11:48 | 顯示全部樓層
太好了太好了,看了之后有好像知道該怎么做了
回復(fù)

使用道具 舉報(bào)

ID:995918 發(fā)表于 2021-12-22 22:54 | 顯示全部樓層
學(xué)習(xí)了大佬的程序,真的受益匪淺。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表