原創:局域網控制系統-下位機-單片機

  1 /*-----------------------------------
  2            多功能下位機
  3     STC89C52RC   11.0592MHz
  4 
  5 -----------------------------------*/
  6 #include<reg52.h>
  7 #include<intrins.h> 
  8 
  9 char code huanhang[3]={0x0d,0x0a,0};   //  "\r\n"
 10 //-----------------普通輸出端口---------------//
 11 sbit LED0=P1^0;
 12 sbit LED1=P1^1;
 13 sbit LED2=P1^2;
 14 sbit jdq_00=P1^3;
 15 sbit fmq_00=P2^5;
 16 
 17 /**********DS18B20***********/
 18 bit Temp_Symbol=0;
 19 //溫度傳感_0---------
 20 sbit DQ=P2^6;
 21 //------------------串口通訊協議-----------------//
 22 /*
 23     客戶端數據包格式解釋(長度恆爲15):
 24     例如:A01_fmq_01Off___#
 25     A--------數據包的開始標記(能夠爲A到Z)
 26     01-----設備代號
 27     fmq_01Off___--------指令(長度恆爲10),指令的前4我的字符是指令頭部,指令的後6個字符是指令尾部
 28     #---------數據包的結束標記
 29 
 30     服務器端數據包格式解釋(長度恆爲15):
 31     例如:A02_SenT010250#
 32     A--------數據包的開始標記(能夠爲A到Z)
 33     02-----設備代號
 34     SenT010250--------指令(長度恆爲10),指令的前4我的字符是指令頭部,指令的後6個字符是指令尾部
 35     #---------數據包的結束標記
 36 */
 37 char buf_string[16];  //定義數據包長度爲15個字符
 38 #define deviceID_1Bit '0'                //用於串口通訊時,定義本地設備ID的第1位
 39 #define deviceID_2Bit '2'                //用於串口通訊時,定義本地設備ID的第2位
 40 #define datapackage_headflag 'A'        //用於串口通訊時,定義數據包頭部的驗證標記
 41 
 42 char DataPackage_DS18B20[16]={datapackage_headflag,deviceID_1Bit,deviceID_2Bit,'_','S','e','n','T','_','_','_','_','_','_','#'};
 43 char HeartBeat[16]={datapackage_headflag,deviceID_1Bit,deviceID_2Bit,'_','B','e','a','t','_','_','_','_','_','_','#'};
 44 //----------------------------------------------//
 45 
 46 /**************************
 47         輔助函數
 48 ***************************/
 49 //改變要發送的DS18B20數據包
 50 void Change_DataPackage_DS18B20(int DS18B20_Value)
 51 {
 52     if(Temp_Symbol)
 53     {
 54         DataPackage_DS18B20[10] = '-'; 
 55     }
 56     else
 57     {
 58         DataPackage_DS18B20[10] = '0'; 
 59     }              
 60     DataPackage_DS18B20[11] = 0x30+DS18B20_Value % 10000 / 1000;     
 61     DataPackage_DS18B20[12] = 0x30+DS18B20_Value % 1000 / 100;       
 62     DataPackage_DS18B20[13] = 0x30+DS18B20_Value % 100 / 10;  
 63 }
 64 /********************************
 65             DS18B20
 66     若沒有效果,意味着延時可能有問題
 67     測溫範圍 -55℃~+125℃
 68 
 69           單線通訊接口
 70     1)邊沿=觸發    
 71     2)電平持續時間=信息
 72     3)一字節的電平組合=指令
 73 ********************************/
 74 //延時------
 75 void delay_DS18B20(unsigned int t)
 76 {
 77   for (;t>0;t--);
 78 }
 79 //復位,使得從設備能夠接收指令-----------
 80 void Reset_DS18B20()
 81 {
 82     char presence=1;
 83     while(presence)
 84     {
 85         while(presence)
 86         {    
 87             DQ=1;_nop_();_nop_();//從高拉倒低
 88             DQ=0;                                       
 89             delay_DS18B20(50);           //550 us
 90             DQ=1;                                        
 91             delay_DS18B20(6);            //66 us
 92             presence=DQ;         //presence=0 復位成功,繼續下一步
 93         } 
 94         delay_DS18B20(45);            //延時500 us
 95         presence=~DQ;         
 96     }
 97     DQ=1;                   //拉高電平
 98 }
 99 //寫DS一個字節數據----------
100 void WriteByte_DS18B20(unsigned char val)
101 { 
102     unsigned char i;
103     for(i=8;i>0;i--)
104     {
105         DQ=1;_nop_();_nop_();                  //從高拉倒低
106         DQ=0;_nop_();_nop_();_nop_();_nop_();  //5 us
107         DQ=val&0x01;                           //最低位移出
108         delay_DS18B20(6);                      //66 us
109         val=val/2;                             //右移1位
110     }
111     DQ=1;
112     delay_DS18B20(1);
113 }
114 //讀DS一個字節數據---------
115 unsigned char ReadByte_DS18B20()
116 {
117     unsigned char i;
118     unsigned char byte=0;
119     for(i=8;i>0;i--)
120     {
121         DQ=1;_nop_();_nop_();
122         byte>>=1;
123         DQ=0;_nop_();_nop_();_nop_();_nop_();         //4 us
124         DQ=1;_nop_();_nop_();_nop_();_nop_();         //4 us
125         if(DQ)byte|=0x80;
126         delay_DS18B20(6);                            //66 us
127     }
128     DQ=1;
129     return(byte);
130 }
131 //讓DS18B20測量一次溫度,並將測量結果存放在其內部RAM----------
132 void  MeasureTemp_DS18B20()
133 {
134     Reset_DS18B20();
135     delay_DS18B20(200);
136     WriteByte_DS18B20(0xcc);        //發送無條件選中命令,選中總線上僅有的DS18B20從設備         
137     WriteByte_DS18B20(0x44);        //溫度轉換命令
138    
139 }
140 //向DS18B20請求讀取溫度值--------------
141 void  ReadTemperature_DS18B20()
142 {    
143     Reset_DS18B20();
144     delay_DS18B20(1);
145     WriteByte_DS18B20(0xcc);     //發送無條件選中命令,選中總線上僅有的DS18B20從設備
146     WriteByte_DS18B20(0xbe);     //發送讀取溫度命令
147 }
148 //獲取並返回DS18B20內部溫度測量值--------
149 int GetTemperature_DS18B20()
150 {
151     int temp=0;
152     unsigned char temperature_H,temperature_L;     //須要連續讀取2個字節數據並進行處理,才能得出一次溫度值
153     MeasureTemp_DS18B20();                 //先寫入轉換命令
154     ReadTemperature_DS18B20();            //而後等待轉換完後發送讀取溫度命令
155     temperature_L=ReadByte_DS18B20();        //讀取溫度值共16位,先讀低字節
156     temperature_H=ReadByte_DS18B20();        //再讀高字節
157     temp=temperature_H;
158     temp<<=8;
159     temp|=temperature_L;
160     if(temp<0)                //當溫度值爲負數(高5位爲符號位)
161       {        
162            temp=~temp;
163         temp=temp+1;
164         temp=0.0625*temp*100+0.5;    //temp*100 意味着取2位小數,  +0.5 意味着四捨五入
165         Temp_Symbol=1;
166       }
167      else            //當溫度值爲正數
168       {            
169         temp=0.0625*temp*100+0.5;    
170         Temp_Symbol=0; 
171     }               
172     return temp;
173 }
174 /*******************************
175             串口通訊
176     MCU:89C52RC        11.0592MHz
177 
178 //11.0592MHz 0xd0 1200bps
179 //12MHz 0xcc 1200bps
180 //11.0592MHz 0xfa 9600bps
181 //0xf4 11.0592MHz  0xf3 12MHz 4800bps
182 //均在SMOD=1的狀況下(波特率倍增模式)
183 *******************************/
184 //串口發送函數
185 void PutString(unsigned char *TXStr)  
186 {                
187     ES=0;     
188      while(*TXStr!=0) 
189     {                      
190         SBUF=*TXStr;
191         while(TI==0);
192         TI=0;    
193         TXStr++;
194     }
195     ES=1; 
196 }                                                     
197 //串口接收函數
198 bit ReceiveString()    
199 {
200     char * RecStr=buf_string;
201     char num=0;
202     unsigned char count=0;
203     loop:    
204     *RecStr=SBUF;
205     count=0;
206     RI=0;    
207     if(num<14)  //數據包長度爲15個字符,嘗試連續接收15個字符
208     {
209         num++;
210         RecStr++;    
211         while(!RI)
212         {
213             count++;
214             if(count>130)return 0;    //接收數據等待延遲,等待時間過久會致使CPU運算閒置,過短會出現"數據包被分割",默認count=130
215         }
216         goto loop;
217     }
218     return 1;
219 }
220 //定時器1用做波特率發生器
221 void Init_USART()  
222 {
223     SCON=0x50;  //串口方式1,使能接收
224     TMOD|=0x20;  //定時器1工做方式2(8位自動重裝初值)
225     TMOD&=~0x10;
226     TH1=0xfa;   //9600bps
227     TL1=0xfa;  
228     PCON|=0x80;  //SMOD=1
229     TR1=1;
230     TI=0;
231     RI=0;
232     //PS=1;   //提升串口中斷優先級
233     ES=1;  //開啓串口中斷使能
234 }
235 //比較指令頭部
236 bit CompareCMD_head(char CMD_head[])    
237 {
238     unsigned char CharNum;
239     for(CharNum=0;CharNum<4;CharNum++)  //指令長度爲10個字符
240     {
241         if(!(buf_string[CharNum+4]==CMD_head[CharNum]))
242         {
243             return 0;  //指令頭部匹配失敗
244         }
245     }
246     return 1;        //指令頭部匹配成功
247 }
248 //比較指令尾部(start:從哪裏開始比較,quality:比較多少個字符,CMD_tail[]:要比較的字符串)
249 bit CompareCMD_tail(unsigned char start,unsigned char quality,char CMD_tail[]) 
250 {
251     unsigned char CharNum;
252     for(CharNum=0;CharNum<quality;CharNum++)
253     {
254         if(!(buf_string[start+CharNum]==CMD_tail[CharNum]))
255         {
256             return 0; 
257         }
258     }
259     return 1;
260 }
261 //處理串口接收數據包函數(成功處理數據包則返回1,不然返回0)
262 bit Deal_UART_RecData()   
263 {
264     //PutString(buf_string);
265     if(buf_string[0]==datapackage_headflag&&buf_string[14]=='#')  //進行數據包頭尾標記驗證
266     {        
267         switch(buf_string[1])        //識別發送者ID的第1位數字
268         {
269             case '0':
270                 switch(buf_string[2])        //識別發送者ID的第2位數字
271                 {
272                     case '3':
273                         if(CompareCMD_head("Ligt"))    //判斷指令頭部是否爲"Ligt"
274                         {
275                             //下面是指令尾部分析
276                             switch(buf_string[8])
277                             {
278                                 case '0':
279                                     switch(buf_string[9])
280                                     {
281                                         case '0':            
282                                             if(CompareCMD_tail(10,3,"Off"))       //A03_Ligt01Off_#
283                                             {
284                                                 LED0=1;
285                                                 return 1;
286                                             }
287                                             if(CompareCMD_tail(10,3,"On_"))
288                                             {
289                                                 LED0=0;
290                                                 return 1;
291                                             }
292                                             return 0;
293                                         case '1':
294                                             if(CompareCMD_tail(10,3,"Off"))       //A03_Ligt01Off_#
295                                             {
296                                                 LED1=1;
297                                                 return 1;
298                                             }
299                                             if(CompareCMD_tail(10,3,"On_"))
300                                             {
301                                                 LED1=0;
302                                                 return 1;
303                                             }
304                                             return 0;
305                                         case '2':
306                                             if(CompareCMD_tail(10,3,"Off"))       //A03_Ligt01Off_#
307                                             {
308                                                 LED2=1;
309                                                 return 1;
310                                             }
311                                             if(CompareCMD_tail(10,3,"On_"))
312                                             {
313                                                 LED2=0;
314                                                 return 1;
315                                             }
316                                             return 0;
317                                         default:
318                                             return 0;
319                                     }                                                    
320                                 default:
321                                     return 0;
322                             }            
323                         }
324                         if(CompareCMD_head("SenT"))  
325                         {
326                             //下面是指令尾部分析
327                             DataPackage_DS18B20[8]=buf_string[8];
328                             DataPackage_DS18B20[9]=buf_string[9];
329                             switch(buf_string[8])    
330                             {
331                                 case '0':
332                                     switch(buf_string[9])    
333                                     {
334                                         case '0':    
335                                             Change_DataPackage_DS18B20(GetTemperature_DS18B20());
336                                             PutString(DataPackage_DS18B20);
337                                             return 1;
338                                         default:
339                                             return 0;
340                                     }
341                                 default:
342                                     return 0;
343                             }    
344                             
345                         }
346                         if(CompareCMD_head("jdq_"))  
347                         {
348                             //下面是指令尾部分析
349                             switch(buf_string[8])    
350                             {
351                                 case '0':
352                                     switch(buf_string[9])    
353                                     {
354                                         case '0':    
355                                             if(CompareCMD_tail(10,3,"Off"))
356                                             {
357                                                 jdq_00=1;
358                                                 return 1;
359                                             }
360                                             if(CompareCMD_tail(10,3,"On_"))
361                                             {
362                                                 jdq_00=0;
363                                                 return 1;
364                                             }
365                                             
366                                             return 0;
367                                         default:
368                                             return 0;
369                                     }
370                                 default:
371                                     return 0;
372                             }
373                         }
374                         if(CompareCMD_head("fmq_"))  
375                         {
376                             //下面是指令尾部分析
377                             switch(buf_string[8])    
378                             {
379                                 case '0':
380                                     switch(buf_string[9])    
381                                     {
382                                         case '0':    
383                                             if(CompareCMD_tail(10,3,"Off"))
384                                             {
385                                                 fmq_00=1;
386                                                 return 1;
387                                             }
388                                             if(CompareCMD_tail(10,3,"On_"))
389                                             {
390                                                 fmq_00=0;
391                                                 return 1;
392                                             }
393                                             
394                                             return 0;
395                                         default:
396                                             return 0;
397                                     }
398                                 default:
399                                     return 0;
400                             }
401                         }
402                         if(CompareCMD_head("Try!"))  
403                         {
404                             PutString(HeartBeat);
405                             return 1;
406                         }
407                         
408                         return 0;
409                     
410                     default:
411                         return 0;
412                 }
413             default:
414                 return 0;
415         }
416     }
417     return 0;
418 }
419 /************************
420         中斷函數
421 ************************/
422 //串口中斷服務函數-----------
423 void USART() interrupt 4   //標誌位TI和RI須要手動復位,TI和RI置位共用一箇中斷入口
424 {
425     if(ReceiveString())    
426     {
427         //數據包長度正確則執行如下代碼
428         Deal_UART_RecData();   
429     }
430     else
431     {
432         //數據包長度錯誤則執行如下代碼
433         //LED1=~LED1;                
434     }
435     RI=0;  //接收並處理一次數據後把接收中斷標誌清除一下,拒絕響應在中斷接收忙的時候發來的請求
436 }
437 /***************************
438         主函數
439 ***************************/
440 //空格20H,回車0DH,'\n'對應ASCLL碼:0x0a
441 void main()
442 {    
443     EA=1;
444     Init_USART();
445     while(1)
446     {
447 
448     }
449 }       

硬件電路要求不高,準備好一個51最小系統,外加一些本身想要的外圍設備,固然最重要的是準備一個透傳模塊(ESP8266),其電路接法以下:html

這個模塊具體有什麼用呢?服務器

簡單來講就是這個模塊能夠跟單片機進行串口通訊,也能夠跟其它終端進行socket通訊,那麼咱們如今就是利用其跟手機進行socket通訊,接收手機的數據,再把數據發送到單片機,實現手機控制單片機。而手機是以客戶端的形式與透傳模塊ESP8266進行鏈接,所以咱們須要對ESP8266進行簡單的配置,才能保證手機能跟ESP8266進行鏈接,具體作法請自行百度。socket

請另外觀看項目的2個部分:函數

1)局域網控制系統-上位機-Android手機oop

2)局域網控制系統-上位機-PC機spa

讓咱們從項目,從代碼中能夠更快地提升本身!code

尊重做者的勞動,轉載請記得註明來源:http://www.cnblogs.com/weifeng727/p/5618062.htmlhtm

相關文章
相關標籤/搜索