通过互联网络TCP(pc机),远程控制四路继电器开关,和查询四路温度DS18B20传感器的温度
下位机使用的是51单片机
淘宝上淘的TCP转串口模块,和四路继电器模块(底电平触发)
电路上有5个指示灯
分别为:电源指示(通电亮) 运行指示灯(约1秒闪烁一次,表示单片机在工作) 联网指示(收到心跳表示联网,灯亮) 数据收发指示(有数据接收发送,闪烁)
下位机可以有同样的很多个(理论上65535个),为每个下位机编一个ID号来区分。
上位机使用C#语言编写,附件提供源码下载
下位机通电后自动使用TCP Socket连接上位机,指示灯可以观看状态
上位机上可以看到所有连接的下位机
以下位机ID,选择连接的下位机,控制下位机
因为没有那么多的下位机,所以又编了一个下位机的仿真,模仿很多下位机连接上位机
试验己成功!
代码有不合理的地方,谢谢大家纠正
上图
定义数据帧格式
数据帧:一个帧由固定16个字节组成
字节:一个字节由8位二进制组成,取值范围0-255
1、规定:帧头1个字节,定值,二进制11111110,十进制 254,十六进制FE
2、规定:帧尾1个字节,定值,二进制11111111,十进制 255,十六进制FF
3、规定:设备ID_1,1个字节,取值范围0-255
4、规定:设备ID_2,1个字节,取值范围0-255
5、规定:控制位固定4个字节
6、规定:数据位固定8个字节
|
服务端程序框图 停止服务
一、定义设备ID
名称 | ID | 密钥 | 备注 | 服务器端
| { 0,0 }
| 无
| 服务器占用的ID
| 1号终端
| { 0,1 }
| {255,255,255,255,255,1}
|
| 2号终端
| { 0,2 }
| {255,255,255,255,255,2}
|
| 3号终端
| { 0,3 }
| {255,255,255,255,255,3}
|
| 4号终端
| { 0,4 }
| {255,255,255,255,255,4}
|
| 5号终端
| { 0,5 }
| {255,255,255,255,255,5}
|
| 6号终端
| { 0,6 }
| {255,255,255,255,255,6}
|
|
二、定义控制位
名称 | 控制位 | 名称 | 控制位 | 心跳
| {0,0,0,1}
|
|
| 查询设备ID和密钥
| {0,0,0,2}
| 返回设备ID和密钥
| {1,0,0,2}
| 登录成功
| {0,0,0,3}
| 登录失败
| {0,0,0,4}
| 更新用户信息时间
| {0,0,0,9}
| 返回更新用户信息时间
| {1,0,0,9}
| 查询温度1
| {0,0,1,1}
| 返回温度 1
| {1,0,1,1}
| 查询温度2
| {0,0,1,2}
| 返回温度 2
| {1,0,1,2}
| 查询温度3
| {0,0,1,3}
| 返回温度 3
| {1,0,1,3}
| 查询温度4
| {0,0,1,4}
| 返回温度 4
| {1,0,1,4}
| 查询开关1
| {0,0,2,1}
| 返回开关1状态
| {1,0,2,1}
| 查询开关2
| {0,0,2,2}
| 返回开关2状态
| {1,0,2,2}
| 查询开关3
| {0,0,2,3}
| 返回开关3状态
| {1,0,2,3}
| 查询开关4
| {0,0,2,4}
| 返回开关4状态
| {1,0,2,4}
| 设置开关1
| {2,0,2,1}
|
|
| 设置开关2
| {2,0,2,2}
|
|
| 设置开关3
| {2,0,2,3}
|
|
| 设置开关4
| {2,0,2,4}
|
|
|
三、定义数据位
名称 | 数据位 | 说明 | 设备ID和密钥
| {0-255,0-255,0-255,0-255,0-255,0-255,0-255,0-255}
| 前2位是设备ID,后6位是密钥
| 打开开关
| {1,0,0,0,0,0,0,0}
| 1是打开
| 关闭开关
| {2,0,0,0,0,0,0,0}
| 2是关闭
| 返回温度
| {0-255,0-255,0,0,0,0,0,0}
| 前两位分别是DS18B20温度传感器高位和底位
|
单片机源程序如下:
- #include "config.h"
- #include<ds1.h>
- #include<ds2.h>
- #include<ds3.h>
- #include<ds4.h>
- void UART_init();
- void PutFrame(uchar *TXStr);
- void DataFrame_Put_init();
- void TEMP_init_var();
- uchar dataFrame[16]; //定义数据帧长度为16个字节
- uchar dataFrame_RI; //数据帧是否己读取标记
- uchar dataFrame_temp[16]; //数据帧临时缓冲区16个字节
- uchar dataFrame_temp_count; //定义数据帧己接收的字节数
- //定义发送数据缓冲区
- uchar DataFrame_Put[16]={DATAFRAME_HEAD,DEVICEID_1,DEVICEID_2,0,0,0,0,0,0,0,0,0,0,0,0,DATAFRAME_TAIL};
- INT32U led1_count; //运行指示灯倒计时变量
- uchar led1_count2; //运行指示灯倒计时变量2
- INT32U led2_count; //收到心跳倒计时变量
- INT32U led3_count; //有数据接收倒计时变量
- INT32U led4_count; //有数据发送倒计时变量
- #define LED1_COUNT 15000
- #define LED2_COUNT 125000
- #define LED3_COUNT 100
- #define LED4_COUNT 100
- //存储温度的高8位和底8位
- uchar ds_M;
- uchar ds_L;
- //温度变量
- uchar symbol; //符号位
- uchar hundreds; //百位
- uchar decade; //十位
- uchar unit; //个位
- uchar decimal; //小数1位
- void main()
- {
- //串口初始化
- UART_init();
- while(1)
- {
- //调试使用
- //uchar dataFrame[16] = {DATAFRAME_HEAD,DEVICEID_1,DEVICEID_2,0,0,1,1,0,0,0,0,0,0,0,0,DATAFRAME_TAIL};
- //dataFrame_RI = 1; //执行时间2.17微妙
- //如果己接收到一帧数据
- if(dataFrame_RI == 1) // 执行时间5.42微秒
- {
- //收到心跳
- if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 1){
- //收到心跳
- DataFrame_Put[3] = 0;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 0;
- DataFrame_Put[6] = 1;
- PutFrame(&DataFrame_Put);
- led2_count = LED2_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 2){
- //收到查询设备id
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 0;
- DataFrame_Put[6] = 2;
- DataFrame_Put[7] = DEVICEID_1;
- DataFrame_Put[8] = DEVICEID_2;
- DataFrame_Put[9] = 255;
- DataFrame_Put[10] = 255;
- DataFrame_Put[11] = 255;
- DataFrame_Put[12] = 255;
- DataFrame_Put[13] = 002;
- DataFrame_Put[14] = 001;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 0 && dataFrame[6] == 9){
- //收到更新用户信息时间,返回
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 0;
- DataFrame_Put[6] = 9;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 1){ // 执行时间15.19 微秒
- //查询温度1:0 0 1 1
- TEMP_init_var();
- DS1_ReadWeather(&ds_M,&ds_L);
- Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 1;
- DataFrame_Put[6] = 1;
- DataFrame_Put[7] = symbol;
- DataFrame_Put[8] = hundreds;
- DataFrame_Put[9] = decade;
- DataFrame_Put[10] = unit;
- DataFrame_Put[11] = decimal;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 2){
- //查询温度2:0 0 1 2
- TEMP_init_var();
- DS2_ReadWeather(&ds_M,&ds_L);
- Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 1;
- DataFrame_Put[6] = 2;
- DataFrame_Put[7] = symbol;
- DataFrame_Put[8] = hundreds;
- DataFrame_Put[9] = decade;
- DataFrame_Put[10] = unit;
- DataFrame_Put[11] = decimal;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 3){ // 执行时间15.19 微秒
- //查询温度3:0 0 1 3
- TEMP_init_var();
- DS3_ReadWeather(&ds_M,&ds_L);
- Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 1;
- DataFrame_Put[6] = 3;
- DataFrame_Put[7] = symbol;
- DataFrame_Put[8] = hundreds;
- DataFrame_Put[9] = decade;
- DataFrame_Put[10] = unit;
- DataFrame_Put[11] = decimal;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 1 && dataFrame[6] == 4){
- //查询温度4:0 0 1 4
- TEMP_init_var();
- DS4_ReadWeather(&ds_M,&ds_L);
- Convert_DS_weather(ds_M, ds_L, &symbol, &hundreds, &decade, &unit, &decimal);
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 1;
- DataFrame_Put[6] = 4;
- DataFrame_Put[7] = symbol;
- DataFrame_Put[8] = hundreds;
- DataFrame_Put[9] = decade;
- DataFrame_Put[10] = unit;
- DataFrame_Put[11] = decimal;
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 1){
- //查询开关1
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 2;
- DataFrame_Put[6] = 1;
- if(SW1 == 0){
- DataFrame_Put[7] = 1;
- }else{
- DataFrame_Put[7] = 2;
- }
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 2){
- //查询开关2
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 2;
- DataFrame_Put[6] = 2;
- if(SW2 == 0){
- DataFrame_Put[7] = 1;
- }else{
- DataFrame_Put[7] = 2;
- }
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 3){
- //查询开关3
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 2;
- DataFrame_Put[6] = 3;
- if(SW3 == 0){
- DataFrame_Put[7] = 1;
- }else{
- DataFrame_Put[7] = 2;
- }
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 0 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 4){
- //查询开关3
- DataFrame_Put[3] = 1;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 2;
- DataFrame_Put[6] = 4;
- if(SW4 == 0){
- DataFrame_Put[7] = 1;
- }else{
- DataFrame_Put[7] = 2;
- }
- PutFrame(&DataFrame_Put);
- led3_count = LED3_COUNT;
- led4_count = LED4_COUNT;
- }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 1){
- //设置开关1
- if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW1 = 0;
- }
- else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW1 = 1;
- }
- led3_count = LED3_COUNT;
- }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 2){
- //设置开关2
- if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW2 = 0;
- }
- else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW2 = 1;
- }
- led3_count = LED3_COUNT;
- }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 3){
- //设置开关3
- if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW3 = 0;
- }
- else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW3 = 1;
- }
- led3_count = LED3_COUNT;
- }else if(dataFrame[3] == 2 && dataFrame[4] == 0 && dataFrame[5] == 2 && dataFrame[6] == 4){
- //设置开关4
- if(dataFrame[7] == 1 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW4 = 0;
- }
- else if(dataFrame[7] == 2 && dataFrame[8] == 0 && dataFrame[9] == 0 && dataFrame[10] == 0 && dataFrame[11] == 0 && dataFrame[12] == 0 && dataFrame[13] == 0 && dataFrame[14] == 0){
- SW4 = 1;
- }
- led3_count = LED3_COUNT;
- }
- dataFrame_RI = 0; //置数据帧己读取
- DataFrame_Put_init(); //初始化发送帧,为下一次发送数据做准备
- }
- //LED1运行指示灯闪烁,整个循环在没有接收数据时,执行一次约40us
- if(led1_count > 0){
- led1_count--;
- }else{
- if(led1_count2 == 0){
- led1_count2 = 1;
- }else{
- led1_count2 = 0;
- }
- led1_count = LED1_COUNT;
- }
- if(led1_count > 0){
- if(led1_count2 == 0){
- LED1 = 0;
- }else{
- LED1 = 1;
- }
- led1_count--;
- }
- //收到心跳灯亮20秒
- if(led2_count > 0){
- LED2 = 0;
- led2_count--;
- }else{
- LED2 = 1;
- }
- //有数据接收闪一下
- if(led3_count > 0){
- LED3 = 0;
- led3_count--;
- }else{
- LED3 = 1;
- }
- //有数据发送闪一下
- if(led4_count > 0){
- LED4 = 0;
- led4_count--;
- }else{
- LED4 = 1;
- }
- }
- while(1);
- }
- //初始化输出帧
- void DataFrame_Put_init(){
- DataFrame_Put[3] = 0;
- DataFrame_Put[4] = 0;
- DataFrame_Put[5] = 0;
- DataFrame_Put[6] = 0;
- DataFrame_Put[7] = 0;
- DataFrame_Put[8] = 0;
- DataFrame_Put[9] = 0;
- DataFrame_Put[10] = 0;
- DataFrame_Put[11] = 0;
- DataFrame_Put[12] = 0;
- DataFrame_Put[13] = 0;
- DataFrame_Put[14] = 0;
- }
- //初始化温度值
- void TEMP_init_var(){
- ds_M = 0;
- ds_L = 0;
- symbol = 0; //符号位
- hundreds = 0; //百位
- decade = 0; //十位
- unit = 0; //个位
- decimal = 0; //小数1位
- }
- //初始化
- void UART_init()
- {
- TMOD = 0x20; //T1工作模式2 8位自动重装
- TH1 = 0xfd;
- TL1 = 0xfd; //比特率9600
- TR1 = 1; //启动T1定时器
- SM0 = 0;
- SM1 = 1; //串口工作方式1 10位异步
- REN = 1; //串口允许接收
- EA = 1; //开总中断
- ES = 1; //串口中断打开
- }
- //串口发送一帧数据函数,一帧16个字节
- void PutFrame(uchar *TXStr)
- {
- uchar i = 0;
- while(1){
- SBUF=*TXStr;
- while(TI == 0); //对方接收后TI置1,停止等待
- TI = 0;
- i++;
- if(i > 15){break;}
- TXStr++;
- }
- }
- void UART() interrupt 4
- {
- if(RI) //检测是否接收完成
- {
- uchar temp = SBUF;
- RI = 0;
- // 如果接收的一帧,第一个字节不是包头标志,则抛弃这个字节
- if(dataFrame_temp_count == 0)
- {
- if(temp != DATAFRAME_HEAD)
- return;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码 C#上位机源码资料包:
所有资料51hei提供下载:
温度检查.rar
(851 KB, 下载次数: 142)
|