久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2886|回復: 3
打印 上一主題 下一主題
收起左側

51單片機CRC串行通信仿真與源碼

[復制鏈接]
跳轉到指定樓層
樓主
    我做的是兩個單片機之間進行串行通信,用的89c52.通過按主機p27口"啟動鍵",主機向從機發送一個四位數據,LED顯示。從機經過CRC校驗,如果接收到正確數據,與其相連的LED顯示所接收的數據。如果經校驗后接收錯誤,則四位LED顯示0xFFFF。
    仿真時從機一點反應也沒有,也許是我程序有問題,或通信協議編的不行。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載):


主機單片機源碼:
  1. #define        _PPDATAT_H

  2. #include <reg51.h>
  3. #include <string.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. /* 握手信號宏定義 */
  7. #define CALL 0x24                // 主機呼叫
  8. #define OK 0x00                        // 從機準備好

  9. #define MAXLEN 64                // 緩沖區最大長度

  10. uchar buf[MAXLEN];

  11. sbit  p00 = P0^0; sbit  p01 = P0^1; sbit  p02 = P0^2; sbit  p03 = P0^3;
  12. sbit p10=P1^0; sbit p11=P1^1; sbit p12=P1^2; sbit p13=P1^3;
  13. sbit p14=P1^4; sbit p15=P1^5; sbit p16=P1^6; sbit p17=P1^7;
  14. sbit p23 = P2^3;sbit p25 = P2^5;sbit p27 = P2^7;

  15. unsigned char a;
  16. unsigned char b;
  17. unsigned char c;
  18. unsigned char d;
  19. unsigned char in1,in2,in3,count;
  20. unsigned char j1,j2;
  21. unsigned char z1,z2,z3;
  22. unsigned int x=1234;
  23. bit qidong;

  24. void delay();

  25. //********************八段碼*************************//
  26. code unsigned char LEDMAP[] = {
  27. 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
  28. 0x7f, 0x6f, 0x00,0x71//共陽顯示碼,分別顯示0、1、2、3、4、5、6、7、8、9、滅、F。
  29. };
  30. //***********************顯示碼選擇**********************//
  31. int DisplayLED(unsigned char j)
  32. {
  33.         unsigned int i=0;
  34.         unsigned int x1;
  35.         x1= LEDMAP[(i+j) & 0x0f];
  36.         return  x1;
  37. }
  38. //***********************轉換*************************//
  39. void si()
  40. {
  41.     unsigned int M;
  42.         a=x%10;
  43.         M=x/10;
  44.         b=M%10;
  45.         M=M/10;
  46.         c=M%10;
  47.         d=M/10;//a取出第四位,b取出第三位,c取出第二位,d取出第一位
  48. }
  49. //***********************顯示**********************//
  50. void  display()
  51. {
  52.     si();
  53.         P0=0xf7;
  54.         P1=DisplayLED(a);
  55.         delay();
  56.         P0=0xfb;
  57.         P1=DisplayLED(b);
  58.         delay();
  59.         P0=0xfd;
  60.         P1=DisplayLED(c);
  61.         delay();
  62.         P0=0xfe;
  63.         P1=DisplayLED(d);
  64.         delay();       
  65. }
  66. //************************掃描按鍵**********************//
  67. void timer0() interrupt 1 using 1
  68. {
  69.         in1=p23;
  70.         in2=p25;
  71.         in3=p27;
  72.         TH0=0xc3;
  73.         TL0=0x50;
  74.         count++;

  75.         if(in1==0)
  76.                 z1++;
  77.         if(in2==0)
  78.                 z2++;
  79.         if(in3==0)
  80.                 z3++;
  81.         if(count==40)
  82.         {
  83. //*************************x+***********************//
  84.         if((0<z1)&(z1<40))
  85.                         x++;
  86.                 if (z1==40)
  87.                         j1++;
  88.                 count=0;
  89.                 z1=0;
  90.                 if((0<j1)&(j1<6))
  91.                         x++;
  92.                 if((5<j1)&(j1<11))
  93.                         x=x+10;
  94.                 if(10<j1)
  95.                         x=x+100;
  96.                 if(in1==1)
  97.                         j1=0;
  98. //************************x-*******************//
  99.                 if((0<z2)&(z2<40))
  100.                         x--;
  101.                 if (z2==40)
  102.                         j2++;
  103.                 z2=0;
  104.                 if((0<j2)&(j2<6))
  105.                         x--;
  106.                 if((5<j2)&(j2<11))
  107.                         x=x-10;
  108.                 if(10<j2)
  109.                         x=x-100;
  110.                 if(in1==1)
  111.                         j2=0;
  112. //************************啟動*******************//
  113.                 if(z3>5)
  114.                   qidong=1;
  115.          }  
  116. }
  117. void init()
  118. {
  119.      TMOD=0x21;                          //定時器0工作于方式1,定時器1工作于方式2
  120.         TH1 = 250;                          // 設置初值
  121.             TL1 = 250;

  122.             PCON = 0x80;                        // SMOD = 1
  123.             SCON = 0x50;                        //工作方式1,波特率9600bps,允許接收

  124.             ET0=1;                              //允許定時器0中斷
  125.             TR0=1;                              //定時器0開始工作
  126.             TR1 = 1;                            //定時器1開始工作
  127.             EA=1;                               //打開所有中斷

  128. }
  129. //*************************delay*********************//
  130. void delay()
  131. {
  132.         unsigned int i,n;
  133.         n=100;
  134.         for (i=0; i<n; i++) {}
  135. }
  136. //************************CRC計算****************************************//
  137. uint getcrc(uchar *s,uchar len)
  138. {
  139.   uint acc=0,i,j=0;
  140. while(len--)
  141. {
  142.     acc=acc^(*s++<<8);
  143.     for(i=0;i++<8;)
  144.       if(acc&0x8000)
  145.         acc=(acc<<1)^0x1021;
  146.       else
  147.         acc=acc<<1;
  148. }
  149. return(acc);
  150. }


  151. //************************串口通信程序****************************************//

  152. /* 發送數據函數 */
  153. void senddata(uchar *buf)
  154. {
  155.         uchar i;
  156.         uchar len;                                        // 保存數據長度
  157.         uint ecc;                                        // 保存校驗字節

  158.         len = strlen(buf);                        // 計算要發送數據的長度

  159.         /* 發送數據長度 */
  160.         TI = 0;
  161.         SBUF = len;                                        // 發送長度
  162.         while(!TI);
  163.         TI = 0;
  164.     /* 發送數據和校驗字節 */
  165.     ecc=getcrc(buf,len);
  166.     buf[len]=ecc/256;
  167.     buf[len+1]=ecc%256;
  168.         for (i=0;i<len+2;i++)
  169.         {
  170.                 SBUF = *buf;
  171.                 buf++;
  172.                 while(!TI);
  173.                 TI = 0;
  174.         }
  175. }       
  176. void tongxin()
  177. {
  178.         uchar i = 0;
  179.         uchar tmp;
  180.         /* 發送呼叫信號CALL并接收應答信息,如果沒有接收到從機準備好的信號,則重新發送呼叫幀 */
  181.         while(tmp!=OK)                       
  182.         {
  183.                 /* 發送呼叫信號CALL */
  184.                 TI = 0;
  185.                 SBUF = CALL;
  186.                 while(!TI);
  187.                 TI = 0;

  188.                 /* 接收從機應答 */
  189.                 RI = 0;
  190.                 while(!RI);
  191.                 tmp = SBUF;
  192.                 RI = 0;               
  193.         }

  194.        
  195. }


  196. //*************************主函數***********************//
  197. void  main()
  198. {
  199.            init();
  200.            while(1)
  201.            {
  202.              display();
  203.              if(qidong==1)
  204.               {
  205.                si();
  206.                buf[0]=a;buf[1]=b;            
  207.                buf[2]=c;buf[3]=d;
  208.                senddata(buf);
  209.                tongxin();
  210.                qidong=0;     
  211.               }
  212.            }  
  213. }  
復制代碼

叢機單片機源程序如下:
  1. #define        _PPDATAR_H

  2. #include <reg51.h>
  3. #include <string.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. /* 握手信號宏定義 */
  7. #define CALL 0x24                // 主機呼叫
  8. #define OK 0x00                        // 從機準備好
  9. #define MAXLEN 64            // 緩沖區最大長度
  10. uchar buf[MAXLEN];
  11. sbit  p00 = P0^0; sbit  p01 = P0^1; sbit  p02 = P0^2; sbit  p03 = P0^3;
  12. sbit p10=P1^0; sbit p11=P1^1; sbit p12=P1^2; sbit p13=P1^3;
  13. sbit p14=P1^4; sbit p15=P1^5; sbit p16=P1^6; sbit p17=P1^7;
  14. bit err;
  15. void delay();

  16. //********************八段碼*************************//
  17. code unsigned char LEDMAP[] = {
  18. 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
  19. 0x7f, 0x6f, 0x00,0x71//共陽顯示碼,分別顯示0、1、2、3、4、5、6、7、8、9、滅、F。
  20. };
  21. //***********************顯示碼選擇**********************//
  22. int DisplayLED(unsigned char j)
  23. {
  24.         unsigned int i=0;
  25.         unsigned int x1;
  26.         x1= LEDMAP[(i+j) & 0x0f];
  27.         return  x1;
  28. }

  29. //***********************顯示**********************//
  30. void  display()
  31. {
  32.         P0=0xf7;
  33.         P1=DisplayLED(buf[0]);
  34.         delay();
  35.         P0=0xfb;
  36.         P1=DisplayLED(buf[1]);
  37.         delay();
  38.         P0=0xfd;
  39.         P1=DisplayLED(buf[2]);
  40.         delay();
  41.         P0=0xfe;
  42.         P1=DisplayLED(buf[3]);
  43.         delay();
  44. }
  45. //////////////////////顯示FFFF//////////////////////////////
  46. void  display_f()
  47. {
  48.         P0=0xfe;
  49.         P1=DisplayLED(11);
  50.         delay();
  51.         P0=0xfd;
  52.         P1=DisplayLED(11);
  53.         delay();
  54.         P0=0xfb;
  55.         P1=DisplayLED(11);
  56.         delay();
  57.         P0=0xf7;
  58.         P1=DisplayLED(11);
  59.         delay();
  60. }
  61. //************************CRC計算****************************************//
  62. uint getcrc(uchar *s,uchar len)
  63. {
  64.   uint acc=0,i,j=0;
  65. while(len--)
  66. {
  67.     acc=acc^(*s++<<8);
  68.     for(i=0;i++<8;)
  69.       if(acc&0x8000)
  70.         acc=(acc<<1)^0x1021;
  71.       else
  72.         acc=acc<<1;
  73. }
  74. return(acc);
  75. }
  76. //*************************delay*********************//
  77. void delay()
  78. {
  79.         unsigned int i,n;
  80.         n=100;
  81.         for (i=0; i<n; i++) {}
  82. }
  83. //************************進行數據校驗****************************************//
  84. int chkcrc(uchar *buf,uchar len)
  85.         {
  86.           uint strcrc;
  87.            strcrc=getcrc(buf,len);   //生成接收數據的CRC碼
  88.            if(((0xff&buf[len])==(0xff&(strcrc/256)))&&((0xff&buf[len+1])==(0xff&(strcrc%256))))
  89.                                    //接收的CRC碼和生成的CRC碼進行比較
  90.              return(0);
  91.            else
  92.              return(-1);
  93.         }

  94. /* 接收數據函數 */
  95. bit recvdata(uchar *buf)
  96. {
  97.         uchar i;
  98.         uchar len;                                        // 保存數據長度
  99.         int ecc;                                        // 保存校驗字節
  100.        
  101.         /* 接收數據長度字節 */
  102.         RI = 0;
  103.         while(!RI);
  104.         len = SBUF;
  105.         RI = 0;

  106.         /* 接收數據及校驗字節 */
  107.         for (i=0;i<len+2;i++)
  108.         {
  109.                 while(!RI);
  110.                 *buf = SBUF;       
  111.                 RI = 0;       
  112.                 buf++;               
  113.         }
  114.         *buf = 0;                                        // 表示接收結束       
  115.       
  116.          /* 進行數據校驗 */
  117.         ecc = chkcrc(buf,len);
  118.         if (ecc!=0)                                        // 如果校驗錯誤
  119.        
  120.                       return 1;                        // 返回1表示校驗錯誤
  121.         else
  122.                return 0;                                        // 校驗成功,返回0
  123.       
  124. }

  125. void init_serial()
  126. {
  127.         TMOD = 0x20;                                // 定時器T1使用工作方式2
  128.         TH1 = 250;
  129.         TL1 = 250;
  130.         TR1 = 1;                                        // 開始計時
  131.         PCON = 0x80;                                // SMOD = 1
  132.         SCON = 0x50;                                // 工作方式1,波特率9600kbit/s,允許接收
  133. }

  134. /*串口通信程序 */
  135. void tongxin()
  136. {
  137.         uchar tmp=0;
  138.         init_serial();
  139.         EA = 0;                                        // 關閉所有中斷

  140.        /* 如果接收到的數據不是CALL,則繼續等待 */
  141.                 while (tmp!=CALL)
  142.                 {
  143.                         RI = 0;
  144.                         while(!RI)
  145.                         tmp = SBUF;
  146.                         RI = 0;
  147.                 }
  148.        
  149.                 /* 發送OK信號,表示從機可以接收數據 */
  150.                 TI = 0;                               
  151.                 SBUF = OK;
  152.                 while(!TI);
  153. ……………………

  154. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
CRC串行通信.zip (86.14 KB, 下載次數: 41)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:344633 發表于 2018-7-18 16:40 來自手機 | 只看該作者
謝謝樓主      
回復

使用道具 舉報

板凳
ID:381488 發表于 2018-8-10 11:52 | 只看該作者
我想看看的
回復

使用道具 舉報

地板
ID:381488 發表于 2018-8-10 11:54 | 只看該作者
為什么不讓下栽
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩精品一区二区三区在线播放 | 密室大逃脱第六季大神版在线观看 | 中文字幕精品一区久久久久 | 中文字幕亚洲一区二区三区 | 欧美久久久久 | 一区二区三区四区视频 | 久久久久国产成人精品亚洲午夜 | 亚洲成人免费视频在线观看 | 国产欧美综合在线 | 精品欧美在线观看 | 日本精品久久 | 亚洲在线视频 | 在线中文字幕亚洲 | 欧美成年人视频在线观看 | 九九在线视频 | 国产成人精品免费视频大全最热 | 婷婷桃色网 | 人人九九精 | 国产做a爱免费视频 | 精品久久久久久亚洲综合网 | 黑人精品 | 免费在线观看一区二区 | 久久久久午夜 | 久久久久91 | 国产精品自拍视频网站 | 不卡在线视频 | 久久中文免费视频 | 黄色免费观看网站 | 一本岛道一二三不卡区 | 日本人爽p大片免费看 | 成人精品一区亚洲午夜久久久 | 别c我啊嗯国产av一毛片 | 午夜一区二区三区在线观看 | 蜜臀久久99精品久久久久久宅男 | 狠狠操狠狠干 | 日日夜夜天天久久 | 涩涩视频在线观看 | 精品国产乱码久久久久久果冻传媒 | 中文字幕91| 97视频在线观看网站 | 91视频一区二区三区 |