基于STC89C52MCU的无线测温系统
eetrendMcu 2023-01-31

本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协议来传输,这个必须要会,下次会尝试使用这个协议来编写上位机程序。采集到的温度没有进行处理,只用来显示了,希望在学习数据库以后加入数据的存储筛选功能。 

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 【立即预约】Keysight直播:搞懂介电常数那些事儿


  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • 深谈嵌入式系统,嵌入式系统是如何组成的?

    嵌入式系统在生活中有诸多应用,大家对于嵌入式系统或多或少有所耳闻。在前两篇文章中,小编对嵌入式系统进行过详细介绍。为继续增进大家对嵌入式系统的认识,本文将对嵌入式系统的组成加以说明。如果你对嵌入式系...

    06-27
  • 嵌入式系统秘籍共享,最全嵌入式系统解析

    嵌入式系统的应用十分广泛,因此越来越多的人学习嵌入式系统。由此,在学习嵌入式系统之前,我们应当对嵌入式系统具备一些认识。所以在本文余下部分,小编将对嵌入式系统进行全面解析。如果你对嵌入式系统具有兴趣...

    06-27
  • 51单片机超声波测距程序详解

    51单片机超声波测距程序详解 超声波四通道测距:超声波测距实现分为三大块: 其一是12864带字库的液晶驱动程序: 代码如下: /////////////////12864驱动程序/////////////////////////// //1写数据 void WriteDat...

    06-25
  • 51系列单片机的引脚图

    51系列单片机的引脚图 端子介绍 l P0.0~P0.7 P0口8位双向口线(在引脚的39~32号端子)。 l P1.0~P1.7 P1口8位双向口线(在引脚的1~8号端子)。 l P2.0~P2.7 P2口8位双向口线(在引脚的21~28号端子)。 l P3.0~P3.7 P2口8...

    06-25
  • 51单片机串口通信需要加超时中断吗?

    接收数据时,超过一定时间就算出错. 这个超时的时间是单片机自己算出的吗?超时的时间是由编程序的人定的,他定多长就多长从一段程序开始 实现电脑向 单片机发送一些数据,单片机返回Iget +数据 #include #define u...

    06-25
  • 51单片机电机pid控制系统程序

    51单片机电机pid控制系统程序 本程序来源网上,小编进行了简单修改,还未验证。 /************************* 应用背景:直流电机的额定功率12V,额定转速3000rpm,光码盘12孔, 晶振为12MHz,定时/计数器T0检测转...

    06-25
  • 51单片机指令集设计实例

    当你编写完一个程序后,通过软件调试,你可以看到程序的指令集,从指令集你就能知道单片机内部是如何工作的,比如数据存取的寄存器与地址,下面是电工之家找的一篇指令集,讲的蛮好的。 一、数据传送类指令(7种助...

    06-25
  • 51单片机定时器工作原理及用法

    TMOD : 控制定时器的工作方式。8个bit,高四位 bit 控制 T1,、低四位 bit 控制 T0。因为定时器有4种工作方式;TMOD = 0x00(工作方式0),TMOD = 0x01(工作方式0),TMOD = 0x02(工作方式2),TMOD = 0x03(工作方式3)。...

    06-25
  • 51单片机指令系统寻址方式

    指令给出参与运算的数据方式称为寻址方式。换句话说,寻址方式就是寻找确定参与操作的数的真正地址。 在MCS-51系列单片机的指令系统中寻址方式共有7种,立即寻址方式,mcs-51单片机的一种寻址方式,操作数就写在指...

    06-25
  • 51单片机学习单片机之路总结

    学习单片机有一学期了,现在也由51转到STM32了。一直想对51的学习做一个总结。也希望对别人有一些启发。也给后学者提供一些建议。当然本文是我对自己学习过程的总结,若有不对的地方,还请高手指出。 我想,再看本...

    06-25
  • 入手STM32单片机的知识点总结

    从STM32新建工程、编译下载程序出发,让新手由浅入深,尽享STM32标准库开发的乐趣

    06-23
  • 单片机定时器之改良版:时间轮定时器

    前段时间把自己以前用的单片机定时器整理出来,我称之为简单定时器,这种简单定时器比较适合定时器使用量少的程序中,如果定时器数量要求多,精度要求高,效率就会有问题,为此,俺就实现了一个时间轮定时器,简单测...

    06-23
下载排行榜
更多
评测报告
更多
EE直播间
更多
广告