標(biāo)題: ESP8266用STC單片機發(fā)送AT命令來連接網(wǎng)絡(luò)的程序 [打印本頁]

作者: 51黑dd    時間: 2016-4-5 14:46
標(biāo)題: ESP8266用STC單片機發(fā)送AT命令來連接網(wǎng)絡(luò)的程序

全部源碼下載:
ESP8266用單片機發(fā)送AT命令來連接網(wǎng)絡(luò)的程序.zip (215.17 KB, 下載次數(shù): 628)


主程序:
  1. /*

  2.   本程序用51單片機經(jīng)過AT指令控制模塊,完成從SMARTLINK 到 手機與模塊的綁定,以及云品臺的登錄,本地數(shù)據(jù)發(fā)給異地手機,手機異地控制測試板上的繼電器動作。
  3.   本程序可以移植到STM8這款只要1元錢的單片機上配合AT模塊,完成高性價的產(chǎn)品,比如開關(guān)插座。主要演示安信可的云平臺的試用!以及整個物聯(lián)網(wǎng)的流程

  4.   注意:變量初始化成0,否者隨機  數(shù)組注意溢出問題  0X55 在其他數(shù)據(jù)中有可能出現(xiàn),并造成混亂,主要是計數(shù)  過濾數(shù)據(jù),根據(jù)網(wǎng)絡(luò)環(huán)境不同,返回有可能變化,注意通用性
  5.   內(nèi)部 ID KEY 輸出格式已經(jīng)固定為8個字節(jié)模式          本程序用的AT固件版本是1.01 ,內(nèi)置合法芯片ID 和授權(quán)KEY ,并且這條記錄已經(jīng)在安信可云服務(wù)器內(nèi)存在
  6.   安信可的云有多簡單?
  7.   1 登錄:    55 26 00 A0 00 60 96 96 60 02 DD 1E 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1E DD 26 AC 55
  8.   2 發(fā)送數(shù)據(jù):55 28 00 AA EE EA 8F 8F EA 02 DD 1E 00 00 00 00 00 00 08 4A 42 85 A9 94 85 0C 00 54 02 45 4D 50 3A 32 35 35 3B 00 42 5C 55
  9.   只要構(gòu)造出上面的數(shù)據(jù)包,經(jīng)過UDP 發(fā)送到安信可云服務(wù)器,就能通訊了
  10.    
  11.   時間倉促,完成功能后,未經(jīng)過優(yōu)化代碼優(yōu)化,和語法風(fēng)格修改,供參考。輔助文檔有這個程序設(shè)計框架解釋,和詳細(xì)的指導(dǎo),這些文件均可以在安信可官網(wǎng)
  12.   WWW.AI-THINKER.COM  ai-cloud 云平臺板塊得到最新的資訊

  13.       本測試程序在安信可科技50元 的大測試板上正確運行,所有安信可出的的模塊從ESP-01到ESP-14均可以正確運行,與遠(yuǎn)程控制。

  14. */


  15. /*************        本地常量聲明        **************/
  16. #define MAIN_Fosc                22118400L        //定義主時鐘
  17. #define        RX1_Lenth                32                        //串口接收緩沖長度
  18. #define        BaudRate1                115200UL        //選擇波特率
  19. #define        Timer1_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 1 重裝值, 對應(yīng)300KHZ
  20. #define        Timer2_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 2 重裝值, 對應(yīng)300KHZ
  21. #include        "STC15Fxxxx.H"
  22. /*************        本地變量聲明        **************/
  23. u8        idata RX1_Buffer[RX1_Lenth];        //接收緩沖
  24. u8        TX1_Cnt;        //發(fā)送計數(shù)
  25. u8        RX1_Cnt;        //接收計數(shù)
  26. bit        B_TX1_Busy;        //發(fā)送忙標(biāo)志
  27. /*************        端口引腳定義        **************/
  28. unsigned char two_lab=0;
  29. sbit LED1=P1^0;//LED1
  30. sbit LED2=P1^1;//LED2
  31. sbit LED3=P3^7;//LED3
  32. sbit DK1=P3^3;//繼電器
  33. sbit BEEP=P3^4;//蜂鳴器
  34. sbit K1=P1^3;//按鍵1
  35. sbit K2=P1^2;//按鍵2
  36. sbit K3=P1^4;//按鍵3
  37. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  38. /////這是安信可云平臺數(shù)據(jù)包的全部組成結(jié)構(gòu),細(xì)節(jié)可參照安信可的云平臺V1.0版本規(guī)格書,包結(jié)構(gòu)章節(jié)
  39. #define O_PF    0X00  //包頭1字節(jié)固定0X55
  40. #define O_LEN_L 0X01  //整個包長低字節(jié)
  41. #define O_LEN_H 0X02  //整個包長高字節(jié) 注意轉(zhuǎn)義碼 兩個這里只計算一個數(shù)據(jù)處理!
  42. #define O_CMD_T 0X03  //命令類型
  43. #define O_CMD_C 0X04  //具體命令
  44. #define O_CIX_L 0X05  //本命令序列編號低字節(jié)
  45. #define O_CIX_H 0X06  //本命令序列編號高字節(jié)
  46. #define O_EXMSH 0X07  //擴展信息高字節(jié)
  47. #define O_EXMSL 0X08  //擴展信息低字節(jié)
  48. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請求 未知
  49. #define O_DEVID_START 0x0A  //8字節(jié)設(shè)備識別  低字節(jié)在前
  50. #define O_DEVID 0x0A  //8字節(jié)設(shè)備識別
  51. #define O_TK_LEN      0X12 //1 BYTS TL_LEN          //獲得的設(shè)備臨時通訊令牌長度
  52. #define O_TOKE_START  0X13
  53. #define O_DATAS_START 0X1B
  54. //N BYTS DATAS          //客戶的數(shù)據(jù)包串
  55. //CRC_L    1BYTE          //CRC16 低字節(jié)
  56. //CRC_H    1BYTE          //CRC16 高字節(jié)
  57. //PACK_END 1BYTE          //包尾1字節(jié)固定0X55

  58. ////////////////////////////////////////////////////////////////////////以上定義了包中的各參數(shù)的絕對位置//////////////////////////////////
  59. #define uart_rec_tcp_udp_data 0        //系統(tǒng)進(jìn)入正常網(wǎng)絡(luò)數(shù)據(jù)收發(fā)狀態(tài)
  60. #define uart_rec_csysid       1        //系統(tǒng)獲取ESP8266WIFI模塊的許可號狀態(tài),獲取四個字節(jié)的芯片ID 和 4個字節(jié)的授權(quán)碼
  61. #define uart_rec_smartlink    2        //系統(tǒng)進(jìn)入獲取上網(wǎng)賬號密碼狀態(tài)
  62. #define uart_rec_bander       3        //系統(tǒng)進(jìn)入將本W(wǎng)IFI設(shè)備 和APP 手機綁定控制狀態(tài)
  63. //////////////////////////////////////////////////////////////////////以上部分定義了系統(tǒng)的幾種狀態(tài)///////////////////////////////////////
  64. bit have_tok=0;
  65. bit have_data=0;
  66. unsigned char rec_len=0;
  67. bit                   a_vec=0;                   //設(shè)置一個標(biāo)志位,串口程序 出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  68. unsigned char          ceng=0;         //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  69. unsigned char str_len_limt=16;         //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  70. unsigned char   str_len_num=11;        //字符個數(shù)
  71. char str_ref=':';
  72. /////////////////////////////////////////////////////////////////////上面幾個變量用來作為在串口中過濾指定字符串的 限定參數(shù),改變過濾內(nèi)容后必定先初始化這幾個/////
  73. code char CYSYS_code[]="+CSYSID:CHIP";
  74. code char PIPD_code[]="+IPD,";
  75. code char bander_code[]="+IPD,4,26:RPL:";//這里過濾有漏洞
  76. code char smartlink_code[]="SMART SUCCESS";
  77. /////////////////////////////////////////////////////////////////////以上是從WIFI模塊串口輸出到本單片機串口輸入后,本單片機要過濾的各種頭部////////////////////
  78. unsigned char uart_rec_sta=uart_rec_csysid;// 串口目前所處于的狀態(tài),比如進(jìn)入正常數(shù)據(jù)接收,或者SMARTLINK 或者 獲取模塊的ID。
  79. code unsigned char AT_RST[]="AT+RST";                                                     
  80. code unsigned char AT_MODE[]="AT+CWMODE=1";
  81. code unsigned char AT_CWJAP[]="AT+CWJAP=\"360we\",\"zty0012001\"";
  82. code unsigned char AT_CIP3[]="AT+CIPSTART=3,\"UDP\",\"cloud.ai-thinker.com\",5001,2468,0" ;
  83. code unsigned char temp_bander[]="RPT:\"0xa1b23467\",\"0xaf321234\",\"192.168.0.123\",\"light\",\"123456a\"";
  84. code unsigned char AT_CIPMUX[]="AT+CIPMUX=1";
  85. code unsigned char CIPSTART[]="AT+CIPSTART=4,\"UDP\",\"cloud.ai-thinker.com\",5001,2468,0";
  86. code unsigned char AT_CSYSID[]="AT+CSYSID";
  87. code unsigned char AT_SMARTLINK[]="AT+CWSMARTSTART=1";
  88. code unsigned char ZERO[]="00000000000000000000000000000000001";
  89. code unsigned char CIPSEND_LEN[]="AT+CIPSEND=4,";
  90. code unsigned char CIP3SEND_LEN[]="AT+CIPSEND=3,63";
  91. /////////////////////////////////////////////////////////////////////以上字串是單片機發(fā)給串口模塊的AT語句有的是直接給WIFI模塊的指令,有些是用來拷貝字符串用/////////////

  92. xdata unsigned char at_send_len_ox[20];               
  93. idata unsigned char send_buf[64]="jisifsfhello:99999;oop";                             //發(fā)送緩沖區(qū)
  94. unsigned char recd_buf[64]= {0x55 ,0x25 ,0x00 ,0xAA ,0xFF ,0x00, 0x00, 0x00, 0x00 ,0x02 ,0x31, 0x0A ,0xFE ,0x00, 0x00, 0x00, 0x00 ,0x00, 0x08, 0x00 ,0x7C ,0xC8, 0x52 ,0xFE, 0x3D ,0x64 ,0x29, 0x4C ,0x49, 0x47, 0x48 ,0x54 ,0x02, 0x3A ,0x3F, 0x6C, 0x02, 0x55};                                                 //接收緩沖區(qū)
  95. data unsigned char temp_buf[72];                                 //加工緩沖區(qū)
  96. idata unsigned char toke[8]={0x24,0x41,0xD6,0x39,0x48,0x83,0xAC,0x00};//此設(shè)備在服務(wù)器上獲得的令牌包
  97. unsigned char esp_dev_id[8]={0,0,0,0,0,0,0X1E,0XDE};         //    8266的8個字節(jié)的器件ID號,可在服務(wù)器數(shù)據(jù)庫中查到,唯一標(biāo)示一個器件,登錄過程需要一個器件ID,和數(shù)據(jù)區(qū)放一個數(shù)據(jù)密碼,這么簡單登錄
  98. unsigned char esp_TOK_id[8]={0,0,0,0,0,0,0,0};                                 //    服務(wù)器分給器件器件的令牌包,另外個地方也定義了,完全可以用一個數(shù)組完成的
  99. unsigned char esp_user_data[14]={0,0,0,0,0,0,0X1E,0XDE};         //    客戶的凈數(shù)據(jù)負(fù)荷區(qū),可以很大,因為本款單片機有限,并且一般控制信號,定義幾個字節(jié)夠了!注意在登錄的時候,這里是器件密碼!
  100. unsigned char temp_cd[]="TEMP:123;";                                                 //    一個數(shù)據(jù)包,前面是包格式定義,后面是客戶數(shù)據(jù)區(qū),這里定義一個即將要發(fā)送的溫度數(shù)據(jù)
  101. unsigned char need_seed_len=0;                                                                 //    全局變量,本次總共需要發(fā)到串口的數(shù)據(jù)
  102. bit t_o=0;                                                                                                         //  在構(gòu)造一個如00123 的數(shù)據(jù)時候,去掉前面的00變成123 這里若碰到0就置1
  103. code unsigned char cip3_lcport[]="2469,0";
  104. data unsigned char chip_id[8]={'0','0','0','0','0','0','0','0'};
  105. data unsigned char flash_id[8]={'0','0','0','0','0','0','0','0'};
  106. pdata unsigned char pass_id[8]={'0','0','0','0','0','0','0','0'};

  107. unsigned int time=0; //每隔30秒把一個變量加1,然后把這個變量作為溫度數(shù)據(jù)上報給云平臺,轉(zhuǎn)給手機端

  108. xdata unsigned char ssid[32];          //暫存SSID賬戶信息
  109. xdata unsigned char password[20]; //暫存客戶密碼
  110. idata char ssid_len=0;                  //記錄SSID 長度
  111. idata char pasd_len=0;                          //記錄密碼長度

  112. bit have_id=0;                                          //記錄是否用AT指令獲取到了這個模塊的ID 和KEY信息
  113. bit have_smartlink=0;                          //記錄是否過濾到 從串口來的TCP UDP 數(shù)據(jù)  smartlink
  114. bit have_bander=0;                                  //記錄是從串口中輸出的網(wǎng)絡(luò)數(shù)據(jù)中過濾到 手機用UDP發(fā)來的請求信息

  115. unsigned char stac_a=0;                      //全局專用變量
  116. unsigned char stac_b=0;                          //全局專用變量
  117.                                                                   //
  118. #include "intrins.h"

  119. typedef unsigned char BYTE;
  120. typedef unsigned int WORD;

  121. void IapIdle();
  122. BYTE IapReadBYTE(WORD addr);
  123. #define EEPROM_SSID_LC     0                  //定義SSID 存在FLASH上的相對位置
  124. #define EEPROM_PASSWORD_LC 64                //定義密碼 存在FLASH上的相對位置
  125. #define EEPROM_LAB         128                //定義是否已將路由器賬戶和密碼保存到FLASH中



  126. #define CMD_IDLE      0
  127. #define CMD_READ      1
  128. #define CMD_PROGRAM   2
  129. #define CMD_ERASE     3

  130. #define ENABLE_IAP  0X81
  131. #define IAP_ADDRESS 0X1200        //設(shè)置客戶參數(shù)保存的位置,這里選擇FLASH的最后一個扇區(qū)。


  132. /////////////////////////////////////////////////////////////////下面部分定義了CRC16校驗函數(shù)用到的表格///////////////////////////////////
  133. code unsigned int crc_table[256]=
  134. {               /* CRC余式表 */
  135. 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
  136. 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
  137. 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
  138. 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
  139. 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
  140. 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
  141. 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
  142. 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
  143. 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
  144. 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
  145. 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
  146. 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
  147. 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
  148. 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
  149. 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
  150. 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
  151. 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
  152. 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
  153. 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
  154. 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
  155. 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
  156. 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
  157. 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
  158. 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
  159. 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
  160. 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
  161. 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
  162. 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
  163. 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
  164. 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
  165. 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
  166. 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
  167. };
  168.    /////////////////////////////////////////////////////////////////上面部分定義了CRC16校驗函數(shù)用到的表格///////////////////////////////////


  169. /////////////////////////////////////////////////////////////////////以下部分是STC的掉電存儲程序,讀寫內(nèi)部的EEPROM 保存上網(wǎng)賬戶和密碼////////////////////////
  170. void Delay(BYTE n);
  171. void IapIdle();
  172. BYTE IapReadByte(WORD addr);
  173. void IapProgramByte(WORD addr,BYTE dat);
  174. void IapEraseSector(WORD addr);


  175. void IapIdle()
  176. {
  177.   IAP_CONTR=0;
  178.   IAP_CMD=0;
  179.   IAP_TRIG=0;
  180.   IAP_ADDRH=0X80;
  181.   IAP_ADDRL=0;
  182. }

  183. BYTE IapReadByte(WORD addr)
  184. {
  185.    BYTE dat;
  186.    IAP_CONTR=ENABLE_IAP;
  187.    IAP_CMD=CMD_READ;
  188.    IAP_ADDRL=addr;
  189.    IAP_ADDRH=addr>>8;
  190.    IAP_TRIG=0x5a;
  191.    IAP_TRIG=0xa5;
  192.    _nop_();
  193.    dat=IAP_DATA;
  194.    IapIdle();
  195.    return dat;
  196. }

  197. void IapProgramByte(WORD addr,BYTE dat)
  198. {
  199.   IAP_CONTR=ENABLE_IAP;
  200.   IAP_CMD=CMD_PROGRAM;
  201.   IAP_ADDRL=addr;
  202.   IAP_ADDRH=addr>>8;
  203.   IAP_DATA=dat;
  204.   IAP_TRIG=0x5a;
  205.   IAP_TRIG=0xa5;
  206.   _nop_();
  207.   IapIdle();
  208. }

  209. void IapEraseSector(WORD addr)
  210. {
  211.   IAP_CONTR=ENABLE_IAP;
  212.   IAP_CMD=CMD_ERASE;
  213.   IAP_ADDRL=addr;
  214.   IAP_ADDRH=addr>>8;
  215.   IAP_TRIG=0x5a;
  216.   IAP_TRIG=0xa5;
  217.   _nop_();
  218.   IapIdle();
  219. }
  220. /////////////////////////////////////////////////////////////////////以上部分是STC的掉電存儲程序,讀寫內(nèi)部的EEPROM 保存上網(wǎng)賬戶和密碼////////////////////////


  221. void make_AT_CIP3(void)
  222. //根據(jù)上邊 在2468 端口監(jiān)聽到的 廣播內(nèi)容 用廣播內(nèi)容的IP 地址192.168.1.10和端口 48008新建一個3連接,
  223. //AT+CIPSTART=3,"UDP","192.168.1.10",48008,2469,0
  224. ///新建一個連接3
  225. {
  226.   unsigned char a,b;
  227.   for(a=0,b=0;a<21;a++,b++)
  228.   temp_buf[b]=AT_CIP3[b];
  229.   for(a=0;recd_buf[a]!=',';a++,b++)
  230.   temp_buf[b]=recd_buf[a];
  231.   temp_buf[b]=',';
  232.   b++;
  233.   a+=2;
  234.   for(;recd_buf[a]!='"';a++,b++)
  235.   temp_buf[b]=recd_buf[a];
  236.   temp_buf[b]=',';
  237.   b++;
  238.   for(a=0;cip3_lcport[a]!=0;a++,b++)
  239.   temp_buf[b]=cip3_lcport[a];
  240.   temp_buf[b]=0;
  241. }
  242. //將16進(jìn)制數(shù),變成16進(jìn)制字符比如10變成A
  243. char back_char(unsigned char user_d)
  244. {
  245.   if(user_d<10)
  246.   return (user_d+'0');
  247.   else
  248.   return (user_d-10+'A');
  249. }
  250. ////制作 向手機發(fā)送如下格式UDP數(shù)據(jù)
  251. ////RPT:"0x00FE6738","0xB8B3C281","192.168.0.123","light","123456a"
  252. void make_bander_data()
  253. {
  254.   unsigned char a,b=0;
  255.   for(a=0;temp_bander[a]!=0;a++)
  256.   temp_buf[a]=temp_bander[a];
  257.   temp_buf[a]=0;

  258.   //以上硬拷貝 code unsigned char temp_bander[]="RPT:\"0xa1b23467\",\"0xaf321234\",\"192.168.0.123\",\"light\",\"123456a\"";到 temp_buf
  259.   //以下語句修改RPT:"0x00FE6738","0xB8B3C281","192.168.0.123","light","123456a" 中將本身的設(shè)備ID(如0x00FE6738) 和 KEY(0xB8B3C281)放到上面修改后的temp_buf
  260.   //后面的 "light","123456a"  為本設(shè)備名字,和本設(shè)備的密碼,暫時未用 可隨便填寫

  261.   temp_buf[7]=back_char(esp_dev_id[4]>>4);
  262.   temp_buf[8]=back_char(esp_dev_id[4]&0x0f);
  263.   temp_buf[9]=back_char(esp_dev_id[5]>>4);
  264.   temp_buf[10]=back_char(esp_dev_id[5]&0x0f);
  265.   temp_buf[11]=back_char(esp_dev_id[6]>>4);
  266.   temp_buf[12]=back_char(esp_dev_id[6]&0x0f);
  267.   temp_buf[13]=back_char(esp_dev_id[7]>>4);
  268.   temp_buf[14]=back_char(esp_dev_id[7]&0x0f);

  269.   temp_buf[20]=back_char(esp_user_data[7]>>4);
  270.   temp_buf[21]=back_char(esp_user_data[7]&0x0f);
  271.   temp_buf[22]=back_char(esp_user_data[6]>>4);
  272.   temp_buf[23]=back_char(esp_user_data[6]&0x0f);
  273.   temp_buf[24]=back_char(esp_user_data[5]>>4);
  274.   temp_buf[25]=back_char(esp_user_data[5]&0x0f);
  275.   temp_buf[26]=back_char(esp_user_data[4]>>4);
  276.   temp_buf[27]=back_char(esp_user_data[4]&0x0f);
  277. }

  278. void make_AT_SEND(unsigned char a_len)   //生成右邊這樣的指令,將參數(shù)a_len 改成10進(jìn)制,右邊這條指令  "AT+CIPSEND=XX" XX是發(fā)送的數(shù)量
  279. {
  280.   unsigned char aa=0;
  281.   for(aa=0;aa<13;aa++)
  282.   {
  283.     at_send_len_ox[aa]=CIPSEND_LEN[aa];         //剪貼"AT+CIPSEND= 到RAM  后面的十進(jìn)制參數(shù)由下面的部分生成
  284.   }
  285.   t_o=0;                                 //去掉前面的0,比如發(fā)送38個字節(jié),038,前面的0就可以去掉了。
  286.   if((a_len/100))
  287.   {
  288.   at_send_len_ox[aa]=a_len/100+'0';
  289.   aa++;
  290.   t_o=1;
  291.   }
  292.   if((a_len%100)/10)
  293.   {
  294.   at_send_len_ox[aa]=(a_len%100)/10+'0';
  295.   aa++;
  296.   t_o=1;
  297.   }
  298.   else if(t_o)
  299.   {
  300.     at_send_len_ox[aa]=0+'0';
  301.         aa++;
  302.   }
  303.   at_send_len_ox[aa]=(a_len%10)+'0';
  304.   aa++;
  305.   at_send_len_ox[aa]=0;
  306. }
  307. //下面函數(shù)獲得CRC校驗碼 采用標(biāo)準(zhǔn)CRC16 初始CRC=0XFFFF  運算多項式參數(shù) 8005 非1021
  308. unsigned int GetRevCrc_16(unsigned char * pData, int nLength)
  309. {
  310.   unsigned int cRc_16 = 0xffff;
  311.   unsigned char temp;
  312.   while(nLength-- > 0)
  313.   {
  314.     temp = cRc_16&0xff;
  315.     cRc_16 = (cRc_16 >> 8) ^ crc_table[(temp ^ *pData++) & 0xFF];
  316.   }
  317.   return cRc_16;   
  318. }
  319. //下面這個函數(shù)構(gòu)造一個發(fā)送的數(shù)據(jù)格式,請看數(shù)據(jù)格式文檔,完全可以用結(jié)構(gòu)體完成,這里采用數(shù)據(jù),從上到下描述這個數(shù)據(jù)包
  320. //發(fā)送的數(shù)據(jù)包,目前只有登錄數(shù)據(jù)包,和上報溫度數(shù)據(jù)包,這兩個基本的數(shù)據(jù)包,上報數(shù)據(jù)包可以充當(dāng)心跳包,第一個參數(shù)決定著,是發(fā)送登錄包還是溫度包
  321. //其他幾個入口參數(shù)是器件ID,令牌包,以及客戶的數(shù)據(jù),以及客戶數(shù)據(jù)長度

  322. void make_send_pack(unsigned char ms_opt,unsigned char *dev_id,unsigned char *toke_id,unsigned char *use_data,unsigned char use_data_len)
  323. {
  324.   unsigned char a,b,i=0;
  325.   unsigned esp_crc=0;
  326.   send_buf[0]=0x55;                                                     //包頭是0X55固定
  327.   
  328.   send_buf[O_LEN_L]=(O_DATAS_START+use_data_len+3)%0xff; //本數(shù)據(jù)包的所有數(shù)據(jù)長度,包頭至包尾,記得是沒有經(jīng)過轉(zhuǎn)義前的包長
  329.   send_buf[O_LEN_H]=(O_DATAS_START+use_data_len+3)/0xff;

  330.   if(ms_opt==0)                                                                                         //根據(jù)入口參數(shù)判斷是發(fā)送登錄鏈路操作,還是發(fā)送數(shù)據(jù)包云平臺
  331.   send_buf[O_CMD_T]=0XA0;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實時檢測指令 0XF0 終端操作
  332.   else if (ms_opt==1)
  333.   send_buf[O_CMD_T]=0XAA;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實時檢測指令 0XF0 終端操作

  334.   if(ms_opt==0)                                                                //0X00代表登錄操作
  335.   send_buf[O_CMD_C]=0X00;// reg  option
  336.   else if (ms_opt==1)
  337.   send_buf[O_CMD_C]=0XEE;                                                    //0XEE代表數(shù)據(jù)是從設(shè)備到云平臺的方向

  338.   send_buf[O_CIX_L]=0XF3;// CMD INDEXL                        //命令序列編號,暫時不用,可以作為對方應(yīng)答的數(shù)據(jù)包號標(biāo)示
  339.   send_buf[O_CIX_H]=0XC0;//        CMD INDEXL                                        //命令序列編號,暫時不用,可以作為對方應(yīng)答的數(shù)據(jù)包號標(biāo)示
  340.   send_buf[O_EXMSH]=0XC0;//        EXTERN MESSAGE1                                //擴展子暫時保留
  341.   send_buf[O_EXMSL]=0XF3;//        EXTERN MESSAGE2                                //擴展子暫時保留

  342.   send_buf[O_RESTA]=0X02;//        CMD_STA 00 OK 01 FAIL 02 SEND 03 NO SUP         //代表本數(shù)據(jù)包的狀態(tài),是發(fā)送還是應(yīng)答成功還是失敗

  343.   for(i=0;i<8;i++)
  344.   send_buf[O_DEVID+i]=*(dev_id+(7-i)); // 拷貝設(shè)備的唯一ID號到數(shù)據(jù)包里


  345.   send_buf[O_TK_LEN] =8;                   //代表接下來的令牌包是8個字節(jié)


  346.   for(i=0;i<8;i++)
  347.   send_buf[O_TOKE_START+i]=*(toke_id+i);//8個字節(jié)令牌包,初始令牌包為00 后續(xù)服務(wù)器會分配一個令牌包給這個設(shè)備,設(shè)備每次通訊要攜帶這個令牌包


  348.   for(i=0;i<use_data_len;i++)
  349.   send_buf[O_DATAS_START+i]=*(use_data+i); // 客戶的數(shù)據(jù)區(qū),登錄的時候放數(shù)據(jù)密碼文本
  350.   
  351.   temp_buf[0]=0x55;                                                   //包尾

  352.   esp_crc=GetRevCrc_16(send_buf,O_DATAS_START+use_data_len);//得到轉(zhuǎn)義之前的總數(shù)據(jù)包CRC,具體可以參照CRC數(shù)據(jù)格式,因此CRC是針對轉(zhuǎn)義之前的數(shù)據(jù)生成

  353.   for(a=1,b=1;a<(O_DATAS_START+use_data_len);a++)           //將出去包頭,所有的數(shù)據(jù)中含有有0X55的數(shù)據(jù)轉(zhuǎn)義成0X54,0X01,將0X54 變成0X54,02,重新轉(zhuǎn)義數(shù)據(jù)包
  354.   {
  355.     if(send_buf[a]==0x55)
  356.         {
  357.           temp_buf[b]=0x54;
  358.           b+=1;
  359.           temp_buf[b]=0x01;
  360.           b+=1;
  361.         }
  362.         else if(send_buf[a]==0x54)
  363.         {
  364.           temp_buf[b]=0x54;
  365.           b+=1;
  366.           temp_buf[b]=0x02;
  367.           b+=1;
  368.         }
  369.         else
  370.         {
  371.         temp_buf[b]=send_buf[a];
  372.         b+=1;
  373.         }
  374. }         ///////////////////////////////////////////////////////////以上的語句轉(zhuǎn)義數(shù)據(jù)包中除包頭到CRC之前的全部的數(shù)據(jù)///////////////////////////////////////////////////////////////////////
  375. //55 28 00 AA EE F3 C0 C0 F3 02 E6 1E 00 00 00 00 00 00 08 24 41 D6 39 48 83 AC 00 54 02 45 4D 50 3A 32 35 35 3B 00 D1 52 55
  376. //55 28 00 AA EE F3 C0 C0 F3 02 E6 1E 00 00 00 00 00 00 08 24 41 D6 39 48 83 AC 00 54 02 45 4D 50 3A 32 35 35 3B 00 D1 52 55

  377. temp_buf[b]=(esp_crc>>8);
  378. b+=1;
  379. temp_buf[b]=(esp_crc&0x00ff);         
  380. b+=1;
  381.     ///////////////////////////////////////////////////////////上面兩句加上CRC校驗////////////////////////////////////////
  382. temp_buf[b]=0x55;        //包尾
  383. b+=1;
  384. temp_buf[b]=0x0d;
  385. b+=1;
  386. temp_buf[b]=0x0a;
  387. b+=1;                                //以上構(gòu)成回車
  388. need_seed_len=b;        //至此構(gòu)造出了需要發(fā)送的全部數(shù)據(jù) 包括AT指令需要的換行
  389. temp_buf[b]=0x00;
  390. }



  391. void Delay1(unsigned long ms)//簡單延遲函數(shù),單位是毫秒
  392. {
  393.         unsigned char i, j,k;
  394.         for(k=0;k<ms;k++)
  395.         {
  396.                 _nop_();
  397.                 _nop_();
  398.                 i = 22;
  399.                 j = 128;
  400.                 do
  401.                 {
  402.                         while (--j);
  403.                 } while (--i);
  404.         }
  405. }


  406. void Delay2(unsigned long cnt)
  407. {
  408.         long i;
  409.         for(i=0;i<cnt*100;i++);
  410. }

  411. void at_uart_send_str(unsigned char *str)//發(fā)送AT字符串到串口
  412. {
  413.   unsigned char *st_p=str;
  414.   do{
  415.      SBUF=*st_p;
  416.          st_p++;
  417.          Delay1(1);
  418.         }while(*st_p);
  419.         SBUF='\r';
  420.         Delay1(1);
  421.         SBUF='\n';
  422.         Delay1(1);
  423. }
  424. void at_uart_send_buf(unsigned char *str,unsigned char len)//發(fā)送數(shù)據(jù)緩沖區(qū)的非字符串信息,數(shù)據(jù)流信息到串口
  425. {
  426.   unsigned char *st_p=str;
  427.   
  428.   while(len){
  429.      SBUF=*st_p;
  430.          st_p++;
  431.          Delay1(1);
  432.          len--;
  433.         }while(*st_p);
  434.         Delay1(1);
  435. }


  436. void change_pack()                                          //把接收到的數(shù)據(jù)包轉(zhuǎn)義過來,0X55 轉(zhuǎn)義成0X54 0X01 0X54 替換成0X54 02
  437. {
  438.                                      for(stac_a=1,stac_b=1;recd_buf[stac_a]!=0x55;)
  439.                                    {
  440.                                      if((recd_buf[stac_a]==0x54)&&(recd_buf[stac_a+1]==0x01))
  441.                                          {
  442.                                          temp_buf[stac_b]=0x55;
  443.                                          stac_b++;
  444.                                          stac_a+=2;
  445.                                          }
  446.                                          else if((recd_buf[stac_a]==0x54)&&(recd_buf[stac_a+1]==0x02))
  447.                                          {
  448.                                          temp_buf[stac_b]=0x54;
  449.                                          stac_b++;
  450.                                          stac_a+=2;
  451.                                          }
  452.                                          else
  453.                                          {
  454.                                            temp_buf[stac_b]=recd_buf[stac_a];
  455.                                            stac_b++;
  456.                                            stac_a++;
  457.                                          }
  458.                                   }
  459.                                   temp_buf[stac_b]=0x55;
  460.                                   temp_buf[0]=0x55;
  461.                                   recd_buf[0]=temp_buf[0];
  462.                                   for(stac_a=1;temp_buf[stac_a]!=0x55;stac_a++)
  463.                                   recd_buf[stac_a]=temp_buf[stac_a];
  464.                                   recd_buf[stac_a]=0x55;
  465.                                   recd_buf[0]=0x55;
  466. }
  467. void init_uart(void)
  468. {
  469.           B_TX1_Busy = 0;
  470.         RX1_Cnt = 0;
  471.         TX1_Cnt = 0;
  472.         S1_8bit();                                //8位數(shù)據(jù)
  473.         S1_USE_P30P31();                //UART1 使用P30 P31口        默認(rèn)
  474.         AUXR &= ~(1<<4);        //Timer stop                波特率使用Timer2產(chǎn)生
  475.         AUXR |= 0x01;                //S1 BRT Use Timer2;
  476.         AUXR |=  (1<<2);        //Timer2 set as 1T mode
  477.         TH2 = (u8)(Timer2_Reload >> 8);
  478.         TL2 = (u8)Timer2_Reload;
  479.         AUXR |=  (1<<4);        //Timer run enable
  480.         REN = 1;        //允許接收
  481.         ES  = 1;        //允許中斷
  482.         EA = 1;                //允許全局中斷
  483.         P3M1 = 0x00;
  484.     P3M0 = 0xFF;
  485.         RX1_Cnt=0;
  486.         DK1=0;
  487.         BEEP=0;
  488. }
  489. bit have_config=0;
  490. void main(void)
  491. {
  492.         char tt,i,k,n,z=0;
  493.         unsigned int h=0;
  494.         //////////////////////////////////////////////////////////////////////////////////////下面部分為定時器以及串口初始化/////////////////////
  495.         init_uart();
  496.         Delay2(1000);
  497.         if(K1==0)           //開機的時候發(fā)現(xiàn)按鍵1也就是MCU_P1.3 被按下,那么清除單片機中EEPROM存的數(shù)據(jù)
  498.         {
  499.                 IapEraseSector(IAP_ADDRESS);  //擦除客戶EEPROM扇區(qū) 512字節(jié)
  500.                         LED2=0;
  501.                         BEEP=1;
  502.                         Delay2(200);
  503.                     LED2=1;
  504.                         BEEP=0;      //閃亮心跳指示燈,和心跳音
  505.         }
  506.         Delay2(300);
  507.         if(IapReadByte(IAP_ADDRESS+EEPROM_LAB)==0x55) //開機后檢測是否已經(jīng)保存了客戶的信息在EEPROM中
  508.         have_config=0;
  509.         else
  510.         have_config=1; //EEPROM沒有記錄客戶的路由器賬戶和密碼,需要配置
  511.         ///////////////////////////////////////////////////////////////////////////////////以上部分主要完成串口的初始化////////////////////////////
  512.         for(;;)
  513.         {         
  514.         a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  515.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  516.         str_len_limt=22;          //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  517.         str_len_num=13;           //要過濾連續(xù)字符個數(shù)
  518.         str_ref=':';                          // 過濾到字符串后,接著要出現(xiàn)的字符,這個字符出現(xiàn)的位置才是絕對0位置
  519.                 uart_rec_sta=uart_rec_smartlink; //設(shè)置在串口中的過濾分支條件,串口中斷中,根據(jù)這個標(biāo)志調(diào)用不同的字符串過濾參數(shù)

  520.                 at_uart_send_str(AT_MODE);                 //設(shè)置模塊進(jìn)入STATION 模式
  521.                 Delay2(1000);
  522.                 if(have_config)                                         //需要配置 模塊連入本地的路由器賬戶和密碼
  523.                 {
  524.                 at_uart_send_str(AT_SMARTLINK);         //發(fā)送進(jìn)入SMARTLINK AT指令
  525.                 Delay2(2000);
  526.                 }
  527.                 else
  528.                 have_smartlink=1;                                 //否則設(shè)置已經(jīng)進(jìn)入過SMARTLINK 狀態(tài)

  529.                 do                                                                 //此循環(huán)完成SMARTLINK 的配置
  530.                 {
  531.                 LED1=0;
  532.                 LED2=0;
  533.                 LED3=0;
  534.                 Delay2(200);
  535.                 LED1=1;
  536.                 LED2=1;
  537.                 LED3=1;
  538.                 Delay2(200);
  539.                 if(have_smartlink)//假如從串口中獲得正確的 SMARTLINK 用戶路由器賬戶和密碼
  540.                 {
  541.                    if(have_config)//需要客戶重新設(shè)置路由器賬戶和密碼
  542.                    {
  543.                          for(i=0;recd_buf[i]!=0x0d;i++)
  544.                          {
  545.                                 ssid_len++;
  546.                                 ssid[i]=recd_buf[i];                                  //拷貝串口緩沖區(qū)中的用戶路由器名字
  547.                                 IapProgramByte(IAP_ADDRESS+EEPROM_SSID_LC+i+1,recd_buf[i]);    //存儲客戶賬戶到EEPROM中
  548.                          }
  549.                          IapProgramByte(IAP_ADDRESS+EEPROM_SSID_LC,ssid_len);                           //存儲客戶的賬戶長度到EEPROM中
  550.                          for(i=0;recd_buf[ssid_len+11+i]!='\r';i++)
  551.                          {
  552.                                 password[i]=recd_buf[ssid_len+11+i];                               //拷貝串口緩沖區(qū)中的用戶路由器密碼
  553.                                 IapProgramByte(IAP_ADDRESS+EEPROM_PASSWORD_LC+i+1,password[i]);//存儲客戶密碼到EEPROM中
  554.                                 pasd_len++;                                                                                                          
  555.                          }

  556.                          IapProgramByte(IAP_ADDRESS+EEPROM_PASSWORD_LC,pasd_len);          //存儲客戶的密碼長度到EEPROM中
  557.                          IapProgramByte(IAP_ADDRESS+EEPROM_LAB,0x55);
  558.                    }
  559.                    else        //無需用SMARTLINK 方式獲取路由器賬戶和秘密,賬戶和密碼直接從單片機的EEPROM直接讀取
  560.                    {
  561.                     ssid_len=IapReadByte(IAP_ADDRESS+EEPROM_SSID_LC);         //從EEPROM中的賬戶長度
  562.                         pasd_len=IapReadByte(IAP_ADDRESS+EEPROM_PASSWORD_LC);//從EEPROM中的密碼長度
  563.                     for(i=0;i<ssid_len;i++)
  564.                         {
  565.                         ssid[i]=IapReadByte(IAP_ADDRESS+EEPROM_SSID_LC+i+1); //從EEPROM中讀取賬戶信息到RAM中
  566.                         }
  567.                         for(i=0;i<pasd_len;i++)
  568.                         {
  569.                         password[i]=IapReadByte(IAP_ADDRESS+EEPROM_PASSWORD_LC+i+1); //從EEPROM中讀取密碼信息到RAM中
  570.                         }
  571.                    }
  572.                 //code unsigned char AT_CWJAP[]="AT+CWJAP=\"360we\",\"zty0012001\"";
  573.                         n=0;
  574.                         for(i=0;i<63;i++)
  575.                     temp_buf[i]=0;                //清空臨時緩沖區(qū)

  576.                         for(i=0;i<10;i++,n++)
  577.                         temp_buf[n]=AT_CWJAP[i];      //拷貝AT指令加入路由器的格式頭AT+CWJAP="

  578.                         for(i=0;i<ssid_len;i++,n++)          //用SMARTLINK 獲得的 SSID 和PASSWORLD 填充 加入路由器所需要的兩個參數(shù)        AT+CWJAP="360we","zty0012001"
  579.                         temp_buf[n]=ssid[i];
  580.                         temp_buf[n]='"';
  581.                         n++;
  582.                         temp_buf[n]=',';
  583.                         n++;
  584.                         temp_buf[n]='"';
  585.                         n++;
  586.                         for(i=0;i<pasd_len;i++,n++)
  587.                         temp_buf[n]=password[i];
  588.                         temp_buf[n]='"';                         //以上語句構(gòu)造出:AT+CWJAP="360we","zty0012001" 這樣的指令,其中路由器賬戶和密碼 隨客戶變動
  589.                 }
  590.             }while(have_smartlink==0); //此循環(huán)完成SMARTLINK 的配置

  591.                 LED1=1;
  592.                 LED2=1;
  593.                 LED3=1;
  594.             //////////////////////////////////////////////////////////下面的語句獲得模塊的設(shè)備ID/////////////////////////////////////////////////////////////
  595.         a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  596.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  597.         str_len_limt=16;          //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  598.         str_len_num=12;           //要過濾的字符個數(shù) +CSYSID:CHIP: 為下一個字符留個位置: 因此是12個字符
  599.         str_ref=':';                          // 要過濾到的字符
  600.                 uart_rec_sta=uart_rec_csysid;
  601.                 at_uart_send_str(AT_CSYSID); //返回如下:+CSYSID:CHIP:00FE6738;FLASH:001640EF;KEY:81C2B3B8;
  602.                 Delay2(2000);                                 //延時兩秒后,串口中必定輸出 所需要的器件ID FLASH ID 和KEY
  603.                 if(have_id)                                         //從串口中獲取了芯片的ID 信息 和KEY 以及FLASH 信息
  604.                 {
  605.                 have_id=0;
  606.                 k=0;
  607.                 for(i=0,tt=0;i<8;i++,tt++)        //  獲取模塊內(nèi)部的芯片ID                          
  608.                 chip_id[tt]=recd_buf[i];
  609.                 for(i=15,tt=0;i<23;i++,tt++)//  獲取模塊內(nèi)部的FLASH ID
  610.                 flash_id[tt]=recd_buf[i];
  611.                 for(i=28,tt=0;i<36;i++,tt++)//  獲取模塊內(nèi)部的KEY
  612.                 pass_id[tt]=recd_buf[i];
  613.         //下面的語句將獲取的16進(jìn)制字符換成 16進(jìn)制數(shù)據(jù),8個字節(jié)的字符最總得到四個字節(jié)的16進(jìn)制數(shù)據(jù) 比如字符串"A2345678"最終變成0XA2,0X34,0X56,0X78 四個字節(jié)存放
  614.             for(i=0;i<8;i++)            
  615.             {
  616.                           if((chip_id[i]>='A')&&(chip_id[i]<='F'))
  617.                           chip_id[i]=(chip_id[i]-'A'+10);
  618.                           else if((chip_id[i]>='a')&&(chip_id[i]<='f'))
  619.               chip_id[i]=(chip_id[i]-'a'+10);
  620.                           else
  621.                           chip_id[i]-='0';
  622.             }
  623.                                
  624.                 for(i=0;i<8;i++)
  625.             esp_dev_id[i]=0;

  626.                 esp_dev_id[7]=((chip_id[6])<<4)+chip_id[7];// 將字符串16進(jìn)制轉(zhuǎn)換后,變成16進(jìn)制數(shù)據(jù)四個字節(jié)存放到對應(yīng)內(nèi)存中
  627.                 esp_dev_id[6]=((chip_id[4])<<4)+chip_id[5];
  628.                 esp_dev_id[5]=((chip_id[2])<<4)+chip_id[3];
  629.                 esp_dev_id[4]=((chip_id[0])<<4)+chip_id[1];
  630.                 //將獲取的16進(jìn)制字符換成 16進(jìn)制數(shù)據(jù),8個字節(jié)的字符最總得到四個字節(jié)的16進(jìn)制數(shù)據(jù) 比如字符串"A2345678"最終變成0XA2,0X34,0X56,0X78 四個字節(jié)存放
  631.             for(i=0;i<8;i++)
  632.             {
  633.                           if((pass_id[i]>='A')&&(pass_id[i]<='F'))
  634.                           pass_id[i]=(pass_id[i]-'A'+10);
  635.                           else if((pass_id[i]>='a')&&(pass_id[i]<='f'))
  636.               pass_id[i]=(pass_id[i]-'a'+10);
  637.                           else
  638.                           pass_id[i]-='0';
  639.             }
  640.                 for(i=0;i<8;i++)
  641.                 flash_id[i]=0;

  642.                 flash_id[7]=((pass_id[6])<<4)+pass_id[7];// 將字符串16進(jìn)制轉(zhuǎn)換后,變成16進(jìn)制數(shù)據(jù)四個字節(jié)存放到對應(yīng)內(nèi)存中
  643.                 flash_id[6]=((pass_id[4])<<4)+pass_id[5];
  644.                 flash_id[5]=((pass_id[2])<<4)+pass_id[3];
  645.                 flash_id[4]=((pass_id[0])<<4)+pass_id[1];

  646.                 for(i=0;i<8;i++)
  647.             esp_user_data[i]=flash_id[i];

  648.                 // 以上操作將模塊輸出的內(nèi)部字符串形式的芯片ID 和KEY (都是4個字節(jié)的)換成16進(jìn)制 存放到內(nèi)存中,在登錄服務(wù)器的時候的兩個必要參數(shù)。
  649.                 //////////////////////////////////////////////////////////上面的語句獲得模塊的設(shè)備ID和KEY/////////////////////////////////////////////////////////////
  650.                 }
  651.                 //while(1);
  652.                 //////////////////////////////////////////////////////////下面的語句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////

  653.                 a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  654.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  655.         str_len_limt=16;          //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  656.         str_len_num=7;            //字符個數(shù)
  657.         str_ref='"';
  658.                 uart_rec_sta=uart_rec_bander;

  659.                 Delay2(2000);
  660.         at_uart_send_str(AT_MODE);
  661.                 Delay2(2000);
  662.         at_uart_send_str(temp_buf); //temp_buf 中此時存放的是  AT+CWJAP="360we","zty0012001"        這樣的AT指令,這一步加入路由器中
  663.                 Delay2(10000);
  664.                 at_uart_send_str(AT_CIPMUX);//進(jìn)入多連接模式,單連接其實也可以的
  665.                 Delay2(2000);
  666.         at_uart_send_str(CIPSTART);        //用UDP方式連接到安信可的云,連接到目標(biāo)5001安信可云服務(wù),順便監(jiān)聽 2468 端口,code unsigned char CIPSTART[]="AT+CIPSTART=4,\"UDP\",\"cloud.ai-thinker.com\",5001,2468,0"
  667.                 Delay2(2000);
  668.                
  669.                 if(have_config)                           //客戶需要重新配置,這個時候也順便把模塊和手機的綁定關(guān)系建立:原理是模塊把芯片ID和KEY經(jīng)過UDP發(fā)給手機,手機把這個合法ID上報給服務(wù)器,從而綁定!
  670.                 {                                                   //過程是手機在和模塊同一個局域網(wǎng)后,手機發(fā)送UDP到2468端口,而上一步,模塊在監(jiān)聽2468端口!手機發(fā)送的UDP包內(nèi)容是RPL:"192.168.1.10","48008"
  671.                 do                                                   //其實手機是把自己現(xiàn)在的IP地址192.168.1.10 和即將監(jiān)聽的端口48008 告訴模塊,然后模塊就可以把自己的芯片ID 和KEY授權(quán) 各四個字節(jié) 回送給手機
  672.                 {                                                   //因此任何一個手機只要獲得這個模塊的芯片ID 和KEY ,即可向服務(wù)器利用這個信息,進(jìn)行控制權(quán)申請,也就是綁定!
  673.                 LED1=0;
  674.                 LED2=0;
  675.                 LED3=0;
  676.                 Delay2(200);
  677.                 LED1=1;
  678.                 LED2=1;
  679.                 LED3=1;
  680.                 Delay2(200);
  681.                
  682.                 if(have_bander)
  683.                 {
  684.                   ;
  685.                 }

  686.                 }while(have_bander==0);        //監(jiān)聽局域網(wǎng)內(nèi)手機向2468端口(2468端口和連接4綁定) 發(fā)出的UDP掃描信息,獲得RPL:"192.168.1.10","48008"  手機透露自己的IP和端口
  687.                  
  688.                  make_AT_CIP3();                                    //根據(jù)上邊 在2468 端口監(jiān)聽到手機透露的IP地址和端口 構(gòu)造一條建立連接指令如右邊示意:AT+CIPSTART=3,"UDP","192.168.1.10",48008,2469,0
  689.                  at_uart_send_str(temp_buf);         //發(fā)送出上面構(gòu)造的連接到AT指令,模塊得以執(zhí)行上面構(gòu)造的AT指令
  690.                  Delay2(2000);
  691.                  make_bander_data();                     //從綁定手機和設(shè)備關(guān)系的處理中,構(gòu)造出如右邊的UDP數(shù)據(jù):RPT:"0x00FE6738","0xB8B3C281","192.168.0.123","light","123456a"
  692.                  at_uart_send_str(CIP3SEND_LEN); //發(fā)送AT指令,告訴模塊即將經(jīng)過路由器發(fā)給手機的數(shù)據(jù)長度,  code unsigned char CIP3SEND_LEN[]="AT+CIPSEND=3,63";
  693.                  Delay2(1000);
  694.                  at_uart_send_str(temp_buf);         //發(fā)送構(gòu)造好的UDP數(shù)據(jù)!
  695.                  Delay2(2000);
  696.                  }                                                                 //根據(jù)上面的幾個步驟,手機獲取到了模塊的芯片ID 和 KEY ID,手機得到后會利用這個信息讓服務(wù)器綁定它們兩個

  697.                 //////////////////////////////////////////////////////////上面面的語句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////
  698.                 at_uart_send_str(AT_MODE);
  699.                 a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  700.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  701.         str_len_limt=12;          //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  702.         str_len_num=5;            //字符個數(shù)
  703.         str_ref=':';
  704.                 uart_rec_sta=uart_rec_tcp_udp_data;

  705.                 make_send_pack(0,esp_dev_id,esp_TOK_id,esp_user_data,8);//構(gòu)造登錄數(shù)據(jù)包
  706.                 make_AT_SEND(need_seed_len);                            //將要進(jìn)過WIFI發(fā)送的總字節(jié)數(shù)變成10進(jìn)制,動態(tài)生成發(fā)送數(shù)據(jù)AT指令
  707.                 two_lab=0;                                                                                                ////////////////////////////////////////////////////////////////////兩個55計數(shù)。∮锌赡苠e亂
  708.         at_uart_send_str(at_send_len_ox);                       //將構(gòu)造好的AT發(fā)送數(shù)據(jù)到互聯(lián)網(wǎng)的動態(tài)發(fā)送數(shù)據(jù)長度
  709.                 Delay2(2000);
  710.                 at_uart_send_buf(temp_buf,need_seed_len);                                //經(jīng)過WIFI模塊發(fā)送構(gòu)造好的登錄包
  711.                 Delay2(4000);

  712.                 //while(1);

  713.                 while(1)
  714.                 {                                                                                                         //主循環(huán)體中,每30秒構(gòu)造一個上傳數(shù)據(jù),上傳數(shù)據(jù)每次加1.
  715.                         for(tt=0;tt<60;tt++)
  716.                         {
  717.                         Delay2(200);
  718.                         Delay2(200);
  719.                     }
  720.                     make_send_pack(1,esp_dev_id,toke,temp_cd,10);    //構(gòu)造上傳數(shù)據(jù)到云,轉(zhuǎn)給手機的溫度數(shù)據(jù)包,符合基本數(shù)據(jù)格式
  721.                     make_AT_SEND(need_seed_len);                                          //動態(tài)構(gòu)造發(fā)送AT指令
  722.                         at_uart_send_str(at_send_len_ox);                //發(fā)送構(gòu)造好的發(fā)送指令
  723.                     Delay2(2000);
  724.                     at_uart_send_buf(temp_buf,need_seed_len);             //經(jīng)過WIFI發(fā)送數(shù)據(jù)

  725.                         LED2=0;
  726.                         BEEP=1;
  727.                         Delay2(200);
  728.                     LED2=1;
  729.                         BEEP=0;                                         //閃亮心跳指示燈,和心跳音
  730.                                                                                                                         //每30秒會運行到這里一次。更新一次溫度數(shù)值
  731.                         time++;
  732.                         temp_cd[5]=(((time%1000)/100)+'0');
  733.                         temp_cd[6]=(((time%100)/10)+'0');
  734.                     temp_cd[7]=(((time%10))+'0');
  735.                 }
  736.         }
  737.         Delay2(2000);
  738. }

  739. /********************* 字符串過濾函數(shù)初始參數(shù)************************/
  740. /*
  741. bit a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  742. unsigned char ceng=0;         //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  743. unsigned char str_len_limt=12;//設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  744. unsigned char str_len_num=5;  //字符個數(shù)
  745. char str_ref=':';
  746. code char test_code[]="+IPD,";
  747. */

  748. void fit_stb(unsigned char *str_p) // 每次串口接收到一個字符都會進(jìn)入本過濾函數(shù),看是否過濾到指定的字符串。
  749. {
  750.    if((a_vec==0)&&(ceng<str_len_limt))
  751.    {
  752.       if(ceng<str_len_num)
  753.           {
  754.       if(SBUF==(*(str_p+ceng)))
  755.           ceng++;
  756.           else
  757.           ceng=0;
  758.           }
  759.           else
  760.           {
  761.                 ceng++;
  762.                 if(SBUF==str_ref)
  763.                 {
  764.                   a_vec=1;
  765.                   ceng=0;       
  766.                 }
  767.           }
  768.           RX1_Cnt=0;
  769.    }
  770.    else if(ceng>=str_len_limt)
  771.    {
  772.                a_vec=0;
  773.                   ceng=0;
  774.    }
  775. }

  776. //unsigned char
  777. void UART1_int (void) interrupt UART1_VECTOR
  778. {
  779.         if(RI)
  780.         {
  781.                 RI = 0;
  782.                 if(a_vec==0)//上次未曾過濾到指定的字符串中所有的字符出現(xiàn),每次只過濾一個字符
  783.                 {
  784.                  switch(uart_rec_sta)              //根據(jù)系統(tǒng)的狀態(tài),決定過濾哪個字符
  785.                  {
  786.                   case uart_rec_tcp_udp_data: //串口進(jìn)入正常的UDP TCP 數(shù)據(jù)收發(fā)
  787.                   fit_stb(PIPD_code);                  //過濾數(shù)據(jù)接收頭
  788.                   break;
  789.                   case  uart_rec_csysid:          //串口進(jìn)入獲得模塊內(nèi)部ID 和KEY 狀態(tài)
  790.                   fit_stb(CYSYS_code);              //過濾指定的頭部
  791.                   break;
  792.                   case uart_rec_smartlink:          //串口進(jìn)入獲得客戶的路由器賬戶密碼狀態(tài)
  793.                   fit_stb(smartlink_code);
  794.                   break;
  795.                   case uart_rec_bander:
  796.                   fit_stb(bander_code);
  797.                  }
  798.                 }
  799.                 else//////////////////////////////過濾到指定的頭部
  800.                 {
  801.                
  802.                  recd_buf[RX1_Cnt] = SBUF;                //保存一個字節(jié)
  803.                  if(recd_buf[RX1_Cnt]==0X55)    //記錄0X55的個數(shù),出現(xiàn)兩次后,代表一個有數(shù)據(jù)包結(jié)束
  804.                  two_lab++;
  805.                  if(RX1_Cnt<62)        /////////////////////防止64字節(jié)的緩沖區(qū)溢出
  806.                  RX1_Cnt++;
  807.                  else                        ///////每次收到的指令超過64字節(jié),就把數(shù)據(jù)清空,接收指針指向開頭
  808.                  {
  809.                    RX1_Cnt=0;
  810.                    a_vec=0;
  811.                    two_lab=0;
  812.                  }
  813.                  switch(uart_rec_sta)
  814.                   {
  815.                     case uart_rec_tcp_udp_data:
  816.                         //have_dd=1;
  817.                            //LED2=0;
  818.                                 if(two_lab==2)//////////////////////////////////////////得到一包有效的數(shù)據(jù)!取出2個OX55之間的有效數(shù)據(jù)////////////////////
  819.                                  {
  820.                                    a_vec=0;
  821.                                    rec_len=RX1_Cnt;
  822.                                    two_lab=0;
  823.                                    RX1_Cnt=0;
  824.                    LED1=0;
  825.                                    LED2=0;
  826.                                    LED3=0;

  827.                                    change_pack();
  828.                                    have_data=1;
  829.                                     if((recd_buf[32])==':')              /////////////////////////////////////簡單得到手機的開關(guān)指令////////////////////
  830.                                         {
  831.                                          if((recd_buf[33])=='0')
  832.                                          {
  833.                                           DK1=0;
  834.                                           LED1=1;          //關(guān)燈指令
  835.                                          }
  836.                                          else if((recd_buf[33])=='1')
  837.                                          {
  838.                                           DK1=1;
  839.                                       LED1=0;    //開燈指令
  840.                                          }
  841.                                         }
  842.                                         if((recd_buf[3]==0xa0)&&(recd_buf[9]==0x00)&&(have_tok==0))////////////////////獲得TOKE包//////////////////////////////////
  843.                                         {
  844.                                           have_tok=1;
  845.                                           toke[7]=recd_buf[19];             
  846.                                           toke[6]=recd_buf[20];               
  847.                                           toke[5]=recd_buf[21];       
  848.                                           toke[4]=recd_buf[22];                 
  849.                                           toke[3]=recd_buf[23];
  850.                                           toke[2]=recd_buf[24];
  851.                                           toke[1]=recd_buf[25];
  852.                                           toke[0]=recd_buf[26];

  853.                                         }
  854.                                  }
  855.                         break;
  856.                    case  uart_rec_csysid:
  857.                    if(RX1_Cnt>40)
  858.                    have_id=1;
  859.                    break;
  860.                    case  uart_rec_smartlink:
  861.                    if(RX1_Cnt>10)
  862.                    have_smartlink=1;
  863.                    break;
  864.                    case  uart_rec_bander:
  865.                    if(RX1_Cnt>20)
  866.                    have_bander=1;
  867.                    break;
  868.                  };
  869.           }
  870.         }
  871.         if(TI)
  872.         {
  873.                 TI = 0;
  874.                 B_TX1_Busy = 0;                //清除發(fā)送忙標(biāo)志
  875.         }
  876. }
復(fù)制代碼
  1. /*
  2.   注意:變量初始化成0,否者隨機  數(shù)組注意溢出問題  0X55 在其他數(shù)據(jù)中有可能出現(xiàn),并造成混亂,主要是計數(shù)  過濾數(shù)據(jù),根據(jù)網(wǎng)絡(luò)環(huán)境不同,返回有可能變化,注意通用性
  3.   內(nèi)部 ID KEY 輸出格式已經(jīng)固定為8個字節(jié)模式
  4. */


  5. /*************        本地常量聲明        **************/
  6. #define MAIN_Fosc                22118400L        //定義主時鐘
  7. #define        RX1_Lenth                32                        //串口接收緩沖長度
  8. #define        BaudRate1                115200UL        //選擇波特率
  9. #define        Timer1_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 1 重裝值, 對應(yīng)300KHZ
  10. #define        Timer2_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 2 重裝值, 對應(yīng)300KHZ
  11. #include        "STC15Fxxxx.H"
  12. /*************        本地變量聲明        **************/
  13. u8        idata RX1_Buffer[RX1_Lenth];        //接收緩沖
  14. u8        TX1_Cnt;        //發(fā)送計數(shù)
  15. u8        RX1_Cnt;        //接收計數(shù)
  16. bit        B_TX1_Busy;        //發(fā)送忙標(biāo)志
  17. /*************        端口引腳定義        **************/
  18. unsigned char two_lab=0;
  19. sbit LED1=P1^0;//LED1
  20. sbit LED2=P1^1;//LED2
  21. sbit LED3=P3^7;//LED3
  22. sbit DK1=P3^3;//繼電器
  23. sbit BEEP=P3^4;//蜂鳴器
  24. sbit K1=P1^3;//按鍵1
  25. sbit K2=P1^2;//按鍵2
  26. sbit K3=P1^4;//按鍵3
  27. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  28. /////這是安信可云平臺數(shù)據(jù)包的全部組成結(jié)構(gòu),細(xì)節(jié)可參照安信可的云平臺V1.0版本規(guī)格書,包結(jié)構(gòu)章節(jié)
  29. #define O_PF    0X00  //包頭1字節(jié)固定0X55
  30. #define O_LEN_L 0X01  //整個包長低字節(jié)
  31. #define O_LEN_H 0X02  //整個包長高字節(jié) 注意轉(zhuǎn)義碼 兩個這里只計算一個數(shù)據(jù)處理!
  32. #define O_CMD_T 0X03  //命令類型
  33. #define O_CMD_C 0X04  //具體命令
  34. #define O_CIX_L 0X05  //本命令序列編號低字節(jié)
  35. #define O_CIX_H 0X06  //本命令序列編號高字節(jié)
  36. #define O_EXMSH 0X07  //擴展信息高字節(jié)
  37. #define O_EXMSL 0X08  //擴展信息低字節(jié)
  38. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請求 未知
  39. #define O_DEVID_START 0x0A  //8字節(jié)設(shè)備識別  低字節(jié)在前
  40. #define O_DEVID 0x0A  //8字節(jié)設(shè)備識別
  41. #define O_TK_LEN      0X12 //1 BYTS TL_LEN          //獲得的設(shè)備臨時通訊令牌長度
  42. #define O_TOKE_START  0X13
  43. #define O_DATAS_START 0X1B
  44. //N BYTS DATAS          //客戶的數(shù)據(jù)包串
  45. //CRC_L    1BYTE          //CRC16 低字節(jié)
  46. //CRC_H    1BYTE          //CRC16 高字節(jié)
  47. //PACK_END 1BYTE          //包尾1字節(jié)固定0X55

  48. ////////////////////////////////////////////////////////////////////////以上定義了包中的各參數(shù)的絕對位置//////////////////////////////////
  49. #define uart_rec_tcp_udp_data 0        //系統(tǒng)進(jìn)入正常網(wǎng)絡(luò)數(shù)據(jù)收發(fā)狀態(tài)
  50. #define uart_rec_csysid       1        //系統(tǒng)獲取ESP8266WIFI模塊的許可號狀態(tài),獲取四個字節(jié)的芯片ID 和 4個字節(jié)的授權(quán)碼
  51. #define uart_rec_smartlink    2        //系統(tǒng)進(jìn)入獲取上網(wǎng)賬號密碼狀態(tài)
  52. #define uart_rec_bander       3        //系統(tǒng)進(jìn)入將本W(wǎng)IFI設(shè)備 和APP 手機綁定控制狀態(tài)
  53. //////////////////////////////////////////////////////////////////////以上部分定義了系統(tǒng)的幾種狀態(tài)///////////////////////////////////////
  54. bit have_tok=0;
  55. bit have_data=0;
  56. unsigned char rec_len=0;
  57. bit                   a_vec=0;                   //設(shè)置一個標(biāo)志位,串口程序 出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  58. unsigned char          ceng=0;         //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  59. unsigned char str_len_limt=16;         //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  60. unsigned char   str_len_num=11;        //字符個數(shù)
  61. char str_ref=':';
  62. /////////////////////////////////////////////////////////////////////上面幾個變量用來作為在串口中過濾指定字符串的 限定參數(shù),改變過濾內(nèi)容后必定先初始化這幾個/////
  63. code char CYSYS_code[]="+CSYSID:CHIP";
  64. code char PIPD_code[]="+IPD,";
  65. code char bander_code[]="+IPD,4,26:RPL:";//這里過濾有漏洞
  66. code char smartlink_code[]="SMART SUCCESS";
  67. /////////////////////////////////////////////////////////////////////以上是從WIFI模塊串口輸出到本單片機串口輸入后,本單片機要過濾的各種頭部////////////////////
  68. unsigned char uart_rec_sta=uart_rec_csysid;// 串口目前所處于的狀態(tài),比如進(jìn)入正常數(shù)據(jù)接收,或者SMARTLINK 或者 獲取模塊的ID。
  69. code unsigned char AT_RST[]="AT+RST";                                                     
  70. code unsigned char AT_MODE[]="AT+CWMODE=1";
  71. code unsigned char AT_CWJAP[]="AT+CWJAP=\"360we\",\"zty0012001\"";
  72. code unsigned char AT_CIP3[]="AT+CIPSTART=3,\"UDP\",\"cloud.ai-thinker.com\",5001,2468,0" ;
  73. code unsigned char temp_bander[]="RPT:\"0xa1b23467\",\"0xaf321234\",\"192.168.0.123\",\"light\",\"123456a\"";
  74. code unsigned char AT_CIPMUX[]="AT+CIPMUX=1";
  75. code unsigned char CIPSTART[]="AT+CIPSTART=4,\"UDP\",\"cloud.ai-thinker.com\",5001,2468,0";
  76. code unsigned char AT_CSYSID[]="AT+CSYSID";
  77. code unsigned char AT_SMARTLINK[]="AT+CWSMARTSTART=1";
  78. code unsigned char ZERO[]="00000000000000000000000000000000001";
  79. code unsigned char CIPSEND_LEN[]="AT+CIPSEND=4,";
  80. code unsigned char CIP3SEND_LEN[]="AT+CIPSEND=3,63";
  81. /////////////////////////////////////////////////////////////////////以上字串是單片機發(fā)給串口模塊的AT語句有的是直接給WIFI模塊的指令,有些是用來拷貝字符串用/////////////

  82. xdata unsigned char at_send_len_ox[20];               
  83. idata unsigned char send_buf[64]="jisifsfhello:99999;oop";                             //發(fā)送緩沖區(qū)
  84. unsigned char recd_buf[64]= {0x55 ,0x25 ,0x00 ,0xAA ,0xFF ,0x00, 0x00, 0x00, 0x00 ,0x02 ,0x31, 0x0A ,0xFE ,0x00, 0x00, 0x00, 0x00 ,0x00, 0x08, 0x00 ,0x7C ,0xC8, 0x52 ,0xFE, 0x3D ,0x64 ,0x29, 0x4C ,0x49, 0x47, 0x48 ,0x54 ,0x02, 0x3A ,0x3F, 0x6C, 0x02, 0x55};                                                 //接收緩沖區(qū)
  85. data unsigned char temp_buf[72];                                 //加工緩沖區(qū)
  86. idata unsigned char toke[8]={0x24,0x41,0xD6,0x39,0x48,0x83,0xAC,0x00};//此設(shè)備在服務(wù)器上獲得的令牌包
  87. unsigned char esp_dev_id[8]={0,0,0,0,0,0,0X1E,0XDE};         //    8266的8個字節(jié)的器件ID號,可在服務(wù)器數(shù)據(jù)庫中查到,唯一標(biāo)示一個器件,登錄過程需要一個器件ID,和數(shù)據(jù)區(qū)放一個數(shù)據(jù)密碼,這么簡單登錄
  88. unsigned char esp_TOK_id[8]={0,0,0,0,0,0,0,0};                                 //    服務(wù)器分給器件器件的令牌包,另外個地方也定義了,完全可以用一個數(shù)組完成的
  89. unsigned char esp_user_data[14]={0,0,0,0,0,0,0X1E,0XDE};         //    客戶的凈數(shù)據(jù)負(fù)荷區(qū),可以很大,因為本款單片機有限,并且一般控制信號,定義幾個字節(jié)夠了!注意在登錄的時候,這里是器件密碼!
  90. unsigned char temp_cd[]="TEMP:123;";                                                 //    一個數(shù)據(jù)包,前面是包格式定義,后面是客戶數(shù)據(jù)區(qū),這里定義一個即將要發(fā)送的溫度數(shù)據(jù)
  91. unsigned char need_seed_len=0;                                                                 //    全局變量,本次總共需要發(fā)到串口的數(shù)據(jù)
  92. bit t_o=0;                                                                                                         //  在構(gòu)造一個如00123 的數(shù)據(jù)時候,去掉前面的00變成123 這里若碰到0就置1
  93. code unsigned char cip3_lcport[]="2469,0";
  94. data unsigned char chip_id[8]={'0','0','0','0','0','0','0','0'};
  95. data unsigned char flash_id[8]={'0','0','0','0','0','0','0','0'};
  96. pdata unsigned char pass_id[8]={'0','0','0','0','0','0','0','0'};

  97. unsigned int time=0; //每隔30秒把一個變量加1,然后把這個變量作為溫度數(shù)據(jù)上報給云平臺,轉(zhuǎn)給手機端

  98. xdata unsigned char ssid[32];          //暫存SSID賬戶信息
  99. xdata unsigned char password[20]; //暫存客戶密碼
  100. idata char ssid_len=0;                  //記錄SSID 長度
  101. idata char pasd_len=0;                          //記錄密碼長度

  102. bit have_id=0;                                          //記錄是否用AT指令獲取到了這個模塊的ID 和KEY信息
  103. bit have_smartlink=0;                          //記錄是否過濾到 從串口來的TCP UDP 數(shù)據(jù)  smartlink
  104. bit have_bander=0;                                  //記錄是從串口中輸出的網(wǎng)絡(luò)數(shù)據(jù)中過濾到 手機用UDP發(fā)來的請求信息

  105. unsigned char stac_a=0;                      //全局專用變量
  106. unsigned char stac_b=0;                          //全局專用變量

  107. #include "intrins.h"

  108. typedef unsigned char BYTE;
  109. typedef unsigned int WORD;

  110. void IapIdle();
  111. BYTE IapReadBYTE(WORD addr);



  112. #define CMD_IDLE      0
  113. #define CMD_READ      1
  114. #define CMD_PROGRAM   2
  115. #define CMD_ERASE     3

  116. #define ENABLE_IAP  0X81
  117. #define IAP_ADDRESS 0X0400


  118. /////////////////////////////////////////////////////////////////下面部分定義了CRC16校驗函數(shù)用到的表格///////////////////////////////////
  119. code unsigned int crc_table[256]=
  120. {               /* CRC余式表 */
  121. 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
  122. 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
  123. 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
  124. 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
  125. 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
  126. 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
  127. 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
  128. 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
  129. 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
  130. 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
  131. 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
  132. 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
  133. 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
  134. 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
  135. 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
  136. 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
  137. 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
  138. 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
  139. 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
  140. 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
  141. 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
  142. 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
  143. 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
  144. 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
  145. 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
  146. 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
  147. 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
  148. 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
  149. 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
  150. 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
  151. 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
  152. 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
  153. };

  154. void Delay(BYTE n);
  155. void IapIdle();
  156. BYTE IapReadByte(WORD addr);
  157. void IapProgramByte(WORD addr,BYTE dat);
  158. void IapEraseSector(WORD addr);

  159. void flash_main()
  160. {  
  161.    WORD i;
  162.    //P1=0xfe;
  163.    Delay(10);
  164.    IapEraseSector(IAP_ADDRESS);
  165.    for(i=0;i<512;i++)
  166.    {
  167.      if(IapReadByte(IAP_ADDRESS+i)!=0xff)
  168.          goto Error;
  169.    }
  170.    //P1=0xfc;
  171.    Delay(10);
  172.    for(i=0;i<512;i++)
  173.    {
  174.       IapProgramByte(IAP_ADDRESS+i,(BYTE)i);
  175.    }
  176.    //P1=0XF8;
  177.    Delay(10);
  178.    for(i=0;i<512;i++)
  179.    {
  180.      if(IapReadByte(IAP_ADDRESS+i)!=(BYTE)i)
  181.          goto Error;
  182.    }
  183.    //P1=0XF0;
  184.    while(1);
  185.    Error:
  186.    //P1&=0x7f;
  187.    while(1);
  188. }
  189. void Delay(BYTE n)
  190. {
  191.   WORD x;
  192.   while(n--)
  193.   {
  194.    x=0;
  195.    while(++x);
  196.   }
  197. }
  198. void IapIdle()
  199. {
  200.   IAP_CONTR=0;
  201.   IAP_CMD=0;
  202.   IAP_TRIG=0;
  203.   IAP_ADDRH=0X80;
  204.   IAP_ADDRL=0;
  205. }

  206. BYTE IapReadByte(WORD addr)
  207. {
  208.    BYTE dat;
  209.    IAP_CONTR=ENABLE_IAP;
  210.    IAP_CMD=CMD_READ;
  211.    IAP_ADDRL=addr;
  212.    IAP_ADDRH=addr>>8;
  213.    IAP_TRIG=0x5a;
  214.    IAP_TRIG=0xa5;
  215.    _nop_();
  216.    dat=IAP_DATA;
  217.    IapIdle();
  218.    return dat;
  219. }

  220. void IapProgramByte(WORD addr,BYTE dat)
  221. {
  222.   IAP_CONTR=ENABLE_IAP;
  223.   IAP_CMD=CMD_PROGRAM;
  224.   IAP_ADDRL=addr;
  225.   IAP_ADDRH=addr>>8;
  226.   IAP_DATA=dat;
  227.   IAP_TRIG=0x5a;
  228.   IAP_TRIG=0xa5;
  229.   _nop_();
  230.   IapIdle();
  231. }

  232. void IapEraseSector(WORD addr)
  233. {
  234.   IAP_CONTR=ENABLE_IAP;
  235.   IAP_CMD=CMD_ERASE;
  236.   IAP_ADDRL=addr;
  237.   IAP_ADDRH=addr>>8;
  238.   IAP_TRIG=0x5a;
  239.   IAP_TRIG=0xa5;
  240.   _nop_();
  241.   IapIdle();
  242. }
  243. /////////////////////////////////////////////////////////////////上面部分定義了CRC16校驗函數(shù)用到的表格///////////////////////////////////


  244. void make_AT_CIP3(void)
  245. //根據(jù)上邊 在2468 端口監(jiān)聽到的 廣播內(nèi)容 用廣播內(nèi)容的IP 地址192.168.1.10和端口 48008新建一個3連接,
  246. //AT+CIPSTART=3,"UDP","192.168.1.10",48008,2469,0
  247. ///新建一個連接3
  248. {
  249.   unsigned char a,b;
  250.   for(a=0,b=0;a<21;a++,b++)
  251.   temp_buf[b]=AT_CIP3[b];
  252.   for(a=0;recd_buf[a]!=',';a++,b++)
  253.   temp_buf[b]=recd_buf[a];
  254.   temp_buf[b]=',';
  255.   b++;
  256.   a+=2;
  257.   for(;recd_buf[a]!='"';a++,b++)
  258.   temp_buf[b]=recd_buf[a];
  259.   temp_buf[b]=',';
  260.   b++;
  261.   for(a=0;cip3_lcport[a]!=0;a++,b++)
  262.   temp_buf[b]=cip3_lcport[a];
  263.   temp_buf[b]=0;
  264. }
  265. //將16進(jìn)制數(shù),變成16進(jìn)制字符比如10變成A
  266. char back_char(unsigned char user_d)
  267. {
  268.   if(user_d<10)
  269.   return (user_d+'0');
  270.   else
  271.   return (user_d-10+'A');
  272. }
  273. ////制作 向手機發(fā)送如下格式UDP數(shù)據(jù)
  274. ////RPT:"0x00FE6738","0xB8B3C281","192.168.0.123","light","123456a"
  275. void make_bander_data()
  276. {
  277.   unsigned char a,b=0;
  278.   for(a=0;temp_bander[a]!=0;a++)
  279.   temp_buf[a]=temp_bander[a];
  280.   temp_buf[a]=0;

  281.   //以上硬拷貝 code unsigned char temp_bander[]="RPT:\"0xa1b23467\",\"0xaf321234\",\"192.168.0.123\",\"light\",\"123456a\"";到 temp_buf
  282.   //以下語句修改RPT:"0x00FE6738","0xB8B3C281","192.168.0.123","light","123456a" 中將本身的設(shè)備ID(如0x00FE6738) 和 KEY(0xB8B3C281)放到上面修改后的temp_buf
  283.   temp_buf[7]=back_char(esp_dev_id[4]>>4);
  284.   temp_buf[8]=back_char(esp_dev_id[4]&0x0f);
  285.   temp_buf[9]=back_char(esp_dev_id[5]>>4);
  286.   temp_buf[10]=back_char(esp_dev_id[5]&0x0f);
  287.   temp_buf[11]=back_char(esp_dev_id[6]>>4);
  288.   temp_buf[12]=back_char(esp_dev_id[6]&0x0f);
  289.   temp_buf[13]=back_char(esp_dev_id[7]>>4);
  290.   temp_buf[14]=back_char(esp_dev_id[7]&0x0f);

  291.   temp_buf[20]=back_char(esp_user_data[7]>>4);
  292.   temp_buf[21]=back_char(esp_user_data[7]&0x0f);
  293.   temp_buf[22]=back_char(esp_user_data[6]>>4);
  294.   temp_buf[23]=back_char(esp_user_data[6]&0x0f);
  295.   temp_buf[24]=back_char(esp_user_data[5]>>4);
  296.   temp_buf[25]=back_char(esp_user_data[5]&0x0f);
  297.   temp_buf[26]=back_char(esp_user_data[4]>>4);
  298.   temp_buf[27]=back_char(esp_user_data[4]&0x0f);
  299. }

  300. void make_AT_SEND(unsigned char a_len)   //生成右邊這樣的指令,將參數(shù)a_len 改成10進(jìn)制,右邊這條指令  "AT+CIPSEND=XX" XX是發(fā)送的數(shù)量
  301. {
  302.   unsigned char aa=0;
  303.   for(aa=0;aa<13;aa++)
  304.   {
  305.     at_send_len_ox[aa]=CIPSEND_LEN[aa];         //剪貼"AT+CIPSEND= 到RAM  后面的十進(jìn)制參數(shù)由下面的部分生成
  306.   }
  307.   t_o=0;                                 //去掉前面的0,比如發(fā)送38個字節(jié),038,前面的0就可以去掉了。
  308.   if((a_len/100))
  309.   {
  310.   at_send_len_ox[aa]=a_len/100+'0';
  311.   aa++;
  312.   t_o=1;
  313.   }
  314.   if((a_len%100)/10)
  315.   {
  316.   at_send_len_ox[aa]=(a_len%100)/10+'0';
  317.   aa++;
  318.   t_o=1;
  319.   }
  320.   else if(t_o)
  321.   {
  322.     at_send_len_ox[aa]=0+'0';
  323.         aa++;
  324.   }
  325.   at_send_len_ox[aa]=(a_len%10)+'0';
  326.   aa++;
  327.   at_send_len_ox[aa]=0;
  328. }
  329. //下面函數(shù)獲得CRC校驗碼 采用標(biāo)準(zhǔn)CRC16 初始CRC=0XFFFF  運算多項式參數(shù) 8005 非1021
  330. unsigned int GetRevCrc_16(unsigned char * pData, int nLength)
  331. {
  332.   unsigned int cRc_16 = 0xffff;
  333.   unsigned char temp;
  334.   while(nLength-- > 0)
  335.   {
  336.     temp = cRc_16&0xff;
  337.     cRc_16 = (cRc_16 >> 8) ^ crc_table[(temp ^ *pData++) & 0xFF];
  338.   }
  339.   return cRc_16;   
  340. }
  341. //下面這個函數(shù)構(gòu)造一個發(fā)送的數(shù)據(jù)格式,請看數(shù)據(jù)格式文檔,完全可以用結(jié)構(gòu)體完成,這里采用數(shù)據(jù),從上到下描述這個數(shù)據(jù)包
  342. //發(fā)送的數(shù)據(jù)包,目前只有登錄數(shù)據(jù)包,和上報溫度數(shù)據(jù)包,這兩個基本的數(shù)據(jù)包,上報數(shù)據(jù)包可以充當(dāng)心跳包,第一個參數(shù)決定著,是發(fā)送登錄包還是溫度包
  343. //其他幾個入口參數(shù)是器件ID,令牌包,以及客戶的數(shù)據(jù),以及客戶數(shù)據(jù)長度

  344. void make_send_pack(unsigned char ms_opt,unsigned char *dev_id,unsigned char *toke_id,unsigned char *use_data,unsigned char use_data_len)
  345. {
  346.   unsigned char a,b,i=0;
  347.   unsigned esp_crc=0;
  348.   send_buf[0]=0x55;                                                     //包頭是0X55固定
  349.   
  350.   send_buf[O_LEN_L]=(O_DATAS_START+use_data_len+3)%0xff; //本數(shù)據(jù)包的所有數(shù)據(jù)長度,包頭至包尾,記得是沒有經(jīng)過轉(zhuǎn)義前的包長
  351.   send_buf[O_LEN_H]=(O_DATAS_START+use_data_len+3)/0xff;

  352.   if(ms_opt==0)                                                                                         //根據(jù)入口參數(shù)判斷是發(fā)送登錄鏈路操作,還是發(fā)送數(shù)據(jù)包云平臺
  353.   send_buf[O_CMD_T]=0XA0;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實時檢測指令 0XF0 終端操作
  354.   else if (ms_opt==1)
  355.   send_buf[O_CMD_T]=0XAA;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實時檢測指令 0XF0 終端操作

  356.   if(ms_opt==0)                                                                //0X00代表登錄操作
  357.   send_buf[O_CMD_C]=0X00;// reg  option
  358.   else if (ms_opt==1)
  359.   send_buf[O_CMD_C]=0XEE;                                                    //0XEE代表數(shù)據(jù)是從設(shè)備到云平臺的方向

  360.   send_buf[O_CIX_L]=0XF3;// CMD INDEXL                        //命令序列編號,暫時不用,可以作為對方應(yīng)答的數(shù)據(jù)包號標(biāo)示
  361.   send_buf[O_CIX_H]=0XC0;//        CMD INDEXL                                        //命令序列編號,暫時不用,可以作為對方應(yīng)答的數(shù)據(jù)包號標(biāo)示
  362.   send_buf[O_EXMSH]=0XC0;//        EXTERN MESSAGE1                                //擴展子暫時保留
  363.   send_buf[O_EXMSL]=0XF3;//        EXTERN MESSAGE2                                //擴展子暫時保留

  364.   send_buf[O_RESTA]=0X02;//        CMD_STA 00 OK 01 FAIL 02 SEND 03 NO SUP         //代表本數(shù)據(jù)包的狀態(tài),是發(fā)送還是應(yīng)答成功還是失敗

  365.   for(i=0;i<8;i++)
  366.   send_buf[O_DEVID+i]=*(dev_id+(7-i)); // 拷貝設(shè)備的唯一ID號到數(shù)據(jù)包里


  367.   send_buf[O_TK_LEN] =8;                   //代表接下來的令牌包是8個字節(jié)


  368.   for(i=0;i<8;i++)
  369.   send_buf[O_TOKE_START+i]=*(toke_id+i);//8個字節(jié)令牌包,初始令牌包為00 后續(xù)服務(wù)器會分配一個令牌包給這個設(shè)備,設(shè)備每次通訊要攜帶這個令牌包


  370.   for(i=0;i<use_data_len;i++)
  371.   send_buf[O_DATAS_START+i]=*(use_data+i); // 客戶的數(shù)據(jù)區(qū),登錄的時候放數(shù)據(jù)密碼文本
  372.   
  373.   temp_buf[0]=0x55;                                                   //包尾

  374.   esp_crc=GetRevCrc_16(send_buf,O_DATAS_START+use_data_len);//得到轉(zhuǎn)義之前的總數(shù)據(jù)包CRC,具體可以參照CRC數(shù)據(jù)格式,因此CRC是針對轉(zhuǎn)義之前的數(shù)據(jù)生成

  375.   for(a=1,b=1;a<(O_DATAS_START+use_data_len);a++)           //將出去包頭,所有的數(shù)據(jù)中含有有0X55的數(shù)據(jù)轉(zhuǎn)義成0X54,0X01,將0X54 變成0X54,02,重新轉(zhuǎn)義數(shù)據(jù)包
  376.   {
  377.     if(send_buf[a]==0x55)
  378.         {
  379.           temp_buf[b]=0x54;
  380.           b+=1;
  381.           temp_buf[b]=0x01;
  382.           b+=1;
  383.         }
  384.         else if(send_buf[a]==0x54)
  385.         {
  386.           temp_buf[b]=0x54;
  387.           b+=1;
  388.           temp_buf[b]=0x02;
  389.           b+=1;
  390.         }
  391.         else
  392.         {
  393.         temp_buf[b]=send_buf[a];
  394.         b+=1;
  395.         }
  396. }         ///////////////////////////////////////////////////////////以上的語句轉(zhuǎn)義數(shù)據(jù)包中除包頭到CRC之前的全部的數(shù)據(jù)///////////////////////////////////////////////////////////////////////
  397. //55 28 00 AA EE F3 C0 C0 F3 02 E6 1E 00 00 00 00 00 00 08 24 41 D6 39 48 83 AC 00 54 02 45 4D 50 3A 32 35 35 3B 00 D1 52 55
  398. //55 28 00 AA EE F3 C0 C0 F3 02 E6 1E 00 00 00 00 00 00 08 24 41 D6 39 48 83 AC 00 54 02 45 4D 50 3A 32 35 35 3B 00 D1 52 55

  399. temp_buf[b]=(esp_crc>>8);
  400. b+=1;
  401. temp_buf[b]=(esp_crc&0x00ff);         
  402. b+=1;
  403.     ///////////////////////////////////////////////////////////上面兩句加上CRC校驗////////////////////////////////////////
  404. temp_buf[b]=0x55;        //包尾
  405. b+=1;
  406. temp_buf[b]=0x0d;
  407. b+=1;
  408. temp_buf[b]=0x0a;
  409. b+=1;                                //以上構(gòu)成回車
  410. need_seed_len=b;        //至此構(gòu)造出了需要發(fā)送的全部數(shù)據(jù) 包括AT指令需要的換行
  411. temp_buf[b]=0x00;
  412. }



  413. void Delay1(unsigned long ms)//簡單延遲函數(shù),單位是毫秒
  414. {
  415.         unsigned char i, j,k;
  416.         for(k=0;k<ms;k++)
  417.         {
  418.                 _nop_();
  419.                 _nop_();
  420.                 i = 22;
  421.                 j = 128;
  422.                 do
  423.                 {
  424.                         while (--j);
  425.                 } while (--i);
  426.         }
  427. }


  428. void Delay2(unsigned long cnt)
  429. {
  430.         long i;
  431.         for(i=0;i<cnt*100;i++);
  432. }

  433. void at_uart_send_str(unsigned char *str)//發(fā)送AT字符串到串口
  434. {
  435.   unsigned char *st_p=str;
  436.   do{
  437.      SBUF=*st_p;
  438.          st_p++;
  439.          Delay1(1);
  440.         }while(*st_p);
  441.         SBUF='\r';
  442.         Delay1(1);
  443.         SBUF='\n';
  444.         Delay1(1);
  445. }
  446. void at_uart_send_buf(unsigned char *str,unsigned char len)//發(fā)送數(shù)據(jù)緩沖區(qū)的非字符串信息,數(shù)據(jù)流信息到串口
  447. {
  448.   unsigned char *st_p=str;
  449.   
  450.   while(len){
  451.      SBUF=*st_p;
  452.          st_p++;
  453.          Delay1(1);
  454.          len--;
  455.         }while(*st_p);
  456.         //SBUF='\r';
  457.         Delay1(1);
  458.         //SBUF='\n';
  459.         Delay1(1);
  460. }


  461. void change_pack()                                          //把接收到的數(shù)據(jù)包轉(zhuǎn)義過來,0X55 轉(zhuǎn)義成0X54 0X01 0X54 替換成0X54 02
  462. {
  463.                                      for(stac_a=1,stac_b=1;recd_buf[stac_a]!=0x55;)
  464.                                    {
  465.                                      if((recd_buf[stac_a]==0x54)&&(recd_buf[stac_a+1]==0x01))
  466.                                          {
  467.                                          temp_buf[stac_b]=0x55;
  468.                                          stac_b++;
  469.                                          stac_a+=2;
  470.                                          }
  471.                                          else if((recd_buf[stac_a]==0x54)&&(recd_buf[stac_a+1]==0x02))
  472.                                          {
  473.                                          temp_buf[stac_b]=0x54;
  474.                                          stac_b++;
  475.                                          stac_a+=2;
  476.                                          }
  477.                                          else
  478.                                          {
  479.                                            temp_buf[stac_b]=recd_buf[stac_a];
  480.                                            stac_b++;
  481.                                            stac_a++;
  482.                                          }
  483.                                   }
  484.                                   temp_buf[stac_b]=0x55;
  485.                                   temp_buf[0]=0x55;
  486.                                   recd_buf[0]=temp_buf[0];
  487.                                   for(stac_a=1;temp_buf[stac_a]!=0x55;stac_a++)
  488.                                   recd_buf[stac_a]=temp_buf[stac_a];
  489.                                   recd_buf[stac_a]=0x55;
  490.                                   recd_buf[0]=0x55;
  491. }
  492. void init_uart(void)
  493. {
  494.           B_TX1_Busy = 0;
  495.         RX1_Cnt = 0;
  496.         TX1_Cnt = 0;
  497.         S1_8bit();                                //8位數(shù)據(jù)
  498.         S1_USE_P30P31();                //UART1 使用P30 P31口        默認(rèn)
  499.         AUXR &= ~(1<<4);        //Timer stop                波特率使用Timer2產(chǎn)生
  500.         AUXR |= 0x01;                //S1 BRT Use Timer2;
  501.         AUXR |=  (1<<2);        //Timer2 set as 1T mode
  502.         TH2 = (u8)(Timer2_Reload >> 8);
  503.         TL2 = (u8)Timer2_Reload;
  504.         AUXR |=  (1<<4);        //Timer run enable
  505.         REN = 1;        //允許接收
  506.         ES  = 1;        //允許中斷
  507.         EA = 1;                //允許全局中斷
  508.         P3M1 = 0x00;
  509.     P3M0 = 0xFF;
  510.         RX1_Cnt=0;
  511.         DK1=0;
  512.         BEEP=0;
  513. }

  514. void main(void)
  515. {
  516.         char tt,i,k,n,z=0;
  517.         //////////////////////////////////////////////////////////////////////////////////////下面部分為定時器以及串口初始化/////////////////////
  518.         init_uart();
  519.         Delay2(2000);
  520.         flash_main();
  521.         ///////////////////////////////////////////////////////////////////////////////////以上部分主要完成串口的初始化////////////////////////////
  522.         for(;;)
  523.         {         
  524.         a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  525.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  526.         str_len_limt=22;          //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  527.         str_len_num=13;           //要過濾連續(xù)字符個數(shù)
  528.         str_ref=':';                          // 過濾到字符串后,接著要出現(xiàn)的字符,這個字符出現(xiàn)的位置才是絕對0位置
  529.                 uart_rec_sta=uart_rec_smartlink; //設(shè)置在串口中的過濾分支條件,串口中斷中,根據(jù)這個標(biāo)志調(diào)用不同的字符串過濾參數(shù)

  530.                 at_uart_send_str(AT_MODE);                 //設(shè)置模塊進(jìn)入STATION 模式
  531.                 Delay2(1000);
  532.                 at_uart_send_str(AT_SMARTLINK);         //發(fā)送進(jìn)入SMARTLINK AT指令
  533.                                          //PASSWORD:zty0012001       
  534.                 Delay2(2000);
  535.                 do                                                                 //此循環(huán)完成SMARTLINK 的配置
  536.                 {
  537.                 LED1=0;
  538.                 LED2=0;
  539.                 LED3=0;
  540.                 Delay2(200);
  541.                 LED1=1;
  542.                 LED2=1;
  543.                 LED3=1;
  544.                 Delay2(200);
  545.                 if(have_smartlink)//假如從串口中獲得正確的 SMARTLINK 用戶路由器賬戶和密碼
  546.                 {
  547.                         for(i=0;recd_buf[i]!=0x0d;i++)
  548.                         {
  549.                                 ssid_len++;
  550.                                 ssid[i]=recd_buf[i];                                  //拷貝串口緩沖區(qū)中的用戶路由器名字
  551.                         }
  552.                         for(i=0;recd_buf[ssid_len+11+i]!='\r';i++)
  553.                         {
  554.                                 password[i]=recd_buf[ssid_len+11+i];          //拷貝串口緩沖區(qū)中的用戶路由器密碼
  555.                                 pasd_len++;
  556.                         }
  557.                 //code unsigned char AT_CWJAP[]="AT+CWJAP=\"360we\",\"zty0012001\"";
  558.                         n=0;
  559.                         for(i=0;i<63;i++)
  560.                     temp_buf[i]=0;                //清空臨時緩沖區(qū)

  561.                         for(i=0;i<10;i++,n++)
  562.                         temp_buf[n]=AT_CWJAP[i];      //拷貝AT指令加入路由器的格式頭AT+CWJAP="

  563.                         for(i=0;i<ssid_len;i++,n++)          //用SMARTLINK 獲得的 SSID 和PASSWORLD 填充 加入路由器所需要的兩個參數(shù)        AT+CWJAP="360we","zty0012001"
  564.                         temp_buf[n]=ssid[i];
  565.                         temp_buf[n]='"';
  566.                         n++;
  567.                         temp_buf[n]=',';
  568.                         n++;
  569.                         temp_buf[n]='"';
  570.                         n++;
  571.                         for(i=0;i<pasd_len;i++,n++)
  572.                         temp_buf[n]=password[i];
  573.                         temp_buf[n]='"';
  574.                 }
  575.             }while(have_smartlink==0); //此循環(huán)完成SMARTLINK 的配置

  576.                 LED1=1;
  577.                 LED2=1;
  578.                 LED3=1;
  579.             //////////////////////////////////////////////////////////下面的語句獲得模塊的設(shè)備ID/////////////////////////////////////////////////////////////
  580.         a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  581.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  582.         str_len_limt=16;          //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  583.         str_len_num=12;           //要過濾的字符個數(shù) +CSYSID:CHIP: 為下一個字符留個位置: 因此是12個字符
  584.         str_ref=':';                          // 要過濾到的字符
  585.                 uart_rec_sta=uart_rec_csysid;
  586.                 at_uart_send_str(AT_CSYSID); //返回如下:+CSYSID:CHIP:00FE6738;FLASH:001640EF;KEY:81C2B3B8;
  587.                 Delay2(2000);                                 //延時兩秒后,串口中必定輸出 所需要的器件ID FLASH ID 和KEY
  588.                 if(have_id)
  589.                 {
  590.                 have_id=0;
  591.                 k=0;
  592.                 for(i=0,tt=0;i<8;i++,tt++)        //  獲取模塊內(nèi)部的芯片ID                          
  593.                 chip_id[tt]=recd_buf[i];
  594.                 for(i=15,tt=0;i<23;i++,tt++)//  獲取模塊內(nèi)部的FLASH ID
  595.                 flash_id[tt]=recd_buf[i];
  596.                 for(i=28,tt=0;i<36;i++,tt++)//  獲取模塊內(nèi)部的KEY
  597.                 pass_id[tt]=recd_buf[i];
  598.         //將獲取的16進(jìn)制字符換成 16進(jìn)制數(shù)據(jù),8個字節(jié)的字符最總得到四個字節(jié)的16進(jìn)制數(shù)據(jù) 比如字符串"A2345678"最終變成0XA2,0X34,0X56,0X78 四個字節(jié)存放
  599.             for(i=0;i<8;i++)            
  600.             {
  601.                           if((chip_id[i]>='A')&&(chip_id[i]<='F'))
  602.                           chip_id[i]=(chip_id[i]-'A'+10);
  603.                           else if((chip_id[i]>='a')&&(chip_id[i]<='f'))
  604.               chip_id[i]=(chip_id[i]-'a'+10);
  605.                           else
  606.                           chip_id[i]-='0';
  607.             }
  608.                                
  609.                 for(i=0;i<8;i++)
  610.             esp_dev_id[i]=0;

  611.                 esp_dev_id[7]=((chip_id[6])<<4)+chip_id[7];// 將字符串16進(jìn)制轉(zhuǎn)換后,變成16進(jìn)制數(shù)據(jù)四個字節(jié)存放到對應(yīng)內(nèi)存中
  612.                 esp_dev_id[6]=((chip_id[4])<<4)+chip_id[5];
  613.                 esp_dev_id[5]=((chip_id[2])<<4)+chip_id[3];
  614.                 esp_dev_id[4]=((chip_id[0])<<4)+chip_id[1];
  615.                 //將獲取的16進(jìn)制字符換成 16進(jìn)制數(shù)據(jù),8個字節(jié)的字符最總得到四個字節(jié)的16進(jìn)制數(shù)據(jù) 比如字符串"A2345678"最終變成0XA2,0X34,0X56,0X78 四個字節(jié)存放
  616.             for(i=0;i<8;i++)
  617.             {
  618.                           if((pass_id[i]>='A')&&(pass_id[i]<='F'))
  619.                           pass_id[i]=(pass_id[i]-'A'+10);
  620.                           else if((pass_id[i]>='a')&&(pass_id[i]<='f'))
  621.               pass_id[i]=(pass_id[i]-'a'+10);
  622.                           else
  623.                           pass_id[i]-='0';
  624.             }
  625.                 for(i=0;i<8;i++)
  626.                 flash_id[i]=0;

  627.                 flash_id[7]=((pass_id[6])<<4)+pass_id[7];// 將字符串16進(jìn)制轉(zhuǎn)換后,變成16進(jìn)制數(shù)據(jù)四個字節(jié)存放到對應(yīng)內(nèi)存中
  628.                 flash_id[6]=((pass_id[4])<<4)+pass_id[5];
  629.                 flash_id[5]=((pass_id[2])<<4)+pass_id[3];
  630.                 flash_id[4]=((pass_id[0])<<4)+pass_id[1];

  631.                 for(i=0;i<8;i++)
  632.             esp_user_data[i]=flash_id[i];

  633.                 // 以上操作將模塊輸出的內(nèi)部字符串形式的芯片ID 和KEY (都是4個字節(jié)的)換成16進(jìn)制 存放到內(nèi)存中,在登錄服務(wù)器的時候的兩個必要參數(shù)。
  634.                 //////////////////////////////////////////////////////////上面的語句獲得模塊的設(shè)備ID和KEY/////////////////////////////////////////////////////////////
  635.                 }
  636.                 //while(1);
  637.                 //////////////////////////////////////////////////////////下面的語句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////

  638.                 a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  639.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  640.         str_len_limt=16;          //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  641.         str_len_num=7;            //字符個數(shù)
  642.         str_ref='"';
  643.                 uart_rec_sta=uart_rec_bander;

  644.                 Delay2(2000);
  645.         at_uart_send_str(AT_MODE);
  646.                 Delay2(2000);
  647.         at_uart_send_str(temp_buf);
  648.                 Delay2(10000);
  649.                 at_uart_send_str(AT_CIPMUX);
  650.                 Delay2(2000);
  651.         at_uart_send_str(CIPSTART);              //用UDP方式連接到安信可的云,連接到目標(biāo)5001安信可云服務(wù),順便監(jiān)聽 2468 端口,
  652.                 Delay2(2000);
  653.                
  654.                 do
  655.                 {
  656.                 LED1=0;
  657.                 LED2=0;
  658.                 LED3=0;
  659.                 Delay2(200);
  660.                 LED1=1;
  661.                 LED2=1;
  662.                 LED3=1;
  663.                 Delay2(200);
  664.                
  665.                 if(have_bander)
  666.                 {
  667.                   ;
  668.                 }

  669.                  }while(have_bander==0);        //監(jiān)聽局域網(wǎng)內(nèi)手機向2468端口(2468端口和連接4綁定) 發(fā)出的UDP掃描信息,獲得RPL:"192.168.1.10","48008"  手機透露自己的IP和端口
  670.                  
  671.                  make_AT_CIP3();                                   //根據(jù)上邊 在2468 端口監(jiān)聽到的 廣播內(nèi)容 新建一個3連接,AT+CIPSTART=3,"UDP","192.168.1.10",48008,2469,0
  672.                  at_uart_send_str(temp_buf);
  673.                  Delay2(2000);
  674.                  make_bander_data();                    //從綁定手機和設(shè)備關(guān)系的處理中,在串口輸出緩沖區(qū)得到
  675.                  at_uart_send_str(CIP3SEND_LEN);
  676.                  Delay2(1000);
  677.                  at_uart_send_str(temp_buf);
  678.                  Delay2(2000);
  679.                 //////////////////////////////////////////////////////////上面面的語句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////
  680.                 at_uart_send_str(AT_MODE);
  681.                 a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  682.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  683.         str_len_limt=12;          //設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  684.         str_len_num=5;            //字符個數(shù)
  685.         str_ref=':';
  686.                 uart_rec_sta=uart_rec_tcp_udp_data;

  687.                 make_send_pack(0,esp_dev_id,esp_TOK_id,esp_user_data,8);//構(gòu)造登錄數(shù)據(jù)包
  688.                 make_AT_SEND(need_seed_len);                            //將要進(jìn)過WIFI發(fā)送的總字節(jié)數(shù)變成10進(jìn)制,動態(tài)生成發(fā)送數(shù)據(jù)AT指令
  689.                 two_lab=0;                                                                                                ////////////////////////////////////////////////////////////////////兩個55計數(shù)!有可能錯亂
  690.         at_uart_send_str(at_send_len_ox);                       //將構(gòu)造好的AT發(fā)送數(shù)據(jù)到互聯(lián)網(wǎng)的動態(tài)發(fā)送數(shù)據(jù)長度
  691.                 Delay2(2000);

  692.        
  693.                 /*
  694.                  for(z=0;z<8;z++)
  695.                 {
  696.                 SBUF='0';
  697.                 Delay2(1);
  698.                 }

  699.                 for(z=0;z<1;z++)
  700.                 {
  701.                 SBUF=need_seed_len;
  702.                 Delay2(1);
  703.                 }

  704.                 for(z=0;z<8;z++)
  705.                 {
  706.                 SBUF='0';
  707.                 Delay2(1);
  708.                 }
  709.                 while(1);
  710.                 */
  711.                 at_uart_send_buf(temp_buf,need_seed_len);                                //經(jīng)過WIFI模塊發(fā)送構(gòu)造好的登錄包
  712.                 Delay2(4000);

  713.                 //while(1);

  714.                 while(1)
  715.                 {
  716.                         for(tt=0;tt<60;tt++)
  717.                         {
  718.                         Delay2(200);
  719.                         if(0)
  720.                         {
  721.                         have_data=0;
  722.                         for(z=0;z<8;z++)
  723.                         {
  724.                         SBUF='0';
  725.                         Delay2(1);
  726.                         }
  727.        
  728.                         for(z=0;z<40;z++)
  729.                         {
  730.                         SBUF=recd_buf[z];
  731.                         Delay2(1);
  732.                         }
  733.        
  734.                         for(z=0;z<8;z++)
  735.                         {
  736.                         SBUF='0';
  737.                         Delay2(1);
  738.                         }
  739.                     }
  740.                         Delay2(200);
  741.                    }
  742.                     make_send_pack(1,esp_dev_id,toke,temp_cd,10);    //構(gòu)造上傳數(shù)據(jù)到云,轉(zhuǎn)給手機的溫度數(shù)據(jù)包,符合基本數(shù)據(jù)格式
  743.                     make_AT_SEND(need_seed_len);                                          //動態(tài)構(gòu)造發(fā)送AT指令
  744.                         at_uart_send_str(at_send_len_ox);                //發(fā)送構(gòu)造好的發(fā)送指令
  745.                     Delay2(2000);
  746.                     at_uart_send_buf(temp_buf,need_seed_len);             //經(jīng)過WIFI發(fā)送數(shù)據(jù)

  747.                         LED2=0;
  748.                         BEEP=1;
  749.                         Delay2(200);
  750.                     LED2=1;
  751.                         BEEP=0;      //閃亮心跳指示燈,和心跳音
  752.                                                                                                                         //每30秒會運行到這里一次。更新一次溫度數(shù)值
  753.                         time++;
  754.                         temp_cd[5]=(((time%1000)/100)+'0');
  755.                         temp_cd[6]=(((time%100)/10)+'0');
  756.                     temp_cd[7]=(((time%10))+'0');
  757.                 }
  758.         }
  759.         Delay2(2000);
  760. }

  761. /********************* 字符串過濾函數(shù)初始參數(shù)************************/
  762. /*
  763. bit a_vec=0;                          //出現(xiàn)指定的字串,并動態(tài)過濾到指定的字符后 置1
  764. unsigned char ceng=0;         //最多 多少字節(jié)內(nèi) 會出現(xiàn)指定字串,靜態(tài)變量,
  765. unsigned char str_len_limt=12;//設(shè)置一個限定參考數(shù)值,在這個參考個數(shù)內(nèi)必定出現(xiàn)指定字符串
  766. unsigned char str_len_num=5;  //字符個數(shù)
  767. char str_ref=':';
  768. code char test_code[]="+IPD,";
  769. */

  770. void fit_stb(unsigned char *str_p) // 每次串口接收到一個字符都會進(jìn)入本過濾函數(shù),看是否過濾到指定的字符串。
  771. {
  772.    if((a_vec==0)&&(ceng<str_len_limt))
  773.    {
  774.       if(ceng<str_len_num)
  775.           {
  776.       if(SBUF==(*(str_p+ceng)))
  777.           ceng++;
  778.           else
  779.           ceng=0;
  780.           }
  781.           else
  782.           {
  783.                 ceng++;
  784.                 if(SBUF==str_ref)
  785.                 {
  786.                   a_vec=1;
  787.                   ceng=0;       
  788.                 }
  789.           }
  790.           RX1_Cnt=0;
  791.    }
  792.    else if(ceng>=str_len_limt)
  793.    {
  794.                a_vec=0;
  795.                   ceng=0;
  796.    }
  797. }

  798. //unsigned char
  799. void UART1_int (void) interrupt UART1_VECTOR
  800. {
  801.         if(RI)
  802.         {
  803.                 RI = 0;
  804.                 if(a_vec==0)//上次未曾過濾到指定的字符串中所有的字符出現(xiàn),每次只過濾一個字符
  805.                 {
  806.                  switch(uart_rec_sta)              //根據(jù)系統(tǒng)的狀態(tài),決定過濾哪個字符
  807.                  {
  808.                   case uart_rec_tcp_udp_data: //串口進(jìn)入正常的UDP TCP 數(shù)據(jù)收發(fā)
  809.                   fit_stb(PIPD_code);                  //過濾數(shù)據(jù)接收頭
  810.                   break;
  811.                   case  uart_rec_csysid:          //串口進(jìn)入獲得模塊內(nèi)部ID 和KEY 狀態(tài)
  812.                   fit_stb(CYSYS_code);              //過濾指定的頭部
  813.                   break;
  814.                   case uart_rec_smartlink:          //串口進(jìn)入獲得客戶的路由器賬戶密碼狀態(tài)
  815.                   fit_stb(smartlink_code);
  816.                   break;
  817.                   case uart_rec_bander:
  818.                   fit_stb(bander_code);
  819.                  }
  820.                 }
  821.                 else//////////////////////////////過濾到指定的頭部
  822.                 {
  823.                
  824.                  recd_buf[RX1_Cnt] = SBUF;                //保存一個字節(jié)
  825.                  if(recd_buf[RX1_Cnt]==0X55)    //記錄0X55的個數(shù),出現(xiàn)兩次后,代表一個有數(shù)據(jù)包結(jié)束
  826.                  two_lab++;
  827.                  if(RX1_Cnt<62)        /////////////////////防止64字節(jié)的緩沖區(qū)溢出
  828.                  RX1_Cnt++;
  829.                  else                        ///////每次收到的指令超過64字節(jié),就把數(shù)據(jù)清空,接收指針指向開頭
  830.                  {
  831.                    RX1_Cnt=0;
  832.                    a_vec=0;
  833.                    two_lab=0;
  834.                  }
  835.                  switch(uart_rec_sta)
  836.                   {
  837.                     case uart_rec_tcp_udp_data:
  838.                         //have_dd=1;
  839.                            //LED2=0;
  840.                                 if(two_lab==2)//////////////////////////////////////////得到一包有效的數(shù)據(jù)!取出2個OX55之間的有效數(shù)據(jù)////////////////////
  841.                                  {
  842.                                    a_vec=0;
  843.                                    rec_len=RX1_Cnt;
  844.                                    two_lab=0;
  845.                                    RX1_Cnt=0;
  846.                    LED1=0;
  847.                                    LED2=0;
  848.                                    LED3=0;

  849.                                    change_pack();
  850.                                    have_data=1;
  851.                                     if((recd_buf[32])==':')              /////////////////////////////////////簡單得到手機的開關(guān)指令////////////////////
  852.                                         {
  853.                                          if((recd_buf[33])=='0')
  854.                                          {
  855.                                           DK1=0;
  856.                                           LED1=1;          //關(guān)燈指令
  857.                                          }
  858.                                          else if((recd_buf[33])=='1')
  859.                                          {
  860.                                           DK1=1;
  861.                                       LED1=0;    //開燈指令
  862.                                          }
  863.                                         }
  864.                                         if((recd_buf[3]==0xa0)&&(recd_buf[9]==0x00)&&(have_tok==0))////////////////////獲得TOKE包//////////////////////////////////
  865.                                         {
  866.                                           have_tok=1;
  867.                                           toke[7]=recd_buf[19];             
  868.                                           toke[6]=recd_buf[20];               
  869.                                           toke[5]=recd_buf[21];       
  870.                                           toke[4]=recd_buf[22];                 
  871.                                           toke[3]=recd_buf[23];
  872.                                           toke[2]=recd_buf[24];
  873.                                           toke[1]=recd_buf[25];
  874.                                           toke[0]=recd_buf[26];

  875.                                         }
  876.                                  }
  877.                         break;
  878.                    case  uart_rec_csysid:
  879.                    if(RX1_Cnt>40)
  880.                    have_id=1;
  881.                    break;
  882.                    case  uart_rec_smartlink:
  883.                    if(RX1_Cnt>10)
  884.                    have_smartlink=1;
  885.                    break;
  886.                    case  uart_rec_bander:
  887.                    if(RX1_Cnt>20)
  888.                    have_bander=1;
  889.                    break;
  890.                  };
  891.           }
  892.         }
  893.         if(TI)
  894.         {
  895.                 TI = 0;
  896.                 B_TX1_Busy = 0;                //清除發(fā)送忙標(biāo)志
  897.         }
  898. }
復(fù)制代碼


  1. /*************        本地常量聲明        **************/
  2. #define MAIN_Fosc                22118400L        //定義主時鐘
  3. #define        RX1_Lenth                32                        //串口接收緩沖長度
  4. #define        BaudRate1                115200UL        //選擇波特率
  5. #define        Timer1_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 1 重裝值, 對應(yīng)300KHZ
  6. #define        Timer2_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 2 重裝值, 對應(yīng)300KHZ
  7. #include        "STC15Fxxxx.H"
  8. /*************        本地變量聲明        **************/
  9. u8        idata RX1_Buffer[RX1_Lenth];        //接收緩沖
  10. u8        TX1_Cnt;        //發(fā)送計數(shù)
  11. u8        RX1_Cnt;        //接收計數(shù)
  12. bit        B_TX1_Busy;        //發(fā)送忙標(biāo)志
  13. /*************        端口引腳定義        **************/
  14. unsigned char two_lab=0;
  15. sbit LED1=P1^0;//LED1
  16. sbit LED2=P1^1;//LED2
  17. sbit LED3=P3^7;//LED3
  18. sbit DK1=P3^3;//繼電器
  19. sbit BEEP=P3^4;//蜂鳴器
  20. sbit K1=P1^3;//按鍵1
  21. sbit K2=P1^2;//按鍵2
  22. sbit K3=P1^4;//按鍵3
  23. #define O_PF    0X00  //包頭1字節(jié)固定0X55
  24. #define O_LEN_L 0X01  //整個包長低字節(jié)
  25. #define O_LEN_H 0X02  //整個包長高字節(jié) 注意轉(zhuǎn)義碼 兩個這里只計算一個數(shù)據(jù)處理!
  26. #define O_CMD_T 0X03  //命令類型
  27. #define O_CMD_C 0X04  //具體命令
  28. #define O_CIX_L 0X05  //本命令序列編號低字節(jié)
  29. #define O_CIX_H 0X06  //本命令序列編號高字節(jié)
  30. #define O_EXMSH 0X07  //擴展信息高字節(jié)
  31. #define O_EXMSL 0X08  //擴展信息低字節(jié)
  32. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請求 未知
  33. #define O_DEVID 0x0A  //8字節(jié)設(shè)備識別
  34.    //1 BYTS TL_LEN          //獲得的設(shè)備臨時通訊令牌長度
  35.    //N BYTS TK                   //TL_LEN個通訊令牌串
  36.    //N BYTS DATAS          //客戶的數(shù)據(jù)包串
  37.    //CRC_L    1BYTE          //CRC16 低字節(jié)
  38.    //CRC_H    1BYTE          //CRC16 高字節(jié)
  39.    //PACK_END 1BYTE          //包尾1字節(jié)固定0X55

  40. //

  41. char led1bl,led2bl,led3bl;
  42. code unsigned char AT_RST[]="AT+RST";
  43. code unsigned char AT_MODE[]="AT+CWMODE=3";
  44. code unsigned char AT_CWJAP[]="AT+CWJAP=\"360we\",\"zty0012001\"";
  45. code unsigned char CIPSTART[]="AT+CIPSTART=\"UDP\",\"cloud.ai-thinker.com\",5001";
  46. code unsigned char CIPSEND_LEN[]="AT+CIPSEND=4,38";
  47. unsigned char at_send_len_ox[16];
  48. unsigned char test_buff[38]={0x55,0x26,0x00,0xA0,0x00,0xA8,0x16,0x16,0xA8,0x02,0xE6,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0xE6,0xBD,0x5B,0x55};
  49. data unsigned char send_buf[64];
  50. pdata unsigned char recd_buf[64];
  51. unsigned char temp_buf[64];

  52. unsigned char toke[8]={0,0,0,0,0,0,0,0,};
  53. code unsigned int crc_table[256]=
  54. {               /* CRC余式表 */
  55. 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
  56. 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
  57. 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
  58. 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
  59. 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
  60. 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
  61. 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
  62. 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
  63. 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
  64. 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
  65. 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
  66. 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
  67. 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
  68. 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
  69. 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
  70. 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
  71. 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
  72. 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
  73. 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
  74. 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
  75. 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
  76. 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
  77. 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
  78. 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
  79. 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
  80. 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
  81. 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
  82. 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
  83. 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
  84. 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
  85. 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
  86. 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
  87. };
  88. bit t_o=0;
  89. void make_AT_SEND(unsigned char a_len)
  90. {
  91.   unsigned char aa=0;
  92.   for(aa=0;aa<11;aa++)
  93.   {
  94.     at_send_len_ox[aa]=CIPSEND_LEN[aa];
  95.   }
  96.   t_o=0;
  97.   if((a_len/100))
  98.   {
  99.   at_send_len_ox[aa]=a_len/100+'0';
  100.   aa++;
  101.   t_o=1;
  102.   }
  103.   if((a_len%100)/10)
  104.   {
  105.   at_send_len_ox[aa]=(a_len%100)/10+'0';
  106.   aa++;
  107.   t_o=1;
  108.   }
  109.   else if(t_o)
  110.   {
  111.     at_send_len_ox[aa]=0+'0';
  112.         aa++;
  113.   }
  114.   at_send_len_ox[aa]=(a_len%10)+'0';
  115.   aa++;
  116.   at_send_len_ox[aa]=0;
  117. }
  118. unsigned int GetRevCrc_16(unsigned char * pData, int nLength)
  119. {
  120.   unsigned int cRc_16 = 0xffff;
  121.   unsigned char temp;

  122.   while(nLength-- > 0)
  123.   {
  124.     temp = cRc_16&0xff;
  125.     cRc_16 = (cRc_16 >> 8) ^ crc_table[(temp ^ *pData++) & 0xFF];
  126.   }

  127.   return cRc_16;   
  128. }
  129. #define O_PF    0X00  //包頭1字節(jié)固定0X55
  130. #define O_LEN_L 0X01  //整個包長低字節(jié)
  131. #define O_LEN_H 0X02  //整個包長高字節(jié) 注意轉(zhuǎn)義碼 兩個這里只計算一個數(shù)據(jù)處理!
  132. #define O_CMD_T 0X03  //命令類型
  133. #define O_CMD_C 0X04  //具體命令
  134. #define O_CIX_L 0X05  //本命令序列編號低字節(jié)
  135. #define O_CIX_H 0X06  //本命令序列編號高字節(jié)
  136. #define O_EXMSH 0X07  //擴展信息高字節(jié)
  137. #define O_EXMSL 0X08  //擴展信息低字節(jié)
  138. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請求 未知
  139. #define O_DEVID_START 0x0A  //8字節(jié)設(shè)備識別  低字節(jié)在前
  140. #define O_TK_LEN      0X12 //1 BYTS TL_LEN          //獲得的設(shè)備臨時通訊令牌長度
  141. #define O_TOKE_START  0X13
  142. #define O_DATAS_START 0X1B
  143.    //N BYTS DATAS          //客戶的數(shù)據(jù)包串
  144.    //CRC_L    1BYTE          //CRC16 低字節(jié)
  145.    //CRC_H    1BYTE          //CRC16 高字節(jié)
  146.    //PACK_END 1BYTE          //包尾1字節(jié)固定0X55
  147. unsigned char esp_dev_id[8]={0,0,0,0,0,0,0X1E,0XE6};
  148. unsigned char esp_TOK_id[8]={0,0,0,0,0,0,0,0};
  149. unsigned char esp_user_data[8]={0,0,0,0,0,0,0X1E,0XE6};
  150. unsigned char need_seed_len=0;
  151. void make_send_pack(unsigned char ms_opt,unsigned char *dev_id,unsigned char *toke_id,unsigned char *use_data,unsigned char use_data_len)
  152. {
  153.   unsigned char a,b,i=0;
  154.   unsigned esp_crc=0;
  155.   send_buf[0]=0x55;

  156.   send_buf[O_LEN_L]=(O_DATAS_START+use_data_len+3)%0xff;
  157.   send_buf[O_LEN_H]=(O_DATAS_START+use_data_len+3)/0xff;

  158.   send_buf[O_CMD_T]=0XA0;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實時檢測指令 0XF0 終端操作
  159.   send_buf[O_CMD_C]=0X00;// reg  option
  160.   send_buf[O_CIX_L]=0XA8;// CMD INDEXL
  161.   send_buf[O_CIX_H]=0X16;//        CMD INDEXL
  162.   send_buf[O_EXMSH]=0X16;//        EXTERN MESSAGE1
  163.   send_buf[O_EXMSL]=0XA8;//        EXTERN MESSAGE2
  164.   send_buf[O_RESTA]=0X02;//        CMD_STA 00 OK 01 FAIL 02 SEND 03 NO SUP

  165.   for(i=0;i<8;i++)
  166.   send_buf[O_DEVID+i]=*(dev_id+(7-i));

  167.   send_buf[O_TK_LEN] =8;
  168.   for(i=0;i<8;i++)
  169.   send_buf[O_TOKE_START+i]=*(toke_id+i);

  170.   for(i=0;i<use_data_len;i++)
  171.   send_buf[O_DATAS_START+i]=*(use_data+i); // 數(shù)據(jù)區(qū),登錄的時候放數(shù)據(jù)密碼文本

  172.   temp_buf[0]=0x55;
  173.   for(a=1,b=1;a<(O_DATAS_START+use_data_len);a++)
  174.   {
  175.     if(send_buf[a]==0x55)
  176.         {
  177.           temp_buf[b]=0x54;
  178.           b+=1;
  179.           temp_buf[b]=0x01;
  180.           b+=1;
  181.         }
  182.         else if(send_buf[a]==0x54)
  183.         {
  184.           temp_buf[b]=0x54;
  185.           b+=1;
  186.           temp_buf[b]=0x02;
  187.           b+=1;
  188.         }
  189.         else
  190.         {
  191.         temp_buf[b]=send_buf[a];
  192.         b+=1;
  193.         }
  194. }
  195. esp_crc=GetRevCrc_16(temp_buf,O_DATAS_START+use_data_len);
  196. temp_buf[b]=(esp_crc>>8);
  197. b+=1;
  198. temp_buf[b]=(esp_crc&0x00ff);         
  199. b+=1;
  200. temp_buf[b]=0x55;
  201. b+=1;
  202. need_seed_len=b;
  203. }
  204. bit have_data=0;
  205. unsigned char rec_len=0;
  206. void Delay1(unsigned long ms)
  207. {
  208.         unsigned char i, j,k;
  209.         for(k=0;k<ms;k++)
  210.         {
  211.                 _nop_();
  212.                 _nop_();
  213.                 i = 22;
  214.                 j = 128;
  215.                 do
  216.                 {
  217.                         while (--j);
  218.                 } while (--i);
  219.         }
  220. }
  221. void Delay2(unsigned long cnt)
  222. {
  223.         long i;
  224.         for(i=0;i<cnt*100;i++);
  225. }
  226. void at_uart_send_str(unsigned char *str)
  227. {
  228.   unsigned char *st_p=str;
  229.   do{
  230.      SBUF=*st_p;
  231.          st_p++;
  232.          Delay1(1);
  233.         }while(*st_p);
  234.         SBUF='\r';
  235.         Delay1(1);
  236.         SBUF='\n';
  237.         Delay1(1);
  238. }
  239. void at_uart_send_buf(unsigned char *str,unsigned char len)
  240. {
  241.   unsigned char *st_p=str;
  242.   
  243.   while(len){
  244.      SBUF=*st_p;
  245.          st_p++;
  246.          Delay1(1);
  247.          len--;
  248.         }while(*st_p);
  249.         SBUF='\r';
  250.         Delay1(1);
  251.         SBUF='\n';
  252.         Delay1(1);
  253. }
  254. void main(void)
  255. {
  256.         char i=0;;
  257.         B_TX1_Busy = 0;
  258.         RX1_Cnt = 0;
  259.         TX1_Cnt = 0;
  260.         S1_8bit();                                //8位數(shù)據(jù)
  261.         S1_USE_P30P31();                //UART1 使用P30 P31口        默認(rèn)
  262.         AUXR &= ~(1<<4);        //Timer stop                波特率使用Timer2產(chǎn)生
  263.         AUXR |= 0x01;                //S1 BRT Use Timer2;
  264.         AUXR |=  (1<<2);        //Timer2 set as 1T mode
  265.         TH2 = (u8)(Timer2_Reload >> 8);
  266.         TL2 = (u8)Timer2_Reload;
  267.         AUXR |=  (1<<4);        //Timer run enable
  268.         REN = 1;        //允許接收
  269.         ES  = 1;        //允許中斷
  270.         EA = 1;                //允許全局中斷
  271.         P3M1 = 0x00;
  272.     P3M0 = 0xFF;
  273.         RX1_Cnt=0;
  274.         DK1=0;
  275.         BEEP=0;
  276.         for(;;)//AT+CWMODE=2 設(shè)置成路由模式
  277.         {
  278.                 //SBUF='A';Delay1(1);


  279.                 Delay2(2000);
  280.         at_uart_send_str(AT_MODE);
  281.                 Delay2(2000);
  282.         at_uart_send_str(AT_CWJAP);
  283.                 Delay2(4000);
  284.         at_uart_send_str(CIPSTART);
  285.                 Delay2(2000);
  286.                 make_send_pack(0,esp_dev_id,esp_TOK_id,esp_user_data,8);
  287.                 make_AT_SEND(need_seed_len);                     //將要發(fā)送的總字節(jié)數(shù)變成10進(jìn)制動態(tài)修改AT發(fā)送指令           at_uart_send_str(at_send_len_ox);
  288.         at_uart_send_str(at_send_len_ox);                //動態(tài)發(fā)送數(shù)據(jù)長度
  289.                 Delay2(2000);
  290.                 at_uart_send_buf(temp_buf,need_seed_len);
  291.                 while(1)
  292.                 {
  293.                   if(have_data)
  294.                   {
  295.                     have_data=0;
  296.                         LED1=0;
  297.                         Delay2(200);
  298.                     LED1=1;
  299.                   }
  300.                 }
  301.         }
  302.         Delay2(2000);
  303. }

  304. /********************* UART1中斷函數(shù)************************/
  305. void UART1_int (void) interrupt UART1_VECTOR
  306. {
  307.         if(RI)
  308.         {
  309.                 RI = 0;
  310.                 LED1=0;
  311.                 LED1=1;
  312.                 recd_buf[RX1_Cnt] = SBUF;                //保存一個字節(jié)
  313.                 if(RX1_Cnt<62)
  314.                 RX1_Cnt++;
  315.                 else
  316.                 RX1_Cnt=0;
  317.                  if(recd_buf[RX1_Cnt]==0X55)
  318.                    two_lab++;
  319.                  if(two_lab==2)
  320.                  {
  321.                    have_data=1;
  322.                    two_lab=0;
  323.                    rec_len=RX1_Cnt;
  324.                    RX1_Cnt=0;
  325.                  }
  326.         }
  327.         if(TI)
  328.         {
  329.                 TI = 0;
  330.                 B_TX1_Busy = 0;                //清除發(fā)送忙標(biāo)志
  331.         }
  332. }
復(fù)制代碼


  1. /*************        本地常量聲明        **************/
  2. #define MAIN_Fosc                22118400L        //定義主時鐘
  3. #define        RX1_Lenth                32                        //串口接收緩沖長度
  4. #define        BaudRate1                115200UL        //選擇波特率
  5. #define        Timer1_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 1 重裝值, 對應(yīng)300KHZ
  6. #define        Timer2_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 2 重裝值, 對應(yīng)300KHZ
  7. #include        "STC15Fxxxx.H"
  8. /*************        本地變量聲明        **************/
  9. u8        idata RX1_Buffer[RX1_Lenth];        //接收緩沖
  10. u8        TX1_Cnt;        //發(fā)送計數(shù)
  11. u8        RX1_Cnt;        //接收計數(shù)
  12. bit        B_TX1_Busy;        //發(fā)送忙標(biāo)志
  13. /*************        端口引腳定義        **************/
  14. unsigned char two_lab=0;
  15. sbit LED1=P1^0;//LED1
  16. sbit LED2=P1^1;//LED2
  17. sbit LED3=P3^7;//LED3
  18. sbit DK1=P3^3;//繼電器
  19. sbit BEEP=P3^4;//蜂鳴器
  20. sbit K1=P1^3;//按鍵1
  21. sbit K2=P1^2;//按鍵2
  22. sbit K3=P1^4;//按鍵3


  23. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  24. #define O_PF    0X00  //包頭1字節(jié)固定0X55
  25. #define O_LEN_L 0X01  //整個包長低字節(jié)
  26. #define O_LEN_H 0X02  //整個包長高字節(jié) 注意轉(zhuǎn)義碼 兩個這里只計算一個數(shù)據(jù)處理!
  27. #define O_CMD_T 0X03  //命令類型
  28. #define O_CMD_C 0X04  //具體命令
  29. #define O_CIX_L 0X05  //本命令序列編號低字節(jié)
  30. #define O_CIX_H 0X06  //本命令序列編號高字節(jié)
  31. #define O_EXMSH 0X07  //擴展信息高字節(jié)
  32. #define O_EXMSL 0X08  //擴展信息低字節(jié)
  33. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請求 未知
  34. #define O_DEVID 0x0A  //8字節(jié)設(shè)備識別
  35.    //1 BYTS TL_LEN          //獲得的設(shè)備臨時通訊令牌長度
  36.    //N BYTS TK                   //TL_LEN個通訊令牌串
  37.    //N BYTS DATAS          //客戶的數(shù)據(jù)包串
  38.    //CRC_L    1BYTE          //CRC16 低字節(jié)
  39.    //CRC_H    1BYTE          //CRC16 高字節(jié)
  40.    //PACK_END 1BYTE          //包尾1字節(jié)固定0X55

  41. ////////////////////////////////////////////////////////////////////////以上定義了包中的各參數(shù)的絕對位置//////////////////////////////////

  42. char led1bl,led2bl,led3bl;

  43. code unsigned char AT_RST[]="AT+RST";                                                     
  44. code unsigned char AT_MODE[]="AT+CWMODE=3";
  45. code unsigned char AT_CWJAP[]="AT+CWJAP=\"360we\",\"zty0012001\"";
  46. code unsigned char CIPSTART[]="AT+CIPSTART=\"UDP\",\"cloud.ai-thinker.com\",5001";
  47. //////////////////////////////////////////////////////////////////////以上部分發(fā)送指令讓單片機連入內(nèi)部網(wǎng)絡(luò)////////////////////////////////
  48. code unsigned char CIPSEND_LEN[]="AT+CIPSEND=38";//AT指令發(fā)送數(shù)據(jù)38字節(jié)的數(shù)據(jù)到網(wǎng)絡(luò)上//////////////////////
  49. unsigned char at_send_len_ox[16];                //上面一條指令只能發(fā)送38的靜態(tài)包長,這里用個RAM存儲上邊CODE的AT指令"AT+CIPSEND=38"可以修改后面的38,為任意數(shù)
  50. unsigned char send_buf[64];                             //發(fā)送緩沖區(qū)
  51. unsigned char recd_buf[64];                                                 //接收緩沖區(qū)
  52. data unsigned char temp_buf[64];                                 //加工緩沖區(qū)
  53. unsigned char toke[8]={0x24,0x41,0xD6,0x39,0x48,0x83,0xAC,0x00};//此設(shè)備在服務(wù)器上獲得的令牌包

  54. /////////////////////////////////////////////////////////////////下面部分定義了CRC16校驗函數(shù)用到的表格///////////////////////////////////
  55. code unsigned int crc_table[256]=
  56. {               /* CRC余式表 */
  57. 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
  58. 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
  59. 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
  60. 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
  61. 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
  62. 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
  63. 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
  64. 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
  65. 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
  66. 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
  67. 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
  68. 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
  69. 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
  70. 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
  71. 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
  72. 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
  73. 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
  74. 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
  75. 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
  76. 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
  77. 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
  78. 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
  79. 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
  80. 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
  81. 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
  82. 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
  83. 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
  84. 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
  85. 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
  86. 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
  87. 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
  88. 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
  89. };
  90. /////////////////////////////////////////////////////////////////上面部分定義了CRC16校驗函數(shù)用到的表格///////////////////////////////////
  91. bit t_o=0;
  92. void make_AT_SEND(unsigned char a_len)//生成右邊這樣的指令,將參數(shù)a_len 改成10進(jìn)制  "AT+CIPSEND=38"
  93. {
  94.   unsigned char aa=0;
  95.   for(aa=0;aa<11;aa++)
  96.   {
  97.     at_send_len_ox[aa]=CIPSEND_LEN[aa];         //剪貼"AT+CIPSEND= 到RAM  后面的十進(jìn)制參數(shù)由下面的部分生成
  98.   }
  99.   t_o=0;                                 //去掉前面的0,比如發(fā)送38個字節(jié),038,前面的0就可以去掉了。
  100.   if((a_len/100))
  101.   {
  102.   at_send_len_ox[aa]=a_len/100+'0';
  103.   aa++;
  104.   t_o=1;
  105.   }
  106.   if((a_len%100)/10)
  107.   {
  108.   at_send_len_ox[aa]=(a_len%100)/10+'0';
  109.   aa++;
  110.   t_o=1;
  111.   }
  112.   else if(t_o)
  113.   {
  114.     at_send_len_ox[aa]=0+'0';
  115.         aa++;
  116.   }
  117.   at_send_len_ox[aa]=(a_len%10)+'0';
  118.   aa++;
  119.   at_send_len_ox[aa]=0;
  120. }
  121. //下面函數(shù)獲得CRC校驗碼 采用標(biāo)準(zhǔn)CRC16 初始CRC=0XFFFF  運算多項式參數(shù) 8005 非1021
  122. unsigned int GetRevCrc_16(unsigned char * pData, int nLength)
  123. {
  124.   unsigned int cRc_16 = 0xffff;
  125.   unsigned char temp;

  126.   while(nLength-- > 0)
  127.   {
  128.     temp = cRc_16&0xff;
  129.     cRc_16 = (cRc_16 >> 8) ^ crc_table[(temp ^ *pData++) & 0xFF];
  130.   }

  131.   return cRc_16;   
  132. }

  133. #define O_PF    0X00  //包頭1字節(jié)固定0X55
  134. #define O_LEN_L 0X01  //整個包長低字節(jié)
  135. #define O_LEN_H 0X02  //整個包長高字節(jié) 注意轉(zhuǎn)義碼 兩個這里只計算一個數(shù)據(jù)處理!
  136. #define O_CMD_T 0X03  //命令類型
  137. #define O_CMD_C 0X04  //具體命令
  138. #define O_CIX_L 0X05  //本命令序列編號低字節(jié)
  139. #define O_CIX_H 0X06  //本命令序列編號高字節(jié)
  140. #define O_EXMSH 0X07  //擴展信息高字節(jié)
  141. #define O_EXMSL 0X08  //擴展信息低字節(jié)
  142. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請求 未知
  143. #define O_DEVID_START 0x0A  //8字節(jié)設(shè)備識別  低字節(jié)在前
  144. #define O_TK_LEN      0X12 //1 BYTS TL_LEN          //獲得的設(shè)備臨時通訊令牌長度
  145. #define O_TOKE_START  0X13
  146. #define O_DATAS_START 0X1B
  147.    //N BYTS DATAS          //客戶的數(shù)據(jù)包串
  148.    //CRC_L    1BYTE          //CRC16 低字節(jié)
  149.    //CRC_H    1BYTE          //CRC16 高字節(jié)
  150.    //PACK_END 1BYTE          //包尾1字節(jié)固定0X55

  151. unsigned char esp_dev_id[8]={0,0,0,0,0,0,0X1E,0XE6};         //    8266的8個字節(jié)的器件ID號,可在服務(wù)器數(shù)據(jù)庫中查到,唯一標(biāo)示一個器件,登錄過程需要一個器件ID,和數(shù)據(jù)區(qū)放一個數(shù)據(jù)密碼,這么簡單登錄
  152. unsigned char esp_TOK_id[8]={0,0,0,0,0,0,0,0};                                 //    服務(wù)器分給器件器件的令牌包,另外個地方也定義了,完全可以用一個數(shù)組完成的
  153. unsigned char esp_user_data[14]={0,0,0,0,0,0,0X1E,0XE6};         //    客戶的凈數(shù)據(jù)負(fù)荷區(qū),可以很大,因為本款單片機有限,并且一般控制信號,定義幾個字節(jié)夠了!注意在登錄的時候,這里是器件密碼!
  154. unsigned char temp_cd[]="TEMP:123;";                                                 //    一個數(shù)據(jù)包,前面是包格式定義,后面是客戶數(shù)據(jù)區(qū),這里定義一個即將要發(fā)送的溫度數(shù)據(jù)
  155. unsigned char need_seed_len=0;                                                                 //    全局變量,本次總共需要發(fā)到串口的數(shù)據(jù)


  156. //下面這個函數(shù)構(gòu)造一個發(fā)送的數(shù)據(jù)格式,請看數(shù)據(jù)格式文檔,完全可以用結(jié)構(gòu)體完成,這里采用數(shù)據(jù),從上到下描述這個數(shù)據(jù)包
  157. //發(fā)送的數(shù)據(jù)包,目前只有登錄數(shù)據(jù)包,和上報溫度數(shù)據(jù)包,這兩個基本的數(shù)據(jù)包,上報數(shù)據(jù)包可以充當(dāng)心跳包,第一個參數(shù)決定著,是發(fā)送登錄包還是溫度包
  158. //其他幾個入口參數(shù)是器件ID,令牌包,以及客戶的數(shù)據(jù),以及客戶數(shù)據(jù)長度

  159. void make_send_pack(unsigned char ms_opt,unsigned char *dev_id,unsigned char *toke_id,unsigned char *use_data,unsigned char use_data_len)
  160. {
  161.   unsigned char a,b,i=0;
  162.   unsigned esp_crc=0;
  163.   send_buf[0]=0x55;                                                     //包頭是0X55固定
  164.   
  165.   send_buf[O_LEN_L]=(O_DATAS_START+use_data_len+3)%0xff; //本數(shù)據(jù)包的所有數(shù)據(jù)長度,包頭至包尾,記得是沒有經(jīng)過轉(zhuǎn)義前的包長
  166.   send_buf[O_LEN_H]=(O_DATAS_START+use_data_len+3)/0xff;

  167.   if(ms_opt==0)                                                                                         //根據(jù)入口參數(shù)判斷是發(fā)送登錄鏈路操作,還是發(fā)送數(shù)據(jù)包云平臺
  168.   send_buf[O_CMD_T]=0XA0;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實時檢測指令 0XF0 終端操作
  169.   else if (ms_opt==1)
  170.   send_buf[O_CMD_T]=0XAA;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實時檢測指令 0XF0 終端操作

  171.   if(ms_opt==0)                                                                //0X00代表登錄操作
  172.   send_buf[O_CMD_C]=0X00;// reg  option
  173.   else if (ms_opt==1)
  174.   send_buf[O_CMD_C]=0XEE;                                                    //0XEE代表數(shù)據(jù)是從設(shè)備到云平臺的方向

  175.   send_buf[O_CIX_L]=0XF3;// CMD INDEXL                        //命令序列編號,暫時不用,可以作為對方應(yīng)答的數(shù)據(jù)包號標(biāo)示
  176.   send_buf[O_CIX_H]=0XC0;//        CMD INDEXL                                        //命令序列編號,暫時不用,可以作為對方應(yīng)答的數(shù)據(jù)包號標(biāo)示
  177.   send_buf[O_EXMSH]=0XC0;//        EXTERN MESSAGE1                                //擴展子暫時保留
  178.   send_buf[O_EXMSL]=0XF3;//        EXTERN MESSAGE2                                //擴展子暫時保留

  179.   send_buf[O_RESTA]=0X02;//        CMD_STA 00 OK 01 FAIL 02 SEND 03 NO SUP         //代表本數(shù)據(jù)包的狀態(tài),是發(fā)送還是應(yīng)答成功還是失敗

  180.   for(i=0;i<8;i++)
  181.   send_buf[O_DEVID+i]=*(dev_id+(7-i)); // 拷貝設(shè)備的唯一ID號到數(shù)據(jù)包里


  182.   send_buf[O_TK_LEN] =8;                   //代表接下來的令牌包是8個字節(jié)


  183.   for(i=0;i<8;i++)
  184.   send_buf[O_TOKE_START+i]=*(toke_id+i);//8個字節(jié)令牌包,初始令牌包為00 后續(xù)服務(wù)器會分配一個令牌包給這個設(shè)備,設(shè)備每次通訊要攜帶這個令牌包


  185.   for(i=0;i<use_data_len;i++)
  186.   send_buf[O_DATAS_START+i]=*(use_data+i); // 客戶的數(shù)據(jù)區(qū),登錄的時候放數(shù)據(jù)密碼文本
  187.   
  188.   temp_buf[0]=0x55;                                                   //包尾

  189.   esp_crc=GetRevCrc_16(send_buf,O_DATAS_START+use_data_len);//得到轉(zhuǎn)義之前的總數(shù)據(jù)包CRC,具體可以參照CRC數(shù)據(jù)格式,因此CRC是針對轉(zhuǎn)義之前的數(shù)據(jù)生成

  190.   for(a=1,b=1;a<(O_DATAS_START+use_data_len);a++)           //將出去包頭,所有的數(shù)據(jù)中含有有0X55的數(shù)據(jù)轉(zhuǎn)義成0X54,0X01,將0X54 變成0X54,02,重新轉(zhuǎn)義數(shù)據(jù)包
  191.   {
  192.     if(send_buf[a]==0x55)
  193.         {
  194.           temp_buf[b]=0x54;
  195.           b+=1;
  196.           temp_buf[b]=0x01;
  197.           b+=1;
  198.         }
  199.         else if(send_buf[a]==0x54)
  200.         {
  201.           temp_buf[b]=0x54;
  202.           b+=1;
  203.           temp_buf[b]=0x02;
  204.           b+=1;
  205.         }
  206.         else
  207.         {
  208.         temp_buf[b]=send_buf[a];
  209.         b+=1;
  210.         }
  211. }         ///////////////////////////////////////////////////////////以上的語句轉(zhuǎn)義數(shù)據(jù)包中除包頭到CRC之前的全部的數(shù)據(jù)///////////////////////////////////////////////////////////////////////
  212. //55 28 00 AA EE F3 C0 C0 F3 02 E6 1E 00 00 00 00 00 00 08 24 41 D6 39 48 83 AC 00 54 02 45 4D 50 3A 32 35 35 3B 00 D1 52 55
  213. //55 28 00 AA EE F3 C0 C0 F3 02 E6 1E 00 00 00 00 00 00 08 24 41 D6 39 48 83 AC 00 54 02 45 4D 50 3A 32 35 35 3B 00 D1 52 55

  214. temp_buf[b]=(esp_crc>>8);
  215. b+=1;
  216. temp_buf[b]=(esp_crc&0x00ff);         
  217. b+=1;
  218.     ///////////////////////////////////////////////////////////上面兩句加上CRC校驗////////////////////////////////////////
  219. temp_buf[b]=0x55;        //包尾
  220. b+=1;
  221. temp_buf[b]=0x0d;
  222. b+=1;
  223. temp_buf[b]=0x0a;
  224. b+=1;                                //以上構(gòu)成回車
  225. need_seed_len=b;        //至此構(gòu)造出了需要發(fā)送的全部數(shù)據(jù) 包括AT指令需要的換行
  226. }
  227. bit have_data=0;
  228. unsigned char rec_len=0;


  229. void Delay1(unsigned long ms)//簡單延遲函數(shù),單位是毫秒
  230. {
  231.         unsigned char i, j,k;
  232.         for(k=0;k<ms;k++)
  233.         {
  234.                 _nop_();
  235.                 _nop_();
  236.                 i = 22;
  237.                 j = 128;
  238.                 do
  239.                 {
  240.                         while (--j);
  241.                 } while (--i);
  242.         }
  243. }
  244. void Delay2(unsigned long cnt)
  245. {
  246.         long i;
  247.         for(i=0;i<cnt*100;i++);
  248. }

  249. void at_uart_send_str(unsigned char *str)//發(fā)送AT字符串到串口
  250. {
  251.   unsigned char *st_p=str;
  252.   do{
  253.      SBUF=*st_p;
  254.          st_p++;
  255.          Delay1(1);
  256.         }while(*st_p);
  257.         SBUF='\r';
  258.         Delay1(1);
  259.         SBUF='\n';
  260.         Delay1(1);
  261. }
  262. void at_uart_send_buf(unsigned char *str,unsigned char len)//發(fā)送數(shù)據(jù)緩沖區(qū)的非字符串信息,數(shù)據(jù)流信息到串口
  263. {
  264.   unsigned char *st_p=str;
  265.   
  266.   while(len){
  267.      SBUF=*st_p;
  268.          st_p++;
  269.          Delay1(1);
  270.          len--;
  271.         }while(*st_p);
  272.         SBUF='\r';
  273.         Delay1(1);
  274.         SBUF='\n';
  275.         Delay1(1);
  276. }
  277. unsigned int time=0; //每隔30秒把一個變量加1,然后把這個變量作為溫度數(shù)據(jù)上報給云平臺,轉(zhuǎn)給手機端
  278. void main(void)
  279. {
  280.         char tt,i=0;;
  281.         //////////////////////////////////////////////////////////////////////////////////////下面部分為定時器以及串口初始化/////////////////////
  282.         B_TX1_Busy = 0;
  283.         RX1_Cnt = 0;
  284.         TX1_Cnt = 0;
  285.         S1_8bit();                                //8位數(shù)據(jù)
  286.         S1_USE_P30P31();                //UART1 使用P30 P31口        默認(rèn)
  287.         AUXR &= ~(1<<4);        //Timer stop                波特率使用Timer2產(chǎn)生
  288.         AUXR |= 0x01;                //S1 BRT Use Timer2;
  289.         AUXR |=  (1<<2);        //Timer2 set as 1T mode
  290.         TH2 = (u8)(Timer2_Reload >> 8);
  291.         TL2 = (u8)Timer2_Reload;
  292.         AUXR |=  (1<<4);        //Timer run enable
  293.         REN = 1;        //允許接收
  294.         ES  = 1;        //允許中斷
  295.         EA = 1;                //允許全局中斷
  296.         P3M1 = 0x00;
  297.     P3M0 = 0xFF;
  298.         RX1_Cnt=0;
  299.         DK1=0;
  300.         BEEP=0;
  301.         ///////////////////////////////////////////////////////////////////////////////////以上部分主要完成串口的初始化////////////////////////////
  302.         for(;;)
  303.         {        //////////////////////////////////////////////////////////下面的語句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////
  304.                 Delay2(2000);
  305.         at_uart_send_str(AT_MODE);
  306.                 Delay2(2000);
  307.         at_uart_send_str(AT_CWJAP);
  308.                 Delay2(10000);
  309.         at_uart_send_str(CIPSTART);
  310.                 Delay2(2000);
  311.                 //////////////////////////////////////////////////////////上面面的語句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////
  312.                 make_send_pack(0,esp_dev_id,esp_TOK_id,esp_user_data,8);//構(gòu)造登錄數(shù)據(jù)包
  313.                 make_AT_SEND(need_seed_len);                            //將要進(jìn)過WIFI發(fā)送的總字節(jié)數(shù)變成10進(jìn)制,動態(tài)生成發(fā)送數(shù)據(jù)AT指令
  314.         at_uart_send_str(at_send_len_ox);                       //將構(gòu)造好的AT發(fā)送數(shù)據(jù)到互聯(lián)網(wǎng)的動態(tài)發(fā)送數(shù)據(jù)長度
  315.                 Delay2(2000);
  316.                 at_uart_send_buf(temp_buf,need_seed_len);                                //經(jīng)過WIFI模塊發(fā)送構(gòu)造好的登錄包
  317.                 while(1)
  318.                 {
  319.                         for(tt=0;tt<60;tt++)
  320.                         {
  321.                         Delay2(200);
  322.                         Delay2(200);
  323.                         }
  324.                     make_send_pack(1,esp_dev_id,toke,temp_cd,10);    //構(gòu)造上傳數(shù)據(jù)到云,轉(zhuǎn)給手機的溫度數(shù)據(jù)包,符合基本數(shù)據(jù)格式
  325.                     make_AT_SEND(need_seed_len);                                          //動態(tài)構(gòu)造發(fā)送AT指令
  326.                         at_uart_send_str(at_send_len_ox);                //發(fā)送構(gòu)造好的發(fā)送指令
  327.                     Delay2(2000);
  328.                     at_uart_send_buf(temp_buf,need_seed_len);             //經(jīng)過WIFI發(fā)送數(shù)據(jù)

  329.                         LED1=0;
  330.                         Delay2(200);
  331.                     LED1=1;
  332.                         Delay2(200);
  333.                                                                                                                         //每30秒會運行到這里一次。更新一次溫度數(shù)值
  334.                         time++;
  335.                         temp_cd[5]=(((time%1000)/100)+'0');
  336.                         temp_cd[6]=(((time%100)/10)+'0');
  337.                     temp_cd[7]=(((time%10))+'0');
  338.                 }
  339.         }
  340.         Delay2(2000);
  341. }

  342. /********************* UART1中斷函數(shù)************************/
  343. bit a_vec=0;
  344. void UART1_int (void) interrupt UART1_VECTOR
  345. {
  346.         if(RI)
  347.         {
  348.                 RI = 0;
  349.                 if(SBUF==0x55)         //////////////////////////////////////下面的語句根據(jù)固定的數(shù)據(jù)包格式,簡單取出想要的數(shù)據(jù)/////////////////////////////////
  350.                 a_vec=1;
  351.                 if(a_vec)
  352.                 {
  353.                  recd_buf[RX1_Cnt] = SBUF;                //保存一個字節(jié)
  354.                  if(RX1_Cnt<62)
  355.                    RX1_Cnt++;
  356.                  else
  357.                    RX1_Cnt=0;
  358.                  if(recd_buf[RX1_Cnt]==0X55)
  359.                    two_lab++;
  360.                  if(two_lab==2)//////////////////////////////////////////取出2個OX55之間的有效數(shù)據(jù)////////////////////
  361.                  {
  362.                    have_data=1;
  363.                    two_lab=0;
  364.                    rec_len=RX1_Cnt;
  365.                    RX1_Cnt=0;
  366.                    a_vec=0;
  367.                     if((recd_buf[33])==':')              /////////////////////////////////////簡單得到手機的開指令////////////////////
  368.                         {

  369.                         if((recd_buf[34])=='0')
  370.                         {
  371.                           LED1=0;          //開燈指令
  372.                           toke[7]=recd_buf[19];             //////////////郁悶的是模塊是令牌包,是登錄服務(wù)器的時候,只發(fā)送一次! 這個時候串口處于未知狀態(tài),因此經(jīng)常把第一個包丟了
  373.                           toke[6]=recd_buf[20];                 //////////////串口接收到的第一個數(shù)據(jù)包就是服務(wù)器回復(fù)的令牌包,本單片機第一恰好丟掉,但是一旦登錄上服務(wù)器,只要手機發(fā)
  374.                           toke[5]=recd_buf[21];                 //////////////一個控制開關(guān)指令到模塊,在這個指令的固定位置,比如19位置處,放的就是可能丟的令牌包!
  375.                           toke[4]=recd_buf[22];                 //////////////保留好這個令牌包,以后模塊發(fā)送到云平臺的數(shù)據(jù),到要用到這個令牌包
  376.                           toke[3]=recd_buf[23];
  377.                           toke[2]=recd_buf[24];
  378.                           toke[1]=recd_buf[25];
  379.                           toke[0]=recd_buf[26];
  380.                         }
  381.                         else if((recd_buf[34])=='1')
  382.                       LED1=1;  //關(guān)燈指令
  383.                         }
  384.                  }
  385.                  }
  386.         }
  387.         if(TI)
  388.         {
  389.                 TI = 0;
  390.                 B_TX1_Busy = 0;                //清除發(fā)送忙標(biāo)志
  391.         }
  392. }
復(fù)制代碼


  1.                                                    /*------------------------------------------------------------------------------
  2. HELLO.C

  3. Copyright 1995-2005 Keil Software, Inc.
  4. ------------------------------------------------------------------------------*/

  5. #include <REG52.H>                /* special function register declarations   */
  6.                                   /* for the intended 8051 derivative         */

  7. #include <stdio.h>                /* prototype declarations for I/O functions */


  8. #ifdef MONITOR51                         /* Debugging with Monitor-51 needs   */
  9. char code reserve [3] _at_ 0x23;         /* space for serial interrupt if     */
  10. #endif                                   /* Stop Exection with Serial Intr.   */
  11.                                          /* is enabled                        */


  12. /*------------------------------------------------
  13. The main C function.  Program execution starts
  14. here after stack initialization.
  15. ------------------------------------------------*/
  16. #define CRC_SEED   0xFFFF   // 該位稱為預(yù)置值,使用人工算法(長除法)時 需要將除數(shù)多項式先與該與職位 異或 ,才能得到最后的除數(shù)多項式
  17. #define POLY16 0x1021  // 該位為簡式書寫 實際為0x11021
  18. unsigned char crc_16[35]={0x55,0x26,0x00,0xA0,0x00,0xA8,0x16,0x16,0xA8,0x02,0xE6,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0xe6};
  19. unsigned char crc_12[6]={1,3,0,0,0,1};
  20. code unsigned int crc_table[256]={               /* CRC余式表 */
  21.     0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
  22.     0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
  23.     0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
  24.     0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
  25.     0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
  26.     0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
  27.     0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
  28.     0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
  29.     0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
  30.     0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
  31.     0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
  32.     0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
  33.     0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
  34.     0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
  35.     0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
  36.     0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
  37.     0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
  38.     0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
  39.     0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
  40.     0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
  41.     0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
  42.     0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
  43.     0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
  44.     0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
  45.     0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
  46.     0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
  47.     0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
  48.     0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
  49.     0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
  50.     0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
  51.     0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
  52.     0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
  53.   };
  54. /*
  55. unsigned int crc16(unsigned char *buf,unsigned short length)
  56. {
  57.   int shift,data1,val;
  58.   int i;

  59.   shift = CRC_SEED;


  60.   for(i=0;i<length;i++) {
  61.     if((i % 8) == 0)
  62.       data1 = (*buf++)<<8;
  63.     val = shift ^ data1;
  64.     shift = shift<<1;
  65.     data1 = data1 <<1;
  66.     if(val&0x8000)
  67.       shift = shift ^ POLY16;
  68.   }
  69.   return shift;
  70. }
  71. */


  72. unsigned char crc_t=0;
  73. unsigned int crc=0;
  74. unsigned int do_crc_table(unsigned char *ptr,int len)
  75. {
  76.    unsigned int crc;
  77.    unsigned char da;
  78.    crc=0;
  79.    while(len--!=0)
  80.     {

  81.        da=(unsigned char) (crc/256); //存儲CRC的高8位

  82.        crc<<=8;//左移8位,相當(dāng)于CRC的低8位乘以2^8

  83.       
  84.        crc^= crc_table[da^*ptr];         ptr++;

  85.       //高8位和當(dāng)前字節(jié)相加后再查表求的CRC,再加上以前的CRC
  86.       }
  87.    return(crc);
  88. }

  89. void main (void) {

  90. /*------------------------------------------------
  91. Setup the serial port for 1200 baud at 16MHz.
  92. ------------------------------------------------*/
  93. #ifndef MONITOR51
  94.     SCON  = 0x50;                        /* SCON: mode 1, 8-bit UART, enable rcvr      */
  95.     TMOD |= 0x20;               /* TMOD: timer 1, mode 2, 8-bit reload        */
  96.     TH1   = 221;                /* TH1:  reload value for 1200 baud @ 16MHz   */
  97.     TR1   = 1;                  /* TR1:  timer 1 run                          */
  98.     TI    = 1;                  /* TI:   set TI to send first char of UART    */
  99. #endif

  100. /*------------------------------------------------
  101. Note that an embedded program never exits (because
  102. there is no operating system to return to).  It
  103. must loop and execute forever.
  104. ------------------------------------------------*/
  105. crc=do_crc_table(crc_16,35);
  106.   while (1) {
  107.     P1 ^= 0x01;                         /* Toggle P1.0 each time we print */
  108.     printf ("Hello World\n");   /* Print "Hello World" */
  109.   }
  110. }

復(fù)制代碼




作者: borwell    時間: 2016-4-10 21:46
非常感謝樓主分享
作者: fengzhongmima    時間: 2016-4-14 11:42
感謝樓主分享
作者: honeyxiaoyi    時間: 2016-6-23 11:21
謝謝樓主分享,學(xué)習(xí)學(xué)習(xí)。。。。。
作者: lollipopwyyy    時間: 2016-7-11 11:17
樓主好棒
作者: lollipopwyyy    時間: 2016-7-11 11:20
用什么軟件打開呢
作者: 騰飛的龍    時間: 2016-7-11 19:41
很好的資料謝謝分享。
作者: 騰飛的龍    時間: 2016-7-11 19:42
樓主你好:手機AAP在哪里下載,謝謝請指教!
作者: 騰飛的龍    時間: 2016-7-11 19:43
lollipopwyyy 發(fā)表于 2016-7-11 11:20
用什么軟件打開呢

kiluv4
作者: 行云流水    時間: 2016-7-11 22:33
學(xué)習(xí)學(xué)習(xí),非常感謝樓主分享
作者: distance1502    時間: 2016-7-12 10:36
來學(xué)習(xí)學(xué)習(xí)
作者: zy6897401    時間: 2016-7-17 13:49
過來學(xué)習(xí)!。

作者: tutu123    時間: 2016-7-23 21:20

學(xué)習(xí)學(xué)習(xí),非常感謝樓主分享
作者: dongdong2018    時間: 2016-8-10 12:54
學(xué)習(xí)一下
作者: dongdong2018    時間: 2016-8-10 12:55
學(xué)習(xí)學(xué)習(xí),非常感謝樓主分享
作者: plutobio    時間: 2016-8-26 09:42
先收藏了,謝謝樓主
作者: lyseg    時間: 2016-8-29 17:40
很好的資料謝謝分享!!!!
作者: cdzfan    時間: 2016-9-8 23:51
謝謝分享!。
作者: 果鍋    時間: 2016-9-28 14:17
看得不是很多,學(xué)習(xí)一下

作者: 2138327187    時間: 2016-12-17 14:37

學(xué)習(xí)學(xué)習(xí),非常感謝樓主分享
作者: 繁華一世簡    時間: 2017-1-3 22:24
謝謝樓主分享
作者: 喔起風(fēng)了    時間: 2017-1-18 21:34
感謝樓主
作者: foison88    時間: 2017-2-23 15:45
已收藏,非常感謝樓主,學(xué)習(xí)中
作者: aa1151953633    時間: 2017-2-24 10:24
 非常感謝樓主分享
作者: 492324317    時間: 2017-3-9 21:57
其實我想知道發(fā)送原理是什么,既然PC可以通過串口向單片機發(fā)送信息,能否直接改為由單片機先模塊發(fā)送信息,不過失敗了,實在弄不清原理
作者: dzbj    時間: 2017-3-10 14:13
感謝樓主分享 學(xué)習(xí)了
作者: wwg258    時間: 2017-3-27 20:49
感謝樓主分享
作者: 5288346    時間: 2017-4-13 01:13
能直接移植到 STM8 上面嗎? 怎么做呢?
作者: 5288346    時間: 2017-4-13 16:54
很好的資料謝謝分享!!!!
作者: wsxujn    時間: 2017-4-14 15:22
這個不錯,我看看
作者: zhwzjf    時間: 2017-4-24 13:03
謝謝摟住,謝謝你的共享!在學(xué)習(xí)中。。。。。。
作者: yelifu007    時間: 2017-5-5 15:19
感謝分享
作者: wzgnb    時間: 2017-5-29 15:12
真心感謝分享。
作者: fffbi    時間: 2017-6-9 02:31
這個看看,謝謝分享
作者: w6403518    時間: 2017-6-10 19:42
正好學(xué)到 謝謝分享
作者: mlee3    時間: 2017-6-16 18:46
非常感謝樓主的分享
作者: 劉流    時間: 2017-6-29 12:59
很棒,學(xué)習(xí)了
作者: 七月的渡口    時間: 2017-7-10 15:13
感謝樓主的分享!
作者: 1181271766    時間: 2017-8-11 17:36
很給力qqdqdq

作者: zhao9988    時間: 2017-9-6 15:11
謝謝樓主的無私分享。
作者: qq3780    時間: 2017-10-13 17:38
很好的東西,學(xué)習(xí)了。正在了解愛信可
作者: 風(fēng)雪殘留    時間: 2017-10-14 20:18
謝謝分享
作者: YQS    時間: 2017-10-16 16:53
謝謝樓主分享資源!正需要來學(xué)習(xí),非常感謝!
作者: TONGHAOFENG    時間: 2017-11-1 12:52
很好的資料,有手機APP就更好啦。感謝
作者: 學(xué)徒工--靜    時間: 2017-11-11 15:30
太棒了  好材料正需要這些 謝謝樓主分享
作者: haitgo    時間: 2017-11-14 12:35
能下載不?
作者: hzyong    時間: 2017-12-22 09:12
好資料一定要支持的。參考參考。謝謝
作者: jdzczz    時間: 2017-12-26 10:51
正需要,謝謝!
作者: chengfgc    時間: 2018-1-29 11:27
學(xué)習(xí)了,謝謝分享!。。
作者: cccai    時間: 2018-3-13 10:39
謝謝樓主
作者: aaronhuang2018    時間: 2018-3-16 17:46
樓主厲害,學(xué)習(xí)了
作者: kelaosi    時間: 2018-4-4 17:07
感謝樓主分享。!
作者: wis98    時間: 2018-4-12 16:37
感謝樓主分享另一類的ESP8266程序
作者: 么么了    時間: 2018-4-16 20:56
謝謝大佬分享
作者: aptx48694517    時間: 2018-5-3 23:00
正在學(xué)習(xí),感謝分享

作者: 1126469277    時間: 2018-5-24 11:43
lollipopwyyy 發(fā)表于 2016-7-11 11:20
**** 作者被禁止或刪除 內(nèi)容自動屏蔽 ****

用 KEIL吧
作者: henry952    時間: 2018-6-15 10:39
感謝樓主的分享!
作者: tong0210    時間: 2018-6-26 11:08
謝謝,樓主好人一個。。
作者: jovew    時間: 2018-7-24 10:52
很好的資料,值得收藏。!
如果有APP源碼就更加好了。
作者: wgb12    時間: 2018-7-28 18:35
不錯,謝謝分享
作者: wycok    時間: 2018-8-6 13:56
謝謝樓主的無私分享!
作者: 別致    時間: 2019-11-20 13:12
代碼有點多,新手一個慢慢琢磨




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1