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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

組態王單片機ASCII協議編程源碼與仿真(含注解)

[復制鏈接]
跳轉到指定樓層
樓主
組態王51單片機ASCII協議編程
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #define uchar unsigned char
  2. #define uint unsigned int
  3. #define tim0 -50000
  4. #define BPS57600 -1          //11.0592
  5. #define BPS28800 -2          //11.0592
  6. #define BPS19200 -3          //11.0592
  7. #define BPS9600 -6          //11.0592
  8. #define BPS4800 -12          //11.0592
  9. //////////////////////////////////////////////////////////////
  10. //支持字節和字類型,由于他的浮點怪異所以不支持
  11. idata uchar DatB[4];   //組態字節
  12. idata uint  DatW[4];   //組態整數
  13. idata float DatF[4];   //組態浮點
  14. uchar Addr;

  15. bit RECV=0;
  16. idata uchar Rbuf[40],Rptr,Rnum;
  17. idata uchar Tbuf[40],Tptr,Tnum;
  18. code uchar asc[]="0123456789ABCDEF";

  19. uchar AscHex(uchar m)
  20. {
  21.   if(m>='0' && m<='9') return m-'0';
  22.   else if(m>='A' && m<='F') return m-'A'+10;
  23.   else if(m>='a' && m<='f') return m-'a'+10;
  24.   return 0;
  25. }

  26. uchar AscByte(uchar p) //ASC變BYTE
  27. {
  28.   uchar x1,x2;
  29.   x1=AscHex(Rbuf[p]);
  30.   x2=AscHex(Rbuf[p+1]);
  31.   return x2+x1*16;
  32. }

  33. void ByteAsc(uchar p)  //BUYE變ASC
  34. {
  35.   Tbuf[Tnum++]=asc[p>>4];
  36.   Tbuf[Tnum++]=asc[p&15];
  37. }

  38. bit ChkLRC() //接收數據包效驗
  39. {
  40.   uchar i,d,s=0;
  41.   for(i=0;i<Rnum-2;i++) s^=Rbuf[i];
  42.   d=AscByte(Rnum-2);
  43.   return s==d;
  44. }

  45. void SetLRC() //發送數據包效驗并發送
  46. {
  47.   uchar i,s=0;
  48.   for(i=0;i<Tnum;i++) s^=Tbuf[i];
  49.   ByteAsc(s);
  50.   Tbuf[Tnum++]=0x0d;  //添加包結束符
  51.   SBUF=0x40;          //發送包起始并啟動串口發送
  52. }

  53. void serial() interrupt 4 using 2  //串口數據收發
  54. {
  55.   uchar m;
  56.   if(RI)   //接收部分
  57.   {
  58.     RI=0; m=SBUF;
  59.         if(m==0x40)      //幀開始
  60.         {
  61.           Rptr=0; Rnum=0;
  62.         }
  63.         else if(m==0x0D) //幀結束
  64.         {
  65.           RECV=1;
  66.         }
  67.         else if(Rnum<40) //包長限制
  68.         {
  69.           Rbuf[Rptr++]=m;
  70.           Rnum++;
  71.         }
  72.   }
  73.   if(TI)   //發送部分
  74.   {
  75.     TI=0;
  76.     if(Tnum>0)
  77.         {
  78.           SBUF=Tbuf[Tptr++];
  79.           Tnum--;
  80.         }
  81.   }
  82. }

  83. //////////////////////////////////////////////////////

  84. void KingASC()       //通信協議的處理程序
  85. {
  86.   uint p,x0,x1,x2;
  87.   uchar n,cmd,i;
  88.   uchar *s;
  89.   cmd=AscByte(2)&0xf;
  90.   p=AscByte(4)*256+AscByte(6);  
  91.   n=AscByte(8);
  92.   if((cmd&1)==0)     //組態王從單片機讀數據
  93.   {
  94.     Tnum=0; Tptr=0;
  95.         ByteAsc(Addr);
  96.         ByteAsc(n);
  97.     switch(cmd&0x0c)
  98.         {
  99.           case 0x00:   //字節變量處理
  100.             s=(uchar*)DatB+p;
  101.         for(i=0;i<n;i++)
  102.                   ByteAsc(s[i]);
  103.                 break;
  104.           case 0x04:   //字變量處理
  105.             s=(uchar*)DatW+2*p;
  106.         for(i=0;i<n/2;i++)
  107.                 {
  108.                   ByteAsc(s[2*i]);
  109.                   ByteAsc(s[2*i+1]);
  110.                 }
  111.                 break;
  112.           case 0x08: //浮點變量處理
  113.           case 0x0c: //浮點變量處理
  114.             s=(uchar*)DatF+4*p;
  115.         for(i=0;i<n/4;i++)
  116.                 {
  117.           x1=s[4*i]&0x80;
  118.           x2=s[4*i]<<1;
  119.           x2+=(s[4*i+1])>>7;
  120.                     ByteAsc(x1+x2-126);
  121.                   ByteAsc((s[4*i+1])|0x80);
  122.                   ByteAsc(s[4*i+2]);
  123.                   ByteAsc(s[4*i+3]);
  124.                 }
  125.                 break;
  126.         }
  127.         SetLRC();
  128.   }
  129.   else              //組態王向單片機寫數據
  130.   {
  131.     switch(cmd&0x0c)
  132.         {
  133.           case 0x00: ////字節變量處理
  134.             s=(uchar*)DatB+p;
  135.         for(i=0;i<n;i++)
  136.                   s[i]=AscByte(10+2*i);
  137.                 break;
  138.           case 0x04: //字變量處理
  139.             s=(uchar*)DatW+2*p;
  140.             for(i=0;i<n/2;i++)
  141.                 {
  142.                   s[2*i]=AscByte(10+4*i);
  143.                   s[2*i+1]=AscByte(12+4*i);
  144.                 }
  145.                 break;
  146.           case 0x08: //浮點變量處理
  147.           case 0x0c: //浮點變量處理
  148.             s=(uchar*)DatF+4*p;
  149.             for(i=0;i<n/4;i++)
  150.                 {
  151.                   x0=AscByte(10+8*i);
  152.                   x1=x0&0x80;
  153.                   x2=x0&0x7f;
  154.           x2=x2+126;
  155.           x0=x1|(x2>>1);
  156.           s[4*i]=x0;
  157.                   x0=AscByte(12+8*i)&0x7f;
  158.           if(x2&1) x0=x0|0x80;
  159.                   s[4*i+1]=x0;
  160.                   s[4*i+2]=AscByte(14+8*i);
  161.                   s[4*i+3]=AscByte(16+8*i);
  162.                 }
  163.                 break;
  164.         }
  165.     Tnum=0; Tptr=0;
  166.         ByteAsc(Addr);
  167.     Tbuf[Tnum++]='#';
  168.     Tbuf[Tnum++]='#';
  169.         SetLRC();
  170.   }
  171.   Rnum=0; Rptr=0;
  172. }

  173. void timer0() interrupt 1  //定時對串口收到的數據包進行處理
  174. {
  175.   TH0=tim0>>8; TL0=tim0;
  176.   if(RECV)
  177.   {
  178.     RECV=0;
  179.     if(ChkLRC()) //先進行數據效驗
  180.     {
  181.       if(AscByte(0)==Addr) KingASC();  //地址是本機則進行協議的處理
  182.     }
  183.   }
  184. }

  185. void Init() //對定時器及串口進行初始化
  186. {
  187.   EA=1; ES=1; ET0=1;
  188.   TMOD=0X21; IP=0x10;
  189.   SCON=0X50; PCON=0X80;     
  190.   TH1=BPS19200; TR1=1;   //串口波特率的設置
  191.   TH0=tim0>>8; TL0=tim0; TR0=1;
  192. }



  193. 主函數:
  194. #include <reg52.h>
  195. #include <glzxj.h>  //對協議的引用

  196. ///////////////////////////////////////////////////////
  197. main()
  198. {
  199.   Init(); //資源的初始化
  200.   DatB[0]=0xff; DatB[1]=0xff;
  201.   DatW[0]=123;  DatW[1]=234;
  202.   DatW[2]=345;  DatW[3]=456;
  203.   DatF[0]=-1.123;  DatF[1]=-1.145;
  204.   DatF[2]=10.123;  DatF[3]=100.145;
  205.   Addr=1; //單片機地址設置
  206.   while(1)
  207. ……………………

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

所有資料51hei提供下載:
組態王單片機ASCII協議編程.rar (25.66 KB, 下載次數: 102)


評分

參與人數 1黑幣 +30 收起 理由
2bsheep + 30 贊一個!

查看全部評分

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

使用道具 舉報

沙發
ID:380052 發表于 2018-8-29 23:22 | 只看該作者
非常感謝樓主的分享
回復

使用道具 舉報

板凳
ID:343192 發表于 2019-7-6 14:40 | 只看該作者
組態王的那部分怎么做,想知道組態王怎么和Proteus連接起來
回復

使用道具 舉報

地板
ID:728133 發表于 2020-4-13 13:03 | 只看該作者
是我需要的
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲国产网址 | 成人h视频 | h片在线观看免费 | 成人精品久久 | 精品久久久久一区 | 欧美激情一区二区三区 | 成人在线激情 | 伊人看片 | 毛片免费看 | 亚洲国产一区二区视频 | 成人av免费 | 懂色av蜜桃av | 久久色视频 | 日日操日日舔 | 日韩精品在线网站 | 久久久久久久久一区 | 久久久久国产一区二区三区四区 | 日本三级电影在线观看视频 | 日本公妇乱淫xxxⅹ 国产在线不卡 | 亚洲精品视频一区 | 国产一区二区在线播放视频 | 天天躁日日躁狠狠躁2018小说 | www成人免费视频 | 欧美一区不卡 | 精品一区二区三区在线视频 | 自拍视频国产 | 精品91久久| 2019天天干天天操 | 亚洲欧洲色视频 | 久久综合国产 | 成人网av | 欧美精品一区二区在线观看 | 日韩精品免费视频 | 久久九九99| 国产精品入口麻豆www | 羞羞在线视频 | 老外几下就让我高潮了 | 欧美日韩一二三区 | 国产视频一区二区 | 欧美在线a | .国产精品成人自产拍在线观看6 |