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

QQ登錄

只需一步,快速開(kāi)始

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

ESP8266用STC單片機(jī)發(fā)送AT命令來(lái)連接網(wǎng)絡(luò)的程序

  [復(fù)制鏈接]
ID:112317 發(fā)表于 2016-4-5 14:46 | 顯示全部樓層 |閱讀模式

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


主程序:
  1. /*

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

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

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

  14. */


  15. /*************        本地常量聲明        **************/
  16. #define MAIN_Fosc                22118400L        //定義主時(shí)鐘
  17. #define        RX1_Lenth                32                        //串口接收緩沖長(zhǎng)度
  18. #define        BaudRate1                115200UL        //選擇波特率
  19. #define        Timer1_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 1 重裝值, 對(duì)應(yīng)300KHZ
  20. #define        Timer2_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 2 重裝值, 對(duì)應(yīng)300KHZ
  21. #include        "STC15Fxxxx.H"
  22. /*************        本地變量聲明        **************/
  23. u8        idata RX1_Buffer[RX1_Lenth];        //接收緩沖
  24. u8        TX1_Cnt;        //發(fā)送計(jì)數(shù)
  25. u8        RX1_Cnt;        //接收計(jì)數(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. /////這是安信可云平臺(tái)數(shù)據(jù)包的全部組成結(jié)構(gòu),細(xì)節(jié)可參照安信可的云平臺(tái)V1.0版本規(guī)格書(shū),包結(jié)構(gòu)章節(jié)
  39. #define O_PF    0X00  //包頭1字節(jié)固定0X55
  40. #define O_LEN_L 0X01  //整個(gè)包長(zhǎng)低字節(jié)
  41. #define O_LEN_H 0X02  //整個(gè)包長(zhǎng)高字節(jié) 注意轉(zhuǎn)義碼 兩個(gè)這里只計(jì)算一個(gè)數(shù)據(jù)處理!
  42. #define O_CMD_T 0X03  //命令類型
  43. #define O_CMD_C 0X04  //具體命令
  44. #define O_CIX_L 0X05  //本命令序列編號(hào)低字節(jié)
  45. #define O_CIX_H 0X06  //本命令序列編號(hào)高字節(jié)
  46. #define O_EXMSH 0X07  //擴(kuò)展信息高字節(jié)
  47. #define O_EXMSL 0X08  //擴(kuò)展信息低字節(jié)
  48. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請(qǐng)求 未知
  49. #define O_DEVID_START 0x0A  //8字節(jié)設(shè)備識(shí)別  低字節(jié)在前
  50. #define O_DEVID 0x0A  //8字節(jié)設(shè)備識(shí)別
  51. #define O_TK_LEN      0X12 //1 BYTS TL_LEN          //獲得的設(shè)備臨時(shí)通訊令牌長(zhǎng)度
  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ù)的絕對(duì)位置//////////////////////////////////
  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模塊的許可號(hào)狀態(tài),獲取四個(gè)字節(jié)的芯片ID 和 4個(gè)字節(jié)的授權(quán)碼
  61. #define uart_rec_smartlink    2        //系統(tǒng)進(jìn)入獲取上網(wǎng)賬號(hào)密碼狀態(tài)
  62. #define uart_rec_bander       3        //系統(tǒng)進(jìn)入將本W(wǎng)IFI設(shè)備 和APP 手機(jī)綁定控制狀態(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è)置一個(gè)標(biāo)志位,串口程序 出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  68. unsigned char          ceng=0;         //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  69. unsigned char str_len_limt=16;         //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  70. unsigned char   str_len_num=11;        //字符個(gè)數(shù)
  71. char str_ref=':';
  72. /////////////////////////////////////////////////////////////////////上面幾個(gè)變量用來(lái)作為在串口中過(guò)濾指定字符串的 限定參數(shù),改變過(guò)濾內(nèi)容后必定先初始化這幾個(gè)/////
  73. code char CYSYS_code[]="+CSYSID:CHIP";
  74. code char PIPD_code[]="+IPD,";
  75. code char bander_code[]="+IPD,4,26:RPL:";//這里過(guò)濾有漏洞
  76. code char smartlink_code[]="SMART SUCCESS";
  77. /////////////////////////////////////////////////////////////////////以上是從WIFI模塊串口輸出到本單片機(jī)串口輸入后,本單片機(jī)要過(guò)濾的各種頭部////////////////////
  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. /////////////////////////////////////////////////////////////////////以上字串是單片機(jī)發(fā)給串口模塊的AT語(yǔ)句有的是直接給WIFI模塊的指令,有些是用來(lái)拷貝字符串用/////////////

  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個(gè)字節(jié)的器件ID號(hào),可在服務(wù)器數(shù)據(jù)庫(kù)中查到,唯一標(biāo)示一個(gè)器件,登錄過(guò)程需要一個(gè)器件ID,和數(shù)據(jù)區(qū)放一個(gè)數(shù)據(jù)密碼,這么簡(jiǎn)單登錄
  98. unsigned char esp_TOK_id[8]={0,0,0,0,0,0,0,0};                                 //    服務(wù)器分給器件器件的令牌包,另外個(gè)地方也定義了,完全可以用一個(gè)數(shù)組完成的
  99. unsigned char esp_user_data[14]={0,0,0,0,0,0,0X1E,0XDE};         //    客戶的凈數(shù)據(jù)負(fù)荷區(qū),可以很大,因?yàn)楸究顔纹瑱C(jī)有限,并且一般控制信號(hào),定義幾個(gè)字節(jié)夠了!注意在登錄的時(shí)候,這里是器件密碼!
  100. unsigned char temp_cd[]="TEMP:123;";                                                 //    一個(gè)數(shù)據(jù)包,前面是包格式定義,后面是客戶數(shù)據(jù)區(qū),這里定義一個(gè)即將要發(fā)送的溫度數(shù)據(jù)
  101. unsigned char need_seed_len=0;                                                                 //    全局變量,本次總共需要發(fā)到串口的數(shù)據(jù)
  102. bit t_o=0;                                                                                                         //  在構(gòu)造一個(gè)如00123 的數(shù)據(jù)時(shí)候,去掉前面的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秒把一個(gè)變量加1,然后把這個(gè)變量作為溫度數(shù)據(jù)上報(bào)給云平臺(tái),轉(zhuǎn)給手機(jī)端

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

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

  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上的相對(duì)位置
  124. #define EEPROM_PASSWORD_LC 64                //定義密碼 存在FLASH上的相對(duì)位置
  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的最后一個(gè)扇區(qū)。


  132. /////////////////////////////////////////////////////////////////下面部分定義了CRC16校驗(yàn)函數(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校驗(yàn)函數(shù)用到的表格///////////////////////////////////


  169. /////////////////////////////////////////////////////////////////////以下部分是STC的掉電存儲(chǔ)程序,讀寫(xiě)內(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的掉電存儲(chǔ)程序,讀寫(xiě)內(nèi)部的EEPROM 保存上網(wǎng)賬戶和密碼////////////////////////


  221. void make_AT_CIP3(void)
  222. //根據(jù)上邊 在2468 端口監(jiān)聽(tīng)到的 廣播內(nèi)容 用廣播內(nèi)容的IP 地址192.168.1.10和端口 48008新建一個(gè)3連接,
  223. //AT+CIPSTART=3,"UDP","192.168.1.10",48008,2469,0
  224. ///新建一個(gè)連接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. ////制作 向手機(jī)發(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.   //以下語(yǔ)句修改RPT:"0x00FE6738","0xB8B3C281","192.168.0.123","light","123456a" 中將本身的設(shè)備ID(如0x00FE6738) 和 KEY(0xB8B3C281)放到上面修改后的temp_buf
  260.   //后面的 "light","123456a"  為本設(shè)備名字,和本設(shè)備的密碼,暫時(shí)未用 可隨便填寫(xiě)

  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個(gè)字節(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校驗(yàn)碼 采用標(biāo)準(zhǔn)CRC16 初始CRC=0XFFFF  運(yùn)算多項(xiàng)式參數(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. //下面這個(gè)函數(shù)構(gòu)造一個(gè)發(fā)送的數(shù)據(jù)格式,請(qǐng)看數(shù)據(jù)格式文檔,完全可以用結(jié)構(gòu)體完成,這里采用數(shù)據(jù),從上到下描述這個(gè)數(shù)據(jù)包
  320. //發(fā)送的數(shù)據(jù)包,目前只有登錄數(shù)據(jù)包,和上報(bào)溫度數(shù)據(jù)包,這兩個(gè)基本的數(shù)據(jù)包,上報(bào)數(shù)據(jù)包可以充當(dāng)心跳包,第一個(gè)參數(shù)決定著,是發(fā)送登錄包還是溫度包
  321. //其他幾個(gè)入口參數(shù)是器件ID,令牌包,以及客戶的數(shù)據(jù),以及客戶數(shù)據(jù)長(zhǎng)度

  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ù)長(zhǎng)度,包頭至包尾,記得是沒(méi)有經(jīng)過(guò)轉(zhuǎn)義前的包長(zhǎng)
  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ù)包云平臺(tái)
  331.   send_buf[O_CMD_T]=0XA0;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實(shí)時(shí)檢測(cè)指令 0XF0 終端操作
  332.   else if (ms_opt==1)
  333.   send_buf[O_CMD_T]=0XAA;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實(shí)時(shí)檢測(cè)指令 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è)備到云平臺(tái)的方向

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

  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號(hào)到數(shù)據(jù)包里


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


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


  348.   for(i=0;i<use_data_len;i++)
  349.   send_buf[O_DATAS_START+i]=*(use_data+i); // 客戶的數(shù)據(jù)區(qū),登錄的時(shí)候放數(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是針對(duì)轉(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. }         ///////////////////////////////////////////////////////////以上的語(yǔ)句轉(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校驗(yàn)////////////////////////////////////////
  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)//簡(jiǎn)單延遲函數(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)義過(guò)來(lái),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.         //////////////////////////////////////////////////////////////////////////////////////下面部分為定時(shí)器以及串口初始化/////////////////////
  495.         init_uart();
  496.         Delay2(1000);
  497.         if(K1==0)           //開(kāi)機(jī)的時(shí)候發(fā)現(xiàn)按鍵1也就是MCU_P1.3 被按下,那么清除單片機(jī)中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) //開(kāi)機(jī)后檢測(cè)是否已經(jīng)保存了客戶的信息在EEPROM中
  508.         have_config=0;
  509.         else
  510.         have_config=1; //EEPROM沒(méi)有記錄客戶的路由器賬戶和密碼,需要配置
  511.         ///////////////////////////////////////////////////////////////////////////////////以上部分主要完成串口的初始化////////////////////////////
  512.         for(;;)
  513.         {         
  514.         a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  515.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  516.         str_len_limt=22;          //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  517.         str_len_num=13;           //要過(guò)濾連續(xù)字符個(gè)數(shù)
  518.         str_ref=':';                          // 過(guò)濾到字符串后,接著要出現(xiàn)的字符,這個(gè)字符出現(xiàn)的位置才是絕對(duì)0位置
  519.                 uart_rec_sta=uart_rec_smartlink; //設(shè)置在串口中的過(guò)濾分支條件,串口中斷中,根據(jù)這個(gè)標(biāo)志調(diào)用不同的字符串過(guò)濾參數(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)入過(guò)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]);    //存儲(chǔ)客戶賬戶到EEPROM中
  548.                          }
  549.                          IapProgramByte(IAP_ADDRESS+EEPROM_SSID_LC,ssid_len);                           //存儲(chǔ)客戶的賬戶長(zhǎng)度到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]);//存儲(chǔ)客戶密碼到EEPROM中
  554.                                 pasd_len++;                                                                                                          
  555.                          }

  556.                          IapProgramByte(IAP_ADDRESS+EEPROM_PASSWORD_LC,pasd_len);          //存儲(chǔ)客戶的密碼長(zhǎng)度到EEPROM中
  557.                          IapProgramByte(IAP_ADDRESS+EEPROM_LAB,0x55);
  558.                    }
  559.                    else        //無(wú)需用SMARTLINK 方式獲取路由器賬戶和秘密,賬戶和密碼直接從單片機(jī)的EEPROM直接讀取
  560.                    {
  561.                     ssid_len=IapReadByte(IAP_ADDRESS+EEPROM_SSID_LC);         //從EEPROM中的賬戶長(zhǎng)度
  562.                         pasd_len=IapReadByte(IAP_ADDRESS+EEPROM_PASSWORD_LC);//從EEPROM中的密碼長(zhǎng)度
  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;                //清空臨時(shí)緩沖區(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 填充 加入路由器所需要的兩個(gè)參數(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]='"';                         //以上語(yǔ)句構(gòu)造出:AT+CWJAP="360we","zty0012001" 這樣的指令,其中路由器賬戶和密碼 隨客戶變動(dòng)
  589.                 }
  590.             }while(have_smartlink==0); //此循環(huán)完成SMARTLINK 的配置

  591.                 LED1=1;
  592.                 LED2=1;
  593.                 LED3=1;
  594.             //////////////////////////////////////////////////////////下面的語(yǔ)句獲得模塊的設(shè)備ID/////////////////////////////////////////////////////////////
  595.         a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  596.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  597.         str_len_limt=16;          //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  598.         str_len_num=12;           //要過(guò)濾的字符個(gè)數(shù) +CSYSID:CHIP: 為下一個(gè)字符留個(gè)位置: 因此是12個(gè)字符
  599.         str_ref=':';                          // 要過(guò)濾到的字符
  600.                 uart_rec_sta=uart_rec_csysid;
  601.                 at_uart_send_str(AT_CSYSID); //返回如下:+CSYSID:CHIP:00FE6738;FLASH:001640EF;KEY:81C2B3B8;
  602.                 Delay2(2000);                                 //延時(shí)兩秒后,串口中必定輸出 所需要的器件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.         //下面的語(yǔ)句將獲取的16進(jìn)制字符換成 16進(jìn)制數(shù)據(jù),8個(gè)字節(jié)的字符最總得到四個(gè)字節(jié)的16進(jìn)制數(shù)據(jù) 比如字符串"A2345678"最終變成0XA2,0X34,0X56,0X78 四個(gè)字節(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ù)四個(gè)字節(jié)存放到對(duì)應(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個(gè)字節(jié)的字符最總得到四個(gè)字節(jié)的16進(jìn)制數(shù)據(jù) 比如字符串"A2345678"最終變成0XA2,0X34,0X56,0X78 四個(gè)字節(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ù)四個(gè)字節(jié)存放到對(duì)應(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個(gè)字節(jié)的)換成16進(jìn)制 存放到內(nèi)存中,在登錄服務(wù)器的時(shí)候的兩個(gè)必要參數(shù)。
  649.                 //////////////////////////////////////////////////////////上面的語(yǔ)句獲得模塊的設(shè)備ID和KEY/////////////////////////////////////////////////////////////
  650.                 }
  651.                 //while(1);
  652.                 //////////////////////////////////////////////////////////下面的語(yǔ)句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////

  653.                 a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  654.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  655.         str_len_limt=16;          //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  656.         str_len_num=7;            //字符個(gè)數(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 中此時(shí)存放的是  AT+CWJAP="360we","zty0012001"        這樣的AT指令,這一步加入路由器中
  663.                 Delay2(10000);
  664.                 at_uart_send_str(AT_CIPMUX);//進(jìn)入多連接模式,單連接其實(shí)也可以的
  665.                 Delay2(2000);
  666.         at_uart_send_str(CIPSTART);        //用UDP方式連接到安信可的云,連接到目標(biāo)5001安信可云服務(wù),順便監(jiān)聽(tīng) 2468 端口,code unsigned char CIPSTART[]="AT+CIPSTART=4,\"UDP\",\"cloud.ai-thinker.com\",5001,2468,0"
  667.                 Delay2(2000);
  668.                
  669.                 if(have_config)                           //客戶需要重新配置,這個(gè)時(shí)候也順便把模塊和手機(jī)的綁定關(guān)系建立:原理是模塊把芯片ID和KEY經(jīng)過(guò)UDP發(fā)給手機(jī),手機(jī)把這個(gè)合法ID上報(bào)給服務(wù)器,從而綁定!
  670.                 {                                                   //過(guò)程是手機(jī)在和模塊同一個(gè)局域網(wǎng)后,手機(jī)發(fā)送UDP到2468端口,而上一步,模塊在監(jiān)聽(tīng)2468端口!手機(jī)發(fā)送的UDP包內(nèi)容是RPL:"192.168.1.10","48008"
  671.                 do                                                   //其實(shí)手機(jī)是把自己現(xiàn)在的IP地址192.168.1.10 和即將監(jiān)聽(tīng)的端口48008 告訴模塊,然后模塊就可以把自己的芯片ID 和KEY授權(quán) 各四個(gè)字節(jié) 回送給手機(jī)
  672.                 {                                                   //因此任何一個(gè)手機(jī)只要獲得這個(gè)模塊的芯片ID 和KEY ,即可向服務(wù)器利用這個(gè)信息,進(jìn)行控制權(quán)申請(qǐng),也就是綁定!
  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)聽(tīng)局域網(wǎng)內(nèi)手機(jī)向2468端口(2468端口和連接4綁定) 發(fā)出的UDP掃描信息,獲得RPL:"192.168.1.10","48008"  手機(jī)透露自己的IP和端口
  687.                  
  688.                  make_AT_CIP3();                                    //根據(jù)上邊 在2468 端口監(jiān)聽(tīng)到手機(jī)透露的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();                     //從綁定手機(jī)和設(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)過(guò)路由器發(fā)給手機(jī)的數(shù)據(jù)長(zhǎng)度,  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ù)上面的幾個(gè)步驟,手機(jī)獲取到了模塊的芯片ID 和 KEY ID,手機(jī)得到后會(huì)利用這個(gè)信息讓服務(wù)器綁定它們兩個(gè)

  697.                 //////////////////////////////////////////////////////////上面面的語(yǔ)句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////
  698.                 at_uart_send_str(AT_MODE);
  699.                 a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  700.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  701.         str_len_limt=12;          //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  702.         str_len_num=5;            //字符個(gè)數(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)過(guò)WIFI發(fā)送的總字節(jié)數(shù)變成10進(jìn)制,動(dòng)態(tài)生成發(fā)送數(shù)據(jù)AT指令
  707.                 two_lab=0;                                                                                                ////////////////////////////////////////////////////////////////////兩個(gè)55計(jì)數(shù)!有可能錯(cuò)亂
  708.         at_uart_send_str(at_send_len_ox);                       //將構(gòu)造好的AT發(fā)送數(shù)據(jù)到互聯(lián)網(wǎng)的動(dòng)態(tài)發(fā)送數(shù)據(jù)長(zhǎng)度
  709.                 Delay2(2000);
  710.                 at_uart_send_buf(temp_buf,need_seed_len);                                //經(jīng)過(guò)WIFI模塊發(fā)送構(gòu)造好的登錄包
  711.                 Delay2(4000);

  712.                 //while(1);

  713.                 while(1)
  714.                 {                                                                                                         //主循環(huán)體中,每30秒構(gòu)造一個(gè)上傳數(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)給手機(jī)的溫度數(shù)據(jù)包,符合基本數(shù)據(jù)格式
  721.                     make_AT_SEND(need_seed_len);                                          //動(dòng)態(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)過(guò)WIFI發(fā)送數(shù)據(jù)

  725.                         LED2=0;
  726.                         BEEP=1;
  727.                         Delay2(200);
  728.                     LED2=1;
  729.                         BEEP=0;                                         //閃亮心跳指示燈,和心跳音
  730.                                                                                                                         //每30秒會(huì)運(yùn)行到這里一次。更新一次溫度數(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. /********************* 字符串過(guò)濾函數(shù)初始參數(shù)************************/
  740. /*
  741. bit a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  742. unsigned char ceng=0;         //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  743. unsigned char str_len_limt=12;//設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  744. unsigned char str_len_num=5;  //字符個(gè)數(shù)
  745. char str_ref=':';
  746. code char test_code[]="+IPD,";
  747. */

  748. void fit_stb(unsigned char *str_p) // 每次串口接收到一個(gè)字符都會(huì)進(jìn)入本過(guò)濾函數(shù),看是否過(guò)濾到指定的字符串。
  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)//上次未曾過(guò)濾到指定的字符串中所有的字符出現(xiàn),每次只過(guò)濾一個(gè)字符
  783.                 {
  784.                  switch(uart_rec_sta)              //根據(jù)系統(tǒng)的狀態(tài),決定過(guò)濾哪個(gè)字符
  785.                  {
  786.                   case uart_rec_tcp_udp_data: //串口進(jìn)入正常的UDP TCP 數(shù)據(jù)收發(fā)
  787.                   fit_stb(PIPD_code);                  //過(guò)濾數(shù)據(jù)接收頭
  788.                   break;
  789.                   case  uart_rec_csysid:          //串口進(jìn)入獲得模塊內(nèi)部ID 和KEY 狀態(tài)
  790.                   fit_stb(CYSYS_code);              //過(guò)濾指定的頭部
  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//////////////////////////////過(guò)濾到指定的頭部
  800.                 {
  801.                
  802.                  recd_buf[RX1_Cnt] = SBUF;                //保存一個(gè)字節(jié)
  803.                  if(recd_buf[RX1_Cnt]==0X55)    //記錄0X55的個(gè)數(shù),出現(xiàn)兩次后,代表一個(gè)有數(shù)據(jù)包結(jié)束
  804.                  two_lab++;
  805.                  if(RX1_Cnt<62)        /////////////////////防止64字節(jié)的緩沖區(qū)溢出
  806.                  RX1_Cnt++;
  807.                  else                        ///////每次收到的指令超過(guò)64字節(jié),就把數(shù)據(jù)清空,接收指針指向開(kāi)頭
  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個(gè)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])==':')              /////////////////////////////////////簡(jiǎn)單得到手機(jī)的開(kāi)關(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;    //開(kāi)燈指令
  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,否者隨機(jī)  數(shù)組注意溢出問(wèn)題  0X55 在其他數(shù)據(jù)中有可能出現(xiàn),并造成混亂,主要是計(jì)數(shù)  過(guò)濾數(shù)據(jù),根據(jù)網(wǎng)絡(luò)環(huán)境不同,返回有可能變化,注意通用性
  3.   內(nèi)部 ID KEY 輸出格式已經(jīng)固定為8個(gè)字節(jié)模式
  4. */


  5. /*************        本地常量聲明        **************/
  6. #define MAIN_Fosc                22118400L        //定義主時(shí)鐘
  7. #define        RX1_Lenth                32                        //串口接收緩沖長(zhǎng)度
  8. #define        BaudRate1                115200UL        //選擇波特率
  9. #define        Timer1_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 1 重裝值, 對(duì)應(yīng)300KHZ
  10. #define        Timer2_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 2 重裝值, 對(duì)應(yīng)300KHZ
  11. #include        "STC15Fxxxx.H"
  12. /*************        本地變量聲明        **************/
  13. u8        idata RX1_Buffer[RX1_Lenth];        //接收緩沖
  14. u8        TX1_Cnt;        //發(fā)送計(jì)數(shù)
  15. u8        RX1_Cnt;        //接收計(jì)數(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. /////這是安信可云平臺(tái)數(shù)據(jù)包的全部組成結(jié)構(gòu),細(xì)節(jié)可參照安信可的云平臺(tái)V1.0版本規(guī)格書(shū),包結(jié)構(gòu)章節(jié)
  29. #define O_PF    0X00  //包頭1字節(jié)固定0X55
  30. #define O_LEN_L 0X01  //整個(gè)包長(zhǎng)低字節(jié)
  31. #define O_LEN_H 0X02  //整個(gè)包長(zhǎng)高字節(jié) 注意轉(zhuǎn)義碼 兩個(gè)這里只計(jì)算一個(gè)數(shù)據(jù)處理!
  32. #define O_CMD_T 0X03  //命令類型
  33. #define O_CMD_C 0X04  //具體命令
  34. #define O_CIX_L 0X05  //本命令序列編號(hào)低字節(jié)
  35. #define O_CIX_H 0X06  //本命令序列編號(hào)高字節(jié)
  36. #define O_EXMSH 0X07  //擴(kuò)展信息高字節(jié)
  37. #define O_EXMSL 0X08  //擴(kuò)展信息低字節(jié)
  38. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請(qǐng)求 未知
  39. #define O_DEVID_START 0x0A  //8字節(jié)設(shè)備識(shí)別  低字節(jié)在前
  40. #define O_DEVID 0x0A  //8字節(jié)設(shè)備識(shí)別
  41. #define O_TK_LEN      0X12 //1 BYTS TL_LEN          //獲得的設(shè)備臨時(shí)通訊令牌長(zhǎng)度
  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ù)的絕對(duì)位置//////////////////////////////////
  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模塊的許可號(hào)狀態(tài),獲取四個(gè)字節(jié)的芯片ID 和 4個(gè)字節(jié)的授權(quán)碼
  51. #define uart_rec_smartlink    2        //系統(tǒng)進(jìn)入獲取上網(wǎng)賬號(hào)密碼狀態(tài)
  52. #define uart_rec_bander       3        //系統(tǒng)進(jìn)入將本W(wǎng)IFI設(shè)備 和APP 手機(jī)綁定控制狀態(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è)置一個(gè)標(biāo)志位,串口程序 出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  58. unsigned char          ceng=0;         //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  59. unsigned char str_len_limt=16;         //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  60. unsigned char   str_len_num=11;        //字符個(gè)數(shù)
  61. char str_ref=':';
  62. /////////////////////////////////////////////////////////////////////上面幾個(gè)變量用來(lái)作為在串口中過(guò)濾指定字符串的 限定參數(shù),改變過(guò)濾內(nèi)容后必定先初始化這幾個(gè)/////
  63. code char CYSYS_code[]="+CSYSID:CHIP";
  64. code char PIPD_code[]="+IPD,";
  65. code char bander_code[]="+IPD,4,26:RPL:";//這里過(guò)濾有漏洞
  66. code char smartlink_code[]="SMART SUCCESS";
  67. /////////////////////////////////////////////////////////////////////以上是從WIFI模塊串口輸出到本單片機(jī)串口輸入后,本單片機(jī)要過(guò)濾的各種頭部////////////////////
  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. /////////////////////////////////////////////////////////////////////以上字串是單片機(jī)發(fā)給串口模塊的AT語(yǔ)句有的是直接給WIFI模塊的指令,有些是用來(lái)拷貝字符串用/////////////

  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個(gè)字節(jié)的器件ID號(hào),可在服務(wù)器數(shù)據(jù)庫(kù)中查到,唯一標(biāo)示一個(gè)器件,登錄過(guò)程需要一個(gè)器件ID,和數(shù)據(jù)區(qū)放一個(gè)數(shù)據(jù)密碼,這么簡(jiǎn)單登錄
  88. unsigned char esp_TOK_id[8]={0,0,0,0,0,0,0,0};                                 //    服務(wù)器分給器件器件的令牌包,另外個(gè)地方也定義了,完全可以用一個(gè)數(shù)組完成的
  89. unsigned char esp_user_data[14]={0,0,0,0,0,0,0X1E,0XDE};         //    客戶的凈數(shù)據(jù)負(fù)荷區(qū),可以很大,因?yàn)楸究顔纹瑱C(jī)有限,并且一般控制信號(hào),定義幾個(gè)字節(jié)夠了!注意在登錄的時(shí)候,這里是器件密碼!
  90. unsigned char temp_cd[]="TEMP:123;";                                                 //    一個(gè)數(shù)據(jù)包,前面是包格式定義,后面是客戶數(shù)據(jù)區(qū),這里定義一個(gè)即將要發(fā)送的溫度數(shù)據(jù)
  91. unsigned char need_seed_len=0;                                                                 //    全局變量,本次總共需要發(fā)到串口的數(shù)據(jù)
  92. bit t_o=0;                                                                                                         //  在構(gòu)造一個(gè)如00123 的數(shù)據(jù)時(shí)候,去掉前面的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秒把一個(gè)變量加1,然后把這個(gè)變量作為溫度數(shù)據(jù)上報(bào)給云平臺(tái),轉(zhuǎn)給手機(jī)端

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

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

  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校驗(yàn)函數(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校驗(yàn)函數(shù)用到的表格///////////////////////////////////


  244. void make_AT_CIP3(void)
  245. //根據(jù)上邊 在2468 端口監(jiān)聽(tīng)到的 廣播內(nèi)容 用廣播內(nèi)容的IP 地址192.168.1.10和端口 48008新建一個(gè)3連接,
  246. //AT+CIPSTART=3,"UDP","192.168.1.10",48008,2469,0
  247. ///新建一個(gè)連接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. ////制作 向手機(jī)發(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.   //以下語(yǔ)句修改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個(gè)字節(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校驗(yàn)碼 采用標(biāo)準(zhǔn)CRC16 初始CRC=0XFFFF  運(yùn)算多項(xiàng)式參數(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. //下面這個(gè)函數(shù)構(gòu)造一個(gè)發(fā)送的數(shù)據(jù)格式,請(qǐng)看數(shù)據(jù)格式文檔,完全可以用結(jié)構(gòu)體完成,這里采用數(shù)據(jù),從上到下描述這個(gè)數(shù)據(jù)包
  342. //發(fā)送的數(shù)據(jù)包,目前只有登錄數(shù)據(jù)包,和上報(bào)溫度數(shù)據(jù)包,這兩個(gè)基本的數(shù)據(jù)包,上報(bào)數(shù)據(jù)包可以充當(dāng)心跳包,第一個(gè)參數(shù)決定著,是發(fā)送登錄包還是溫度包
  343. //其他幾個(gè)入口參數(shù)是器件ID,令牌包,以及客戶的數(shù)據(jù),以及客戶數(shù)據(jù)長(zhǎng)度

  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ù)長(zhǎng)度,包頭至包尾,記得是沒(méi)有經(jīng)過(guò)轉(zhuǎn)義前的包長(zhǎng)
  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ù)包云平臺(tái)
  353.   send_buf[O_CMD_T]=0XA0;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實(shí)時(shí)檢測(cè)指令 0XF0 終端操作
  354.   else if (ms_opt==1)
  355.   send_buf[O_CMD_T]=0XAA;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實(shí)時(shí)檢測(cè)指令 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è)備到云平臺(tái)的方向

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

  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號(hào)到數(shù)據(jù)包里


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


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


  370.   for(i=0;i<use_data_len;i++)
  371.   send_buf[O_DATAS_START+i]=*(use_data+i); // 客戶的數(shù)據(jù)區(qū),登錄的時(shí)候放數(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是針對(duì)轉(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. }         ///////////////////////////////////////////////////////////以上的語(yǔ)句轉(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校驗(yàn)////////////////////////////////////////
  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)//簡(jiǎn)單延遲函數(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)義過(guò)來(lái),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.         //////////////////////////////////////////////////////////////////////////////////////下面部分為定時(shí)器以及串口初始化/////////////////////
  518.         init_uart();
  519.         Delay2(2000);
  520.         flash_main();
  521.         ///////////////////////////////////////////////////////////////////////////////////以上部分主要完成串口的初始化////////////////////////////
  522.         for(;;)
  523.         {         
  524.         a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  525.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  526.         str_len_limt=22;          //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  527.         str_len_num=13;           //要過(guò)濾連續(xù)字符個(gè)數(shù)
  528.         str_ref=':';                          // 過(guò)濾到字符串后,接著要出現(xiàn)的字符,這個(gè)字符出現(xiàn)的位置才是絕對(duì)0位置
  529.                 uart_rec_sta=uart_rec_smartlink; //設(shè)置在串口中的過(guò)濾分支條件,串口中斷中,根據(jù)這個(gè)標(biāo)志調(diào)用不同的字符串過(guò)濾參數(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;                //清空臨時(shí)緩沖區(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 填充 加入路由器所需要的兩個(gè)參數(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.             //////////////////////////////////////////////////////////下面的語(yǔ)句獲得模塊的設(shè)備ID/////////////////////////////////////////////////////////////
  580.         a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  581.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  582.         str_len_limt=16;          //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  583.         str_len_num=12;           //要過(guò)濾的字符個(gè)數(shù) +CSYSID:CHIP: 為下一個(gè)字符留個(gè)位置: 因此是12個(gè)字符
  584.         str_ref=':';                          // 要過(guò)濾到的字符
  585.                 uart_rec_sta=uart_rec_csysid;
  586.                 at_uart_send_str(AT_CSYSID); //返回如下:+CSYSID:CHIP:00FE6738;FLASH:001640EF;KEY:81C2B3B8;
  587.                 Delay2(2000);                                 //延時(shí)兩秒后,串口中必定輸出 所需要的器件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個(gè)字節(jié)的字符最總得到四個(gè)字節(jié)的16進(jìn)制數(shù)據(jù) 比如字符串"A2345678"最終變成0XA2,0X34,0X56,0X78 四個(gè)字節(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ù)四個(gè)字節(jié)存放到對(duì)應(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個(gè)字節(jié)的字符最總得到四個(gè)字節(jié)的16進(jìn)制數(shù)據(jù) 比如字符串"A2345678"最終變成0XA2,0X34,0X56,0X78 四個(gè)字節(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ù)四個(gè)字節(jié)存放到對(duì)應(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個(gè)字節(jié)的)換成16進(jìn)制 存放到內(nèi)存中,在登錄服務(wù)器的時(shí)候的兩個(gè)必要參數(shù)。
  634.                 //////////////////////////////////////////////////////////上面的語(yǔ)句獲得模塊的設(shè)備ID和KEY/////////////////////////////////////////////////////////////
  635.                 }
  636.                 //while(1);
  637.                 //////////////////////////////////////////////////////////下面的語(yǔ)句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////

  638.                 a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  639.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  640.         str_len_limt=16;          //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  641.         str_len_num=7;            //字符個(gè)數(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)聽(tīng) 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)聽(tīng)局域網(wǎng)內(nèi)手機(jī)向2468端口(2468端口和連接4綁定) 發(fā)出的UDP掃描信息,獲得RPL:"192.168.1.10","48008"  手機(jī)透露自己的IP和端口
  670.                  
  671.                  make_AT_CIP3();                                   //根據(jù)上邊 在2468 端口監(jiān)聽(tīng)到的 廣播內(nèi)容 新建一個(gè)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();                    //從綁定手機(jī)和設(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.                 //////////////////////////////////////////////////////////上面面的語(yǔ)句發(fā)送AT指令加入內(nèi)網(wǎng),并鏈接到安信可物聯(lián)網(wǎng)服務(wù)器/////////////////////
  680.                 at_uart_send_str(AT_MODE);
  681.                 a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  682.         ceng=0;                   //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  683.         str_len_limt=12;          //設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  684.         str_len_num=5;            //字符個(gè)數(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)過(guò)WIFI發(fā)送的總字節(jié)數(shù)變成10進(jìn)制,動(dòng)態(tài)生成發(fā)送數(shù)據(jù)AT指令
  689.                 two_lab=0;                                                                                                ////////////////////////////////////////////////////////////////////兩個(gè)55計(jì)數(shù)!!有可能錯(cuò)亂
  690.         at_uart_send_str(at_send_len_ox);                       //將構(gòu)造好的AT發(fā)送數(shù)據(jù)到互聯(lián)網(wǎng)的動(dòng)態(tài)發(fā)送數(shù)據(jù)長(zhǎng)度
  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)過(guò)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)給手機(jī)的溫度數(shù)據(jù)包,符合基本數(shù)據(jù)格式
  743.                     make_AT_SEND(need_seed_len);                                          //動(dòng)態(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)過(guò)WIFI發(fā)送數(shù)據(jù)

  747.                         LED2=0;
  748.                         BEEP=1;
  749.                         Delay2(200);
  750.                     LED2=1;
  751.                         BEEP=0;      //閃亮心跳指示燈,和心跳音
  752.                                                                                                                         //每30秒會(huì)運(yùn)行到這里一次。更新一次溫度數(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. /********************* 字符串過(guò)濾函數(shù)初始參數(shù)************************/
  762. /*
  763. bit a_vec=0;                          //出現(xiàn)指定的字串,并動(dòng)態(tài)過(guò)濾到指定的字符后 置1
  764. unsigned char ceng=0;         //最多 多少字節(jié)內(nèi) 會(huì)出現(xiàn)指定字串,靜態(tài)變量,
  765. unsigned char str_len_limt=12;//設(shè)置一個(gè)限定參考數(shù)值,在這個(gè)參考個(gè)數(shù)內(nèi)必定出現(xiàn)指定字符串
  766. unsigned char str_len_num=5;  //字符個(gè)數(shù)
  767. char str_ref=':';
  768. code char test_code[]="+IPD,";
  769. */

  770. void fit_stb(unsigned char *str_p) // 每次串口接收到一個(gè)字符都會(huì)進(jìn)入本過(guò)濾函數(shù),看是否過(guò)濾到指定的字符串。
  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)//上次未曾過(guò)濾到指定的字符串中所有的字符出現(xiàn),每次只過(guò)濾一個(gè)字符
  805.                 {
  806.                  switch(uart_rec_sta)              //根據(jù)系統(tǒng)的狀態(tài),決定過(guò)濾哪個(gè)字符
  807.                  {
  808.                   case uart_rec_tcp_udp_data: //串口進(jìn)入正常的UDP TCP 數(shù)據(jù)收發(fā)
  809.                   fit_stb(PIPD_code);                  //過(guò)濾數(shù)據(jù)接收頭
  810.                   break;
  811.                   case  uart_rec_csysid:          //串口進(jìn)入獲得模塊內(nèi)部ID 和KEY 狀態(tài)
  812.                   fit_stb(CYSYS_code);              //過(guò)濾指定的頭部
  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//////////////////////////////過(guò)濾到指定的頭部
  822.                 {
  823.                
  824.                  recd_buf[RX1_Cnt] = SBUF;                //保存一個(gè)字節(jié)
  825.                  if(recd_buf[RX1_Cnt]==0X55)    //記錄0X55的個(gè)數(shù),出現(xiàn)兩次后,代表一個(gè)有數(shù)據(jù)包結(jié)束
  826.                  two_lab++;
  827.                  if(RX1_Cnt<62)        /////////////////////防止64字節(jié)的緩沖區(qū)溢出
  828.                  RX1_Cnt++;
  829.                  else                        ///////每次收到的指令超過(guò)64字節(jié),就把數(shù)據(jù)清空,接收指針指向開(kāi)頭
  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個(gè)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])==':')              /////////////////////////////////////簡(jiǎn)單得到手機(jī)的開(kāi)關(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;    //開(kāi)燈指令
  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        //定義主時(shí)鐘
  3. #define        RX1_Lenth                32                        //串口接收緩沖長(zhǎng)度
  4. #define        BaudRate1                115200UL        //選擇波特率
  5. #define        Timer1_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 1 重裝值, 對(duì)應(yīng)300KHZ
  6. #define        Timer2_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 2 重裝值, 對(duì)應(yīng)300KHZ
  7. #include        "STC15Fxxxx.H"
  8. /*************        本地變量聲明        **************/
  9. u8        idata RX1_Buffer[RX1_Lenth];        //接收緩沖
  10. u8        TX1_Cnt;        //發(fā)送計(jì)數(shù)
  11. u8        RX1_Cnt;        //接收計(jì)數(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  //整個(gè)包長(zhǎng)低字節(jié)
  25. #define O_LEN_H 0X02  //整個(gè)包長(zhǎng)高字節(jié) 注意轉(zhuǎn)義碼 兩個(gè)這里只計(jì)算一個(gè)數(shù)據(jù)處理!
  26. #define O_CMD_T 0X03  //命令類型
  27. #define O_CMD_C 0X04  //具體命令
  28. #define O_CIX_L 0X05  //本命令序列編號(hào)低字節(jié)
  29. #define O_CIX_H 0X06  //本命令序列編號(hào)高字節(jié)
  30. #define O_EXMSH 0X07  //擴(kuò)展信息高字節(jié)
  31. #define O_EXMSL 0X08  //擴(kuò)展信息低字節(jié)
  32. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請(qǐng)求 未知
  33. #define O_DEVID 0x0A  //8字節(jié)設(shè)備識(shí)別
  34.    //1 BYTS TL_LEN          //獲得的設(shè)備臨時(shí)通訊令牌長(zhǎng)度
  35.    //N BYTS TK                   //TL_LEN個(gè)通訊令牌串
  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  //整個(gè)包長(zhǎng)低字節(jié)
  131. #define O_LEN_H 0X02  //整個(gè)包長(zhǎng)高字節(jié) 注意轉(zhuǎn)義碼 兩個(gè)這里只計(jì)算一個(gè)數(shù)據(jù)處理!
  132. #define O_CMD_T 0X03  //命令類型
  133. #define O_CMD_C 0X04  //具體命令
  134. #define O_CIX_L 0X05  //本命令序列編號(hào)低字節(jié)
  135. #define O_CIX_H 0X06  //本命令序列編號(hào)高字節(jié)
  136. #define O_EXMSH 0X07  //擴(kuò)展信息高字節(jié)
  137. #define O_EXMSL 0X08  //擴(kuò)展信息低字節(jié)
  138. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請(qǐng)求 未知
  139. #define O_DEVID_START 0x0A  //8字節(jié)設(shè)備識(shí)別  低字節(jié)在前
  140. #define O_TK_LEN      0X12 //1 BYTS TL_LEN          //獲得的設(shè)備臨時(shí)通訊令牌長(zhǎng)度
  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 實(shí)時(shí)檢測(cè)指令 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í)候放數(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)制動(dòng)態(tài)修改AT發(fā)送指令           at_uart_send_str(at_send_len_ox);
  288.         at_uart_send_str(at_send_len_ox);                //動(dòng)態(tài)發(fā)送數(shù)據(jù)長(zhǎng)度
  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;                //保存一個(gè)字節(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        //定義主時(shí)鐘
  3. #define        RX1_Lenth                32                        //串口接收緩沖長(zhǎng)度
  4. #define        BaudRate1                115200UL        //選擇波特率
  5. #define        Timer1_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 1 重裝值, 對(duì)應(yīng)300KHZ
  6. #define        Timer2_Reload        (65536UL -(MAIN_Fosc / 4 / BaudRate1))                //Timer 2 重裝值, 對(duì)應(yīng)300KHZ
  7. #include        "STC15Fxxxx.H"
  8. /*************        本地變量聲明        **************/
  9. u8        idata RX1_Buffer[RX1_Lenth];        //接收緩沖
  10. u8        TX1_Cnt;        //發(fā)送計(jì)數(shù)
  11. u8        RX1_Cnt;        //接收計(jì)數(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  //整個(gè)包長(zhǎng)低字節(jié)
  26. #define O_LEN_H 0X02  //整個(gè)包長(zhǎng)高字節(jié) 注意轉(zhuǎn)義碼 兩個(gè)這里只計(jì)算一個(gè)數(shù)據(jù)處理!
  27. #define O_CMD_T 0X03  //命令類型
  28. #define O_CMD_C 0X04  //具體命令
  29. #define O_CIX_L 0X05  //本命令序列編號(hào)低字節(jié)
  30. #define O_CIX_H 0X06  //本命令序列編號(hào)高字節(jié)
  31. #define O_EXMSH 0X07  //擴(kuò)展信息高字節(jié)
  32. #define O_EXMSL 0X08  //擴(kuò)展信息低字節(jié)
  33. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請(qǐng)求 未知
  34. #define O_DEVID 0x0A  //8字節(jié)設(shè)備識(shí)別
  35.    //1 BYTS TL_LEN          //獲得的設(shè)備臨時(shí)通訊令牌長(zhǎng)度
  36.    //N BYTS TK                   //TL_LEN個(gè)通訊令牌串
  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ù)的絕對(duì)位置//////////////////////////////////

  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ā)送指令讓單片機(jī)連入內(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)包長(zhǎng),這里用個(gè)RAM存儲(chǔ)上邊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校驗(yàn)函數(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校驗(yàn)函數(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個(gè)字節(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校驗(yàn)碼 采用標(biāo)準(zhǔn)CRC16 初始CRC=0XFFFF  運(yùn)算多項(xiàng)式參數(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  //整個(gè)包長(zhǎng)低字節(jié)
  135. #define O_LEN_H 0X02  //整個(gè)包長(zhǎng)高字節(jié) 注意轉(zhuǎn)義碼 兩個(gè)這里只計(jì)算一個(gè)數(shù)據(jù)處理!
  136. #define O_CMD_T 0X03  //命令類型
  137. #define O_CMD_C 0X04  //具體命令
  138. #define O_CIX_L 0X05  //本命令序列編號(hào)低字節(jié)
  139. #define O_CIX_H 0X06  //本命令序列編號(hào)高字節(jié)
  140. #define O_EXMSH 0X07  //擴(kuò)展信息高字節(jié)
  141. #define O_EXMSL 0X08  //擴(kuò)展信息低字節(jié)
  142. #define O_RESTA 0X09  //數(shù)據(jù)包狀態(tài)信息,成功 失敗 請(qǐng)求 未知
  143. #define O_DEVID_START 0x0A  //8字節(jié)設(shè)備識(shí)別  低字節(jié)在前
  144. #define O_TK_LEN      0X12 //1 BYTS TL_LEN          //獲得的設(shè)備臨時(shí)通訊令牌長(zhǎng)度
  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個(gè)字節(jié)的器件ID號(hào),可在服務(wù)器數(shù)據(jù)庫(kù)中查到,唯一標(biāo)示一個(gè)器件,登錄過(guò)程需要一個(gè)器件ID,和數(shù)據(jù)區(qū)放一個(gè)數(shù)據(jù)密碼,這么簡(jiǎn)單登錄
  152. unsigned char esp_TOK_id[8]={0,0,0,0,0,0,0,0};                                 //    服務(wù)器分給器件器件的令牌包,另外個(gè)地方也定義了,完全可以用一個(gè)數(shù)組完成的
  153. unsigned char esp_user_data[14]={0,0,0,0,0,0,0X1E,0XE6};         //    客戶的凈數(shù)據(jù)負(fù)荷區(qū),可以很大,因?yàn)楸究顔纹瑱C(jī)有限,并且一般控制信號(hào),定義幾個(gè)字節(jié)夠了!注意在登錄的時(shí)候,這里是器件密碼!
  154. unsigned char temp_cd[]="TEMP:123;";                                                 //    一個(gè)數(shù)據(jù)包,前面是包格式定義,后面是客戶數(shù)據(jù)區(qū),這里定義一個(gè)即將要發(fā)送的溫度數(shù)據(jù)
  155. unsigned char need_seed_len=0;                                                                 //    全局變量,本次總共需要發(fā)到串口的數(shù)據(jù)


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

  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ù)長(zhǎng)度,包頭至包尾,記得是沒(méi)有經(jīng)過(guò)轉(zhuǎn)義前的包長(zhǎng)
  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ù)包云平臺(tái)
  168.   send_buf[O_CMD_T]=0XA0;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實(shí)時(shí)檢測(cè)指令 0XF0 終端操作
  169.   else if (ms_opt==1)
  170.   send_buf[O_CMD_T]=0XAA;// 0XA0 鏈路操作 0XAA 數(shù)據(jù)傳輸 0XAC 實(shí)時(shí)檢測(cè)指令 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è)備到云平臺(tái)的方向

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

  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號(hào)到數(shù)據(jù)包里


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


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


  185.   for(i=0;i<use_data_len;i++)
  186.   send_buf[O_DATAS_START+i]=*(use_data+i); // 客戶的數(shù)據(jù)區(qū),登錄的時(shí)候放數(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是針對(duì)轉(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. }         ///////////////////////////////////////////////////////////以上的語(yǔ)句轉(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校驗(yàn)////////////////////////////////////////
  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)//簡(jiǎn)單延遲函數(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秒把一個(gè)變量加1,然后把這個(gè)變量作為溫度數(shù)據(jù)上報(bào)給云平臺(tái),轉(zhuǎn)給手機(jī)端
  278. void main(void)
  279. {
  280.         char tt,i=0;;
  281.         //////////////////////////////////////////////////////////////////////////////////////下面部分為定時(shí)器以及串口初始化/////////////////////
  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.         {        //////////////////////////////////////////////////////////下面的語(yǔ)句發(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.                 //////////////////////////////////////////////////////////上面面的語(yǔ)句發(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)過(guò)WIFI發(fā)送的總字節(jié)數(shù)變成10進(jìn)制,動(dòng)態(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)的動(dòng)態(tài)發(fā)送數(shù)據(jù)長(zhǎng)度
  315.                 Delay2(2000);
  316.                 at_uart_send_buf(temp_buf,need_seed_len);                                //經(jīng)過(guò)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)給手機(jī)的溫度數(shù)據(jù)包,符合基本數(shù)據(jù)格式
  325.                     make_AT_SEND(need_seed_len);                                          //動(dòng)態(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)過(guò)WIFI發(fā)送數(shù)據(jù)

  329.                         LED1=0;
  330.                         Delay2(200);
  331.                     LED1=1;
  332.                         Delay2(200);
  333.                                                                                                                         //每30秒會(huì)運(yùn)行到這里一次。更新一次溫度數(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)         //////////////////////////////////////下面的語(yǔ)句根據(jù)固定的數(shù)據(jù)包格式,簡(jiǎn)單取出想要的數(shù)據(jù)/////////////////////////////////
  350.                 a_vec=1;
  351.                 if(a_vec)
  352.                 {
  353.                  recd_buf[RX1_Cnt] = SBUF;                //保存一個(gè)字節(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個(gè)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])==':')              /////////////////////////////////////簡(jiǎn)單得到手機(jī)的開(kāi)指令////////////////////
  368.                         {

  369.                         if((recd_buf[34])=='0')
  370.                         {
  371.                           LED1=0;          //開(kāi)燈指令
  372.                           toke[7]=recd_buf[19];             //////////////郁悶的是模塊是令牌包,是登錄服務(wù)器的時(shí)候,只發(fā)送一次! 這個(gè)時(shí)候串口處于未知狀態(tài),因此經(jīng)常把第一個(gè)包丟了
  373.                           toke[6]=recd_buf[20];                 //////////////串口接收到的第一個(gè)數(shù)據(jù)包就是服務(wù)器回復(fù)的令牌包,本單片機(jī)第一恰好丟掉,但是一旦登錄上服務(wù)器,只要手機(jī)發(fā)
  374.                           toke[5]=recd_buf[21];                 //////////////一個(gè)控制開(kāi)關(guān)指令到模塊,在這個(gè)指令的固定位置,比如19位置處,放的就是可能丟的令牌包!
  375.                           toke[4]=recd_buf[22];                 //////////////保留好這個(gè)令牌包,以后模塊發(fā)送到云平臺(tái)的數(shù)據(jù),到要用到這個(gè)令牌包
  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ù)置值,使用人工算法(長(zhǎng)除法)時(shí) 需要將除數(shù)多項(xiàng)式先與該與職位 異或 ,才能得到最后的除數(shù)多項(xiàng)式
  17. #define POLY16 0x1021  // 該位為簡(jiǎn)式書(shū)寫(xiě) 實(shí)際為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); //存儲(chǔ)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ù)制代碼



評(píng)分

參與人數(shù) 1黑幣 +5 收起 理由
qjyjack612510 + 5 很給力!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:71423 發(fā)表于 2016-4-10 21:46 | 顯示全部樓層
非常感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:114158 發(fā)表于 2016-4-14 11:42 | 顯示全部樓層
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:126573 發(fā)表于 2016-6-23 11:21 | 顯示全部樓層
謝謝樓主分享,學(xué)習(xí)學(xué)習(xí)。。。。。
回復(fù)

使用道具 舉報(bào)

ID:129989 發(fā)表于 2016-7-11 11:17 | 顯示全部樓層
樓主好棒
回復(fù)

使用道具 舉報(bào)

ID:129989 發(fā)表于 2016-7-11 11:20 | 顯示全部樓層
用什么軟件打開(kāi)呢
回復(fù)

使用道具 舉報(bào)

ID:79544 發(fā)表于 2016-7-11 19:41 | 顯示全部樓層
很好的資料謝謝分享。
回復(fù)

使用道具 舉報(bào)

ID:79544 發(fā)表于 2016-7-11 19:42 | 顯示全部樓層
樓主你好:手機(jī)AAP在哪里下載,謝謝請(qǐng)指教!
回復(fù)

使用道具 舉報(bào)

ID:79544 發(fā)表于 2016-7-11 19:43 | 顯示全部樓層
lollipopwyyy 發(fā)表于 2016-7-11 11:20
用什么軟件打開(kāi)呢

kiluv4
回復(fù)

使用道具 舉報(bào)

ID:102293 發(fā)表于 2016-7-11 22:33 | 顯示全部樓層
學(xué)習(xí)學(xué)習(xí),非常感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:129868 發(fā)表于 2016-7-12 10:36 | 顯示全部樓層
來(lái)學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:130791 發(fā)表于 2016-7-17 13:49 | 顯示全部樓層
過(guò)來(lái)學(xué)習(xí)。!
回復(fù)

使用道具 舉報(bào)

ID:134757 發(fā)表于 2016-7-23 21:20 | 顯示全部樓層

學(xué)習(xí)學(xué)習(xí),非常感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:136422 發(fā)表于 2016-8-10 12:54 | 顯示全部樓層
學(xué)習(xí)一下
回復(fù)

使用道具 舉報(bào)

ID:136422 發(fā)表于 2016-8-10 12:55 | 顯示全部樓層
學(xué)習(xí)學(xué)習(xí),非常感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:137635 發(fā)表于 2016-8-26 09:42 | 顯示全部樓層
先收藏了,謝謝樓主
回復(fù)

使用道具 舉報(bào)

ID:128463 發(fā)表于 2016-8-29 17:40 | 顯示全部樓層
很好的資料謝謝分享!!!!
回復(fù)

使用道具 舉報(bào)

ID:138902 發(fā)表于 2016-9-8 23:51 | 顯示全部樓層
謝謝分享。。
回復(fù)

使用道具 舉報(bào)

ID:121470 發(fā)表于 2016-9-28 14:17 | 顯示全部樓層
看得不是很多,學(xué)習(xí)一下
回復(fù)

使用道具 舉報(bào)

ID:149037 發(fā)表于 2016-12-17 14:37 | 顯示全部樓層

學(xué)習(xí)學(xué)習(xí),非常感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:75062 發(fā)表于 2017-1-3 22:24 | 顯示全部樓層
謝謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:162349 發(fā)表于 2017-1-18 21:34 | 顯示全部樓層
感謝樓主
回復(fù)

使用道具 舉報(bào)

ID:166195 發(fā)表于 2017-2-23 15:45 | 顯示全部樓層
已收藏,非常感謝樓主,學(xué)習(xí)中
回復(fù)

使用道具 舉報(bào)

ID:166347 發(fā)表于 2017-2-24 10:24 | 顯示全部樓層
 非常感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:169508 發(fā)表于 2017-3-9 21:57 | 顯示全部樓層
其實(shí)我想知道發(fā)送原理是什么,既然PC可以通過(guò)串口向單片機(jī)發(fā)送信息,能否直接改為由單片機(jī)先模塊發(fā)送信息,不過(guò)失敗了,實(shí)在弄不清原理
回復(fù)

使用道具 舉報(bào)

ID:47286 發(fā)表于 2017-3-10 14:13 | 顯示全部樓層
感謝樓主分享 學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:166895 發(fā)表于 2017-3-27 20:49 | 顯示全部樓層
感謝樓主分享
回復(fù)

使用道具 舉報(bào)

ID:185256 發(fā)表于 2017-4-13 01:13 | 顯示全部樓層
能直接移植到 STM8 上面嗎? 怎么做呢?
回復(fù)

使用道具 舉報(bào)

ID:185256 發(fā)表于 2017-4-13 16:54 | 顯示全部樓層
很好的資料謝謝分享!!!!
回復(fù)

使用道具 舉報(bào)

ID:186249 發(fā)表于 2017-4-14 15:22 | 顯示全部樓層
這個(gè)不錯(cuò),我看看
回復(fù)

使用道具 舉報(bào)

ID:110687 發(fā)表于 2017-4-24 13:03 | 顯示全部樓層
謝謝摟住,謝謝你的共享!在學(xué)習(xí)中。。。。。。
回復(fù)

使用道具 舉報(bào)

ID:196946 發(fā)表于 2017-5-5 15:19 | 顯示全部樓層
感謝分享
回復(fù)

使用道具 舉報(bào)

ID:25518 發(fā)表于 2017-5-29 15:12 | 顯示全部樓層
真心感謝分享。
回復(fù)

使用道具 舉報(bào)

ID:209407 發(fā)表于 2017-6-9 02:31 | 顯示全部樓層
這個(gè)看看,謝謝分享
回復(fù)

使用道具 舉報(bào)

ID:104683 發(fā)表于 2017-6-10 19:42 | 顯示全部樓層
正好學(xué)到 謝謝分享
回復(fù)

使用道具 舉報(bào)

ID:211931 發(fā)表于 2017-6-16 18:46 | 顯示全部樓層
非常感謝樓主的分享
回復(fù)

使用道具 舉報(bào)

ID:215781 發(fā)表于 2017-6-29 12:59 | 顯示全部樓層
很棒,學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:218517 發(fā)表于 2017-7-10 15:13 | 顯示全部樓層
感謝樓主的分享!
回復(fù)

使用道具 舉報(bào)

ID:227029 發(fā)表于 2017-8-11 17:36 | 顯示全部樓層
很給力qqdqdq
回復(fù)

使用道具 舉報(bào)

ID:210861 發(fā)表于 2017-9-6 15:11 | 顯示全部樓層
謝謝樓主的無(wú)私分享。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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