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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機實現的485通訊程序①

[復制鏈接]
跳轉到指定樓層
樓主
ID:71259 發表于 2014-12-30 00:52 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include<reg51.h>
  2. #include<string.h>

  3. #define  uchar unsigned char
  4. #define  uint   unsigned int
  5.      
  6. /* 通信命令 */
  7. #define __ACTIVE_  0x01    // 主機詢問從機是否存在
  8. #define __GETDATA_ 0x02    // 主機發送讀設備請求
  9. #define __OK_      0x03    // 從機應答
  10. #define __STATUS_  0x04    // 從機發送設備狀態信息

  11. /****************************幀格式****************************
  12.   目的地址-本機地址-命令字-數據-校驗碼-結束標志     至少5個字節
  13. *************************************************************/

  14. #define MAXSIZE 0x08    // 緩沖區長度
  15. #define ERRLEN 12       // 任何通信幀長度超過12則表示出錯
  16. uchar send_buf[MAXSIZE]={0xc0,0xdb};    // 該緩沖區用于保存設備狀態信息
  17. uchar rec_buf[ERRLEN];    // 保存接收到的幀

  18. uchar dev;    // 該字節用于保存本機設備號

  19. sbit M_DE = P1^0;    // 驅動器使能,1有效
  20. sbit M_RE = P1^1;    // 接收器使能,0有效

  21. void get_status();      // 調用該函數獲得設備狀態信息,函數代碼未給出
  22. void send_data(uchar type, uchar len, uchar *send_buf);    // 發送數據幀
  23. bit recv_cmd(uchar *type);    // 接收主機命令,主機請求僅包含命令信息
  24. void send_byte(uchar da);    // 該函數發送一幀數據中的一個字節,由send_data()函數調用




  25. void main()
  26. {
  27. uchar type;
  28. uchar len=2;

  29. /* 系統初始化 */

  30. dev =0xff;  //設備號

  31. TMOD = 0x20; // 定時器T1使用工作方式2
  32. TH1 = 0xfd;    // 設置初值
  33. TL1 = 0xfd;
  34. TR1 = 1;    // 開始計時
  35. PCON = 0x00;    // bps不倍增
  36. SCON = 0x50; // 工作方式1,波特率9600bps,允許接收
  37. ES = 1;    // 開串口中斷
  38. IT0 = 0;    // 外部中斷0使用電平觸發模式
  39. EX0 = 1;    // 開啟外部中斷0
  40. EA = 1;    // 開啟中斷

  41. /* 主程序流程 */
  42. while(1)    // 主循環
  43. {

  44.      if(recv_cmd(&type) == 0)    // 發生幀錯誤或幀地址與本機地址不符,丟棄當前幀后返回
  45.        continue;

  46.      SBUF = rec_buf[0];
  47.       while(!TI);
  48.        TI = 0;
  49.          SBUF = rec_buf[1];
  50.       while(!TI);
  51.        TI = 0;
  52.          SBUF = rec_buf[2];
  53.       while(!TI);
  54.        TI = 0;
  55.          SBUF = rec_buf[3];
  56.       while(!TI);
  57.        TI = 0;
  58.          SBUF = rec_buf[4];
  59.       while(!TI);
  60.        TI = 0;
  61.   /*
  62.     switch(type)
  63.     {
  64.      case __ACTIVE_:    // 主機詢問從機是否存在
  65.       send_data(__OK_, 0, send_buf);    // 發送應答信息,這里buf的內容并未用到
  66.       break;
  67.      case __GETDATA_:
  68.       len = strlen(send_buf);
  69.       send_data(__STATUS_, len, send_buf);    // 發送設備狀態信息
  70.       break;
  71.      default:
  72.       break;    // 命令類型錯誤,丟棄當前幀后返回
  73.     }  
  74.       */
  75. }
  76. }


  77. /* 該函數接收一幀數據并進行檢測,無論該幀是否錯誤,函數均會返回
  78. * 函數參數type保存接收到的命令字
  79. * 當接收到數據幀錯誤或其地址位不為0時(非主機發送幀),函數返回0,反之返回1
  80. */
  81. bit recv_cmd(uchar *type)
  82. {
  83. bit db = 0;    // 當接收到的上一個字節為0xdb時,該位置位
  84. bit c0 = 0;    // 當接收到的上一個字節為0xc0時,該位置位

  85. uchar tmp;
  86. uchar sum = 0;
  87. uchar i,j;

  88. M_DE = 0;    // 置發送禁止,接收允許
  89. M_RE = 0;

  90. /* 接收一幀數據 */
  91. i = 0;
  92. while(!c0)    // 循環直至幀接收完畢
  93. {
  94.     RI = 0;
  95.     while(!RI);
  96.     tmp = SBUF;
  97.     RI = 0;
  98.     if(db == 1)    // 接收到的上一個字節為0xdb
  99.     {
  100.         switch(tmp)
  101.         {
  102.         case 0xdd:
  103.          rec_buf[i] = 0xdb;    // 0xdbdd表示0xdb
  104.       
  105.          db = 0;
  106.          break;
  107.         case 0xdc:
  108.          rec_buf[i] = 0xc0;    // 0xdbdc表示0xc0
  109.      
  110.          db = 0;
  111.          break;
  112.         default :
  113.          return 0;    // 幀錯誤,返回
  114.         }
  115.       i++;
  116.     }
  117.    else{
  118.       switch(tmp)    // 正常情況
  119.       {
  120.        case 0xc0:    // 幀結束
  121.         c0 = 1;
  122.   
  123.         break;
  124.        case 0xdb:    // 檢測到轉義字符
  125.         db = 1;
  126.    
  127.         break;
  128.        default:    // 普通數據
  129.         rec_buf[i] = tmp;    // 保存數據
  130.         // 計算校驗字節
  131.         i++;
  132.       }
  133.      if(i == ERRLEN)    // 幀超長,錯誤,返回
  134.       return 0;
  135.    }
  136.   }
  137.   
  138. /* 判斷幀是否錯誤 */
  139. if(i<4)    // 幀過短,錯誤,返回
  140.     return 0;

  141. for(j=0;j<i-1;j++)
  142.   sum+=rec_buf[j];
  143. sum=sum%256;
  144. if(sum !=rec_buf[i-1] )    // 校驗錯誤,返回
  145.     return 0;

  146. if(rec_buf[0] != dev)    // 非訪問本機命令,錯誤,返回
  147.     return 0;

  148. *type = rec_buf[2];    // 獲得命令字

  149. return 1;    // 函數成功返回
  150. }


  151. // 該函數發送一幀數據幀,參數type為命令字、len為數據長度、buf為要發送的數據內容
  152. void send_data(uchar type, uchar len, uchar *send_buf)
  153. {
  154. uchar i;
  155. uchar sum = 0;    // 該字節用于保存校驗字節

  156. M_DE = 1;    // 置發送允許,接收禁止
  157. M_RE = 1;

  158. send_byte(0x00);    // 發送目的地址
  159. sum+=0x00;  //假設主機地址為0x00
  160. send_byte(dev);    // 發送本機地址
  161. sum+=dev;
  162. send_byte(type);    // 發送命令字
  163. sum+=type;
  164. //send_byte(len);    // 發送長度

  165. for(i=0; i<len; i++)    // 發送數據
  166. {
  167.     send_byte(*send_buf);
  168.     sum =sum+ (*send_buf);
  169.     send_buf++;
  170. }
  171. sum%=256;
  172. send_byte(sum);    // 發送校驗字節

  173. TI = 0;    // 發送幀結束標志
  174. SBUF = 0xc0;
  175. while(!TI);
  176. TI = 0;
  177. }

  178. //該函數發送一個數據字節,若該字節為0xdb,則發送0xdbdd,若該字節為0xc0則,發送0xdbdc
  179. void send_byte(uchar da)
  180. {
  181. switch(da)
  182. {
  183.     case 0xdb:    // 字節為0xdb,發送0xdbdd
  184.      TI = 0;
  185.      SBUF = 0xdb;
  186.      while(!TI);
  187.      TI = 0;
  188.      SBUF = 0xdd;
  189.      while(!TI)
  190.      TI = 0;
  191.      break;
  192.     case 0xc0:    // 字節為0xc0,發送0xdbdc
  193.      TI = 0;
  194.      SBUF = 0xdb;
  195.      while(!TI);
  196.      TI = 0;
  197.      SBUF = 0xdc;
  198.      while(!TI)
  199.      TI = 0;
  200.      break;
  201.     default:    // 普通數據則直接發送
  202.      TI = 0;
  203.      SBUF = da;
  204.      while(!TI);
  205.      TI = 0;
  206. }
  207. }
復制代碼


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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 97伦理 | 欧美日韩国产精品一区二区 | 亚洲福利一区二区 | 久久不射电影网 | 一本岛道一二三不卡区 | 极情综合网 | 久久大| 中文字幕亚洲精品在线观看 | 国产在线小视频 | 91精品国产日韩91久久久久久 | 欧美成人第一页 | 日本aaaa | 精品国产精品一区二区夜夜嗨 | 国产精品一二三区 | 欧美综合国产精品久久丁香 | 亚洲成av片人久久久 | 国产一区黄色 | 成人亚洲在线 | 国产性色视频 | 99这里只有精品视频 | 91久久久久久久 | 91av在线视频观看 | 亚洲一级淫片 | 欧美精品电影一区 | 午夜免费在线观看 | 亚洲精品欧美精品 | 国产精品不卡一区 | 国产黄色在线观看 | 亚洲网站在线播放 | 国产精品久久久久久久久久 | 国产精品视频不卡 | 国产免费一区二区 | 亚洲aⅴ精品 | 久久久免费电影 | 亚洲精品电影在线 | 亚洲视频在线观看一区二区三区 | 欧美 日韩 国产 成人 | 国产日韩免费观看 | 91视频免费 | 精品国产乱码久久久久久蜜柚 | 日本色高清 |