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

  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

时间: 2025-02-01 12:00:39

局域网控制系统-下位机-单片机的相关文章

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

.java文件源码(供参考,请使用前自行作修改): 1 package com.example.hello; 2 3 import java.io.DataInputStream; 4 import java.io.DataOutputStream; 5 import java.io.IOException; 6 import java.net.Socket; 7 import java.util.Timer; 8 import java.util.TimerTask; 9 10 import

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

C#程序代码: 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.IO.Ports; 10 //using System

下位机单片机c语言发送数据到串口,上位机pc机java语言获取端口数据

环境: Windows7 64b,jdk64b,myeclipse8.5,rxtx开发包,STC,keil,格西烽火,51单片机,rs232USB转串口线. 下位机c代码 #include <reg51.h> #include <string.h> #define INBUF_LEN 7   //数据长度 unsigned char inbuf1[INBUF_LEN]; unsigned char checksum,count3,count=0; bit           rea

上位机 下位机

上位机是指:人可以直接发出操控命令的计算机,一般是PC,屏幕上显示各种信号变化(液压,水位,温度等).下位机是直接控制设备获取设备状况的的计算机,一般是PLC/单片机之类的.上位机发出的命令首先给下位机,下位机再根据此命令解释成相应时序信号直接控制相应设备.下位机不时读取设备状态数据(一般模拟量),转化成数字信号反馈给上位机.简言之如此,真实情况千差万别不离其宗.上下位机都需要编程,都有专门的开发系统. 在概念上 控制者和提供服务者是上位机 被控制者和被服务者是下位机 也可以理解为主机和从机的关

串口操作包括 java上位机 嵌入式c下位机

一环境 1.1 Keil uVision4 http://pan.baidu.com/s/1o6A331w 1.2 STC http://pan.baidu.com/s/1jGpCUTC 1.3 Myeclipse 8.5 http://pan.baidu.com/s/1jGABEaM 1.4 需导入的jar包RXTX http://pan.baidu.com/s/1ntwsvRr 首先把rxtxParallel.dll和rxtxSerial.dll复制到jdk目录的bin目录下面 然后把RXT

5.23-ROSARIA下位机使用

前言 基础:下位机配置 前言使用记录环境搭建基础:ssh使用基础:netcat基础:secureCRT(多标签ssh)后续工作 TOC 使用记录 环境搭建 sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev sudo apt-get install ros-indigo-move-base 配置激光ip地址:192.168.0.4 mask:192.168.0.0 gateway:192.168.0.1 安装其他库,编译文件代码 /Ros

ROS主题发布订阅控制真实的机器人下位机

先模拟控制小乌龟 新建cmd_node.ccpp文件: #include"ros/ros.h" #include"geometry_msgs/Twist.h" //包含geometry_msgs::Twist消息头文件 #include <stdlib.h> #include<stdlib.h> int main(int argc, char **argv) { ros::init(argc, argv, "cmd_node&quo

MSP430G2333下位机乘法运算需要注意的一个问题

背景: 最近负责为主板管理电源的电源管理模块编写软体,使用的MCU为MSP430G2333.功能上很简单,即通过板子上的硬件拨码设定,或者通过IIC与主板通信,由主板的BIOS决定开机及关机的延时供电时间. 正文: 所有功能均按预期实现,但有一个bug在最后蹦了出来,即在延时关机设定时,明明设定为15.18.48个小时,却每次在9个多小时的时候,电源被执行关闭动作.9个多小时,很有意思的数字.不用深究,问题直接锁定在时间比对函数内. 1 // when the current time less

6.PMAC下位机-下位机编程

PMAC的下位机编程包括三种程序:命令序列程序.运动(Program)程序和PLC程序. PMAC中编写程序,直接在File->new新建文件会打开编辑器,所有文件为PMC后缀. 查看当前程序可以在File->Uplaod Programs查看当前已有的Program程序和PLC程序及他们的编号.状态. 1.命令序列程序 上节讲到,PMAC卡中可以使用手动操作,在命令行设置参数状态.控制电机等,但是它一次只能发送一条命令,那么为了一次性运行多个命令序列,即可在PMC程序中如下编写: i620=