原创:局域网控制系统-下位机-单片机

  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),其电路接法如下:

这个模块具体有什么用呢?

简单来说就是这个模块可以跟单片机进行串口通信,也可以跟其它终端进行socket通信,那么我们现在就是利用其跟手机进行socket通信,接收手机的数据,再把数据发送到单片机,实现手机控制单片机。而手机是以客户端的形式与透传模块ESP8266进行连接,因此我们需要对ESP8266进行简单的配置,才能保证手机能跟ESP8266进行连接,具体做法请自行百度。

请另外观看项目的2个部分:

1)局域网控制系统-上位机-Android手机

2)局域网控制系统-上位机-PC机

让我们从项目,从代码中可以更快地提高自己!

尊重作者的劳动,转载请记得注明来源:http://www.cnblogs.com/weifeng727/p/5618062.html

posted @ 2016-06-26 16:13  weifeng727  阅读(1681)  评论(0编辑  收藏  举报