基于51单片机的无线测温系统

本51项目基于STC89C52MCU,温度传感器为DS18B20,显示模块用的是LCD1602,无线模块用的是Nodemcu。

项目用到的编程语言:C,C++,Lua。

实现思路是这样,DS18B20测温,然后数据串行传送给51单片机,然后51通过串口将数据传送给Nodemcu,Nodemcu通过其WIFI模块将数据发送给上位机,上位机上的程序是用Qt编写的GUI。(这里无线传输采用的是无连接的UDP协议)

1.DS18B20温度测量模块

DS18B20是单总线器件,所以时序要求非常严格,程序编写时注意时序,否则读不出温度。DS18B20有寄生供电和单独供电,这里采用单独供电方式。它的驱动程序如下:

#include"Temp.h"
void delay1ms(unsigned int y)
{
unsigned int x;
for( ; y>0; y--)
{
for(x=110; x>0; x--);
}
}

void Init18b20(){
int i;
DQ=0;
i=60;
while(i--);   //10us左右,一共延时60*10=600us左右。
DQ=1;

while(DQ)
{
i=1;
while(i--); 
}

}

void Writeonebyte(unsigned char ins){
int i=0;
int j=0;
for(i=0;i<8;i++){
DQ=0;
j++;                   //延时1us
DQ=0x01&ins;   //写0或者1,写完以后保持,15us内DS18B20会来采集数据。
j++;
j=6;
while(j--);           //一个写周期至少60us。

DQ=1;                //释放数据线

ins=ins>>1;      //写下一位数据

}
}

unsigned char Readonebyte(){
int i=0;
int j=0;
unsigned char bi, byte;
for(i=0;i<8;i++){
DQ=0; 
j++;
DQ=1;              //拉低1us后释放,给一个准备读的信号
j++;
j++;
bi=DQ;             
byte=(byte>>1)|(bi<<7);    //读取8位数据
j=5;
while(j--);
}
return byte;
}

void Tempconvert(){
Init18b20();
delay1ms(1); 
Writeonebyte(0xcc);
Writeonebyte(0x44);
}

void Readrom(){
Init18b20();
delay1ms(1);
Writeonebyte(0xcc);
Writeonebyte(0xbe);
}

int Readtemp(){
int temp;
unsigned char tml,tmh;
Tempconvert();
Readrom();
tml=Readonebyte();
tmh=Readonebyte();
temp=tmh;
temp=temp<<8;
temp=temp|tml;
return temp;
}

头文件

#include"reg52.h"
sbit DQ=P1^0;
void Init18b20();
void Writeonebyte(char ins);
unsigned char Readonebyte();
void Tempconvert();
void Readrom();
int Readtemp();
void delay1ms();

2.LCD1602显示模块

这个模块比较简单,注意时序,然后初始化函数里面不要写清屏指令,以免显示的数据一直闪烁。

#include"lcd1602.h"
char init[]="Temp ";
void delay1ms()   //误差 -0.651041666667us
{
    unsigned char a,b;
    for(b=102;b>0;b--)
        for(a=3;a>0;a--);
}

void delay5ms()   //误差 -0.000000000001us
{
    unsigned char a,b;
    for(b=15;b>0;b--)
        for(a=152;a>0;a--);
}
void writecom(int com){
E=0;
RS=0;
RW=0;
P0=com;     //并行送数据
delay1ms(); //送完后保持一下 使其稳定
E=1;           //拉高,让数据发送
delay5ms();
E=0;
}
void writedat(char dat){
E=0;
RS=1;
RW=0;
P0=dat;
delay1ms();
E=1;
delay5ms();
E=0;
}
void lcdinit(){
int i=0;
delay1ms();
writecom(0x06);
writecom(0x0c);
delay1ms();
writecom(0x38);
writecom(0xc3);
for(i=0;i<5;i++)
writedat(init[i]);
}

头文件

#include<reg52.h>
sbit RS=P2^0;
sbit RW=P2^1;
sbit E=P2^2;
void delay1ms();
void delay5ms();
void lcdinit();
void writecom(int com);
void writedat(char dat);

3.Nodemcu模块

手里只有这个MCU,没有ESP8266。其实差不多,Nodemcu就是一个ESP8266的小系统板,然后将一些资源进行二次封装,然后用Lua语言开发。如果是单独的ESP8266模块,就用串口 AT指令调试。 相同的是一开始都要烧固件进去,固件可以自己选,模块都在github上。这个Nodemcu三种工作方式 STA ,AP,STA+AP。 STA模式就是可以像手机一样接到你的路由器上,然后你可以用你的手机电脑通过网络来操纵。AP就是这个模块成为一个热点,你手机电脑可以连接上这个热点,这种方式适用于局域网。STA+AP是都可以的。本次项目使用STA模式。

代码如下

print(‘Setting up WIFI...‘)
wifi.setmode(wifi.STATION)
wifi.sta.config(‘AP‘, ‘SSID‘)
wifi.sta.connect()

tmr.alarm(1, 1000, tmr.ALARM_AUTO, function()
    if wifi.sta.getip() == nil then
        print(‘Waiting for IP ...‘)
    else
        print(‘IP is ‘ .. wifi.sta.getip())
    tmr.stop(1)
    end
end)

cu=net.createConnection(net.UDP, 0)
cu:connect(9999,"ip")
cu:on("receive",function(cuk,c) print(c) end )

uart.setup(0,9600,8,0,1,0)
uart.on("data",
function(data)
print("receive from uart:", data) 
cu:send(data)
end, 0)

这里要注意的是你烧进去的第一个程序,名字必须是init.lua 它上电是从这个文件开始执行的。

最后一点

各个模块的组合,即C语言主函数如下

#include"Temp.h"
#include"lcd1602.h"
#include<reg52.h>
void dlay1ms(int y)
{
int x;
for( ; y>0; y--)
{
for(x=110; x>0; x--);
}
}
void Serialinit(){
TMOD=0x20;
TH1=0XFD;
TL1=0XFD;
TR1=1;
SCON=0x50;    //配置好串口,这里波特率为9600. 只用定时器和串口,不用中断。
}

char list[11]={‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘,‘.‘};
char value[4];
int i=0;

void Datapros(int temp){
float fp;
fp=temp;
temp=fp*0.0625*100;     //注意 0.0625*temp是温度,但是乘出来的可能是带小数部分的,你要先把temp变成带小数的,再乘0.0625,否则乘出来的小数部分就被类型转换截掉了。
value[0]=list[temp/1000];
value[1]=list[temp%1000/100];
value[2]=list[10];
value[3]=list[temp%100/10];      //显示一位小数,这种显示算法对数码管也通用。

}

void Lcddisplay(){
lcdinit();
writedat(value[0]);
dlay1ms(20);
writedat(value[1]);
dlay1ms(20);
writedat(value[2]);
dlay1ms(20);
writedat(value[3]);
dlay1ms(20);
}

int main(){
Serialinit();
while(1){
Datapros(Readtemp());
Lcddisplay();
for(i=0;i<4;i++)
{
SBUF=value[i];    //启动串口传输,51单片机的TXD RXD接到Nodemcu上的TX RX上。
while(!TI);
TI=0;
}
}
}

上位机界面用Qt编写。

代码就不贴出来了。效果图已经上传。

整个项目做完以后的总结与不足。

总结:DS18B20时序一定要特别注意。Lcd如果添加了清屏指令,显示温度会闪烁。Nodemcu第一个程序名一定是init.lua。烧写工作有好几种,自己选择。Lua语言需要了解一下,Nodemcu的API需要了解一下。然后就是Qt写的GUI,里面用到的UDP协议,端口和IP要对应好,不然接收不到数据。

不足: DS18B20可以用寄生方式供电,这个我不是很了解,下次可以尝试寄生供电方式工作,这个适合远距离测温。无线数据传说部分可以用更可靠的TCP协议来传输,这个必须要会,下次会尝试使用这个协议来编写上位机程序。采集到的温度没有进行处理,只用来显示了,希望在学习数据库以后加入数据的存储筛选功能。

原文地址:https://www.cnblogs.com/crenx/p/8453799.html

时间: 2024-10-12 17:45:20

基于51单片机的无线测温系统的相关文章

基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目

一.前言 1.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目包括用Keil软件编写单片机C语言程序和用Proteus软件仿真单片机外围电路 2.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目构思 (1).声明程序变量思维导图 (2).程序子函数思维导图 (3).程序主函数思维导图 二.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目的Keil软件编写的单片机C语言程序 1 #include<reg52.h>//声明51单片机

[原创]基于51单片机的红外遥控课程设计

[注]: 一眨眼,大学接近尾声,具有找工作需要,所以把大学做的电子设计“劣作”放上来.希望考研失意,还能赶上“好工作”的春招班车.如果大伙有什么工作推荐也可以联系我哦,因为一年考研少接触了这方面,所以难免有些生疏.但请相信我!给我机会我会很认真学的! 邮箱:[email protected] 转载请注明出处呀! 基于51单片机的红外遥控课程设计 目录 第一章 设计简介... 3 第二章 系统方案... 3 一.设计方案对比... 3 二.方案设计... 4 第三章 硬件设计... 5 一.红外遥

基于51单片机的温度控制系统毕设

分享一下单片机毕设课程计参考资料33个,献给大四的朋友,毕业设计就不用愁了,如果有什么不懂的地方可以加群大家一起交流:813238832资料下载的地址:https://bbs.usoftchina.com/thread-208012-1-1.html 1.CDMA通信系统中的接入信道部分进行仿真与分析2.USB接口设计3.毕业设计(论文)OFDM通信系统基带数据4.电气工程系毕业设计开题报告5.电信运营商收入保障系统设计与实现6.基于51单片机的16×16点阵(滚动显示)7.基于51单片机的LE

环网柜(开关柜)超高频UHF局放在线监测及无线测温2合1装置方案简介

环网柜(开关柜)超高频UHF局放在线监测及无线测温2合1装置方案简介一.局放监测的几种技术流派二.超高频局放的优势三.系统的设计方案1. 概述广州智昊电气IHPS-3300型开关柜局部放电及温升在线监测装置通过检测伴随局部放电而产生的电磁波辐射及开关柜接头温升现象,装置扫描10~100MHz频率范围内的电磁波辐射并自动确定现场局部放电的实际检测频率,随后将检测的局部放电脉冲簇数据和开关柜头温升数据上传DTU.高压开关柜是使用极广且数量最多的开关设备.由于在设计.制造.安装和运行维护等方面存在着不

[51单片机] nRF24L01 无线模块 测试 按键-灯-远程控制

哈哈,穷吊死一个,自己做的一个超简单的板还没有电源提供,只得借助我的大开发板啦.其实这2个模块是完全可以分开的,无线嘛,你懂得!进入正题,这个实验的功能就是一个发送模块(大的那个板)连接4个按键,通过按动这4个不同的按键来发送4种不同的命令,来控制接收端(小的板)点亮4个不同的灯. >_<!首先是发送模块: 1 void main() 2 { 3 uchar Tx_Buf1[]={1}; //发送的信息1 4 uchar Rx_Buf[32]; //接收到的数据暂存器,最多32字节数据 5 i

基于51单片机的万年历(算法实现)

基于51单片机的万年历,用到了单片机独立键盘.数码管.LED灯模块实现. 想要简单还是DS1302好用. 1 /************************************************** 2 3 作者:纟彖氵戋 博客:http://www.cnblogs.com/yllinux/ 4 5 时间:2017年6月7日 6 7 目标:利用单片机独立键盘.数码管.LED灯模块实现万年历(算法实现) 8 9 ************************************

基于51单片机的12864驱动

/**************dis_12864.h***************/ #include <reg52.h> #ifndef __DIS_12864_H__ #define __DIS_12864_H__ #define uchar unsigned char #define uint  unsigned int /*12864端口定义*/ #define LCD_data  P0             //数据口 sbit LCD_RS  =  P1^0;          

[51单片机] nRF24L01 无线模块 串口法命令 通过无线控制另一个的灯

>_<!概述: 这是在上一个的基础上通过按键发送4种不同命令来控制接收端的LED灯亮的改进版(上一个:http://www.cnblogs.com/zjutlitao/p/3840013.html),这里俺把按键发命令给去掉,然后加入一个串口通信的功能,PC通过串口给发送端发送命令,然后发送端通过无线将命令发给接收端来实现控制,这里接收端和上一个例程中的一样,只是在发送端的代码里去除了按键控制,变成了串口控制. >_<!发送端电路: >_<!接收电路图: >_&l

单片机课程设计——基于51单片机温湿度检测系统的设计与实现

1 #include <reg52.h> 2 #include "1602.h" 3 #include "dht.h" 4 #include "2402.h" 5 6 //定义三个LED灯 7 sbit Led_qushi=P1^6; //去湿灯 8 sbit Led_jiangwen=P1^5; //降温灯 9 sbit Led_shengwen=P1^4; //升温灯 10 sbit Key_TH1 = P3^2; 11 sbit