单片机
返回首页

单片机+VB上位机温湿度检测制作

2020-09-22 来源:51hei


 

单片机源程序如下:

#include                                    // 头文件包含

#include                        


#define uchar unsigned char        // 以后unsigned char就可以用uchar代替

#define uint  unsigned int        // 以后unsigned int 就可以用uint 代替


sbit Buzzer_P  = P1^0;            // 蜂鸣器

sbit DHT11_P   = P1^1;                         // 温湿度传感器DHT11数据接入

sbit LcdRs_P   = P2^7;             // 1602液晶的RS管脚      

sbit LcdRw_P   = P2^6;            // 1602液晶的RW管脚

sbit LcdEn_P   = P2^5;            // 1602液晶的EN管脚


uchar temp;                                                                // 保存温度

uchar humi;                                                                  // 保存湿度



/*********************************************************/

// 毫秒级的延时函数,time是要延时的毫秒数

/*********************************************************/

void DelayMs(uint time)

{

        uint i,j;

        for(i=0;i                for(j=0;j<112;j++);

}



/*********************************************************/

// 1602液晶写命令函数,cmd就是要写入的命令

/*********************************************************/

void LcdWriteCmd(uchar cmd)

{

        LcdRs_P = 0;

        LcdRw_P = 0;

        LcdEn_P = 0;

        P0=cmd;

        DelayMs(2);

        LcdEn_P = 1;   

        DelayMs(2);

        LcdEn_P = 0;       

}



/*********************************************************/

// 1602液晶写数据函数,dat就是要写入的数据

/*********************************************************/

void LcdWriteData(uchar dat)

{

        LcdRs_P = 1;

        LcdRw_P = 0;

        LcdEn_P = 0;

        P0=dat;

        DelayMs(2);

        LcdEn_P = 1;   

        DelayMs(2);

        LcdEn_P = 0;

}



/*********************************************************/

// 1602液晶初始化函数

/*********************************************************/

void LcdInit()

{

        LcdWriteCmd(0x38);        // 16*2显示,5*7点阵,8位数据口

        LcdWriteCmd(0x0C);        // 开显示,不显示光标

        LcdWriteCmd(0x06);        // 地址加1,当写入数据后光标右移

        LcdWriteCmd(0x01);        // 清屏

}



/*********************************************************/

// 液晶光标定位函数

/*********************************************************/

void LcdGotoXY(uchar line,uchar column)

{

        // 第一行

        if(line==0)        

                LcdWriteCmd(0x80+column);

        // 第二行

        if(line==1)        

                LcdWriteCmd(0x80+0x40+column);

}



/*********************************************************/

// 液晶输出字符串函数

/*********************************************************/

void LcdPrintStr(uchar *str)

{

        while(*str!='')                                         // 判断是否到字符串的尽头了

                LcdWriteData(*str++);

}



/*********************************************************/

// 液晶输出数字

/*********************************************************/

void LcdPrintNum(uchar num)

{

        LcdWriteData(num/10+48);                // 十位

        LcdWriteData(num%10+48);                 // 个位

}



/*********************************************************/

// 液晶显示内容的初始化

/*********************************************************/

void LcdShowInit()

{

        LcdGotoXY(0,0);                                   // 光标定位

        LcdPrintStr('  DHT11 System  ');        // 第0行显示的内容

        LcdGotoXY(1,0);                                 // 光标定位       

        LcdPrintStr('T:   C   H:  %RH');        // 第1行显示的内容

        LcdGotoXY(1,4);                            // 温度单位摄氏度上面的圆圈符号

        LcdWriteData(0xdf);       

}



/*********************************************************/

// 10us级延时程序

/*********************************************************/

void Delay10us()

{

        _nop_();        // 执行一条指令,延时1微秒

        _nop_();

        _nop_();

        _nop_();

        _nop_();

        _nop_();

        _nop_();

        _nop_();

        _nop_();

        _nop_();

}



/*********************************************************/

// 读取DHT11单总线上的一个字节

/*********************************************************/

uchar DhtReadByte(void)

{   

        bit bit_i;

        uchar j;

        uchar dat=0;


        for(j=0;j<8;j++)   

        {

                while(!DHT11_P);        // 等待低电平结束       

                Delay10us();                        // 延时

                Delay10us();

                Delay10us();

                if(DHT11_P==1)                // 判断数据线是高电平还是低电平

                {

                        bit_i=1;

                        while(DHT11_P);

                }

                else

                {

                        bit_i=0;

                }

                dat<<=1;                                   // 将该位移位保存到dat变量中

                dat|=bit_i;   

        }

    return(dat);  

}



/*********************************************************/

// 读取DHT11的一帧数据,湿高、湿低(0)、温高、温低(0)、校验码

/*********************************************************/

void ReadDhtData()

{             

        uchar HumiHig;                // 湿度高检测值

        uchar HumiLow;          // 湿度低检测值

        uchar TemHig;                        // 温度高检测值

        uchar TemLow;                        // 温度低检测值

    uchar check;                // 校验字节

       

        DHT11_P=0;                                // 主机拉低20ms

        DelayMs(20);

        DHT11_P=1;                                // DATA总线由上拉电阻拉高 主机延时40us               


        Delay10us();                         // 延时等待30us

        Delay10us();

        Delay10us();


        while(!DHT11_P);        // 等待DHT的低电平结束

        while(DHT11_P);                // 等待DHT的高电平结束


        //进入数据接收状态

        HumiHig = DhtReadByte();         // 湿度高8位

        HumiLow = DhtReadByte();         // 湿度低8为,总为0

        TemHig  = DhtReadByte();         // 温度高8位

        TemLow  = DhtReadByte();         // 温度低8为,总为0

        check   = DhtReadByte();        // 8位校验码,其值等于读出的四个字节相加之和的低8位


        while(!DHT11_P);

        DHT11_P=1;                                                                // 拉高总线


        if(check==HumiHig + HumiLow + TemHig + TemLow)   // 如果收到的数据无误

        {

                temp=TemHig;                         // 将温度的检测结果赋值给全局变量temp

                humi=HumiHig;                        // 将湿度的检测结果赋值给全局变量humi

        }

}



/*********************************************************/

// 串口初始化

/*********************************************************/

void UartInit()

{

        SCON = 0x50;        // 配置串口寄存器

        TMOD = 0x20;        // 配置定时器寄存器

        TH1  = 0xfd;        // 计算波特率的值为9600

        TL1  = 0xfd;        // 计算波特率的值为9600

        EA   = 1;                        // 打开总中断

        ES   = 1;                        // 打开串口中断

        TR1  = 1;                        // 启动定时器

}




/*********************************************************/

// 串口发送数据函数

/*********************************************************/

void UartSendNum(uchar num)

{

        ES=0;                                                        // 发送过程关闭串口中断

        SBUF=num/10+48;                // 十位

        while(!TI);

        TI=0;

        SBUF=num%10+48;          // 个位

        while(!TI);

        TI=0;

        ES=1;                                                        // 发送结束打开串口中断

}       



/*********************************************************/

// 主函数

/*********************************************************/

void main(void)

{

        UartInit();                                                // 串口初始化

        LcdInit();                                                // 液晶功能的初始化                       

        LcdShowInit();                                 // 液晶显示的初始化


        DelayMs(1200);                                // 上电后等一下再开始读取

       

        while(1)

        {

                 EA=0;                                       / 读取温湿度数值前,关闭总中断

                ReadDhtData();                        // 读取温湿度数据

                EA=1;                                          // 读取温湿度数值后,开启总中断

       

                LcdGotoXY(1,2);                         // 定位到要显示温度的地方

                LcdPrintNum(temp);        // 显示温度值

                LcdGotoXY(1,11);                // 定位到要显示湿度的地方

                LcdPrintNum(humi);        // 显示湿度值


                UartSendNum(temp);        // 串口发送温度

                UartSendNum(humi);        // 串口发送湿度


                DelayMs(2200);                  // 进行延时,可实现不同的采集频率

        }

}



/*********************************************************/

// 串口中断服务程序

/*********************************************************/

void UartInt(void) interrupt 4

{

        uchar dat;

       

        if(RI==1)                                                        // 是否收到串口数据

        {

                RI=0;

                dat=SBUF;                               // 把串口收到的数据保存在dat变量里

               

                if(dat==0x01)                                // 如果串口收到的值是0x01

                        Buzzer_P=0;                                // 那么打开蜂鸣器

                if(dat==0x02)                                // 如果串口收到的值是0x02

                        Buzzer_P=1;                                // 那么关闭蜂鸣器

        }

}



进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章