找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4849|回复: 8
收起左侧

单片机+VB上位机温湿度检测制作 附源程序

  [复制链接]
ID:416896 发表于 2020-9-21 14:09 | 显示全部楼层 |阅读模式
休息时间尝试用VB作为上位机与单片机进行通信,自己动手做了板子,效果还行,分享下。

实物

实物


仿真图附上

未上电

未上电

检测

检测

调试

调试

代码因为是上位机和下位机的,直接压缩放上来了。
单片机源程序如下:
  1. #include <reg52.h>                                   // 头文件包含
  2. #include <intrins.h>                       

  3. #define uchar unsigned char        // 以后unsigned char就可以用uchar代替
  4. #define uint  unsigned int        // 以后unsigned int 就可以用uint 代替

  5. sbit Buzzer_P  = P1^0;            // 蜂鸣器
  6. sbit DHT11_P   = P1^1;                         // 温湿度传感器DHT11数据接入
  7. sbit LcdRs_P   = P2^7;             // 1602液晶的RS管脚      
  8. sbit LcdRw_P   = P2^6;            // 1602液晶的RW管脚
  9. sbit LcdEn_P   = P2^5;            // 1602液晶的EN管脚

  10. uchar temp;                                                                // 保存温度
  11. uchar humi;                                                                  // 保存湿度


  12. /*********************************************************/
  13. // 毫秒级的延时函数,time是要延时的毫秒数
  14. /*********************************************************/
  15. void DelayMs(uint time)
  16. {
  17.         uint i,j;
  18.         for(i=0;i<time;i++)
  19.                 for(j=0;j<112;j++);
  20. }


  21. /*********************************************************/
  22. // 1602液晶写命令函数,cmd就是要写入的命令
  23. /*********************************************************/
  24. void LcdWriteCmd(uchar cmd)
  25. {
  26.         LcdRs_P = 0;
  27.         LcdRw_P = 0;
  28.         LcdEn_P = 0;
  29.         P0=cmd;
  30.         DelayMs(2);
  31.         LcdEn_P = 1;   
  32.         DelayMs(2);
  33.         LcdEn_P = 0;       
  34. }


  35. /*********************************************************/
  36. // 1602液晶写数据函数,dat就是要写入的数据
  37. /*********************************************************/
  38. void LcdWriteData(uchar dat)
  39. {
  40.         LcdRs_P = 1;
  41.         LcdRw_P = 0;
  42.         LcdEn_P = 0;
  43.         P0=dat;
  44.         DelayMs(2);
  45.         LcdEn_P = 1;   
  46.         DelayMs(2);
  47.         LcdEn_P = 0;
  48. }


  49. /*********************************************************/
  50. // 1602液晶初始化函数
  51. /*********************************************************/
  52. void LcdInit()
  53. {
  54.         LcdWriteCmd(0x38);        // 16*2显示,5*7点阵,8位数据口
  55.         LcdWriteCmd(0x0C);        // 开显示,不显示光标
  56.         LcdWriteCmd(0x06);        // 地址加1,当写入数据后光标右移
  57.         LcdWriteCmd(0x01);        // 清屏
  58. }


  59. /*********************************************************/
  60. // 液晶光标定位函数
  61. /*********************************************************/
  62. void LcdGotoXY(uchar line,uchar column)
  63. {
  64.         // 第一行
  65.         if(line==0)        
  66.                 LcdWriteCmd(0x80+column);
  67.         // 第二行
  68.         if(line==1)        
  69.                 LcdWriteCmd(0x80+0x40+column);
  70. }


  71. /*********************************************************/
  72. // 液晶输出字符串函数
  73. /*********************************************************/
  74. void LcdPrintStr(uchar *str)
  75. {
  76.         while(*str!='\0')                                         // 判断是否到字符串的尽头了
  77.                 LcdWriteData(*str++);
  78. }


  79. /*********************************************************/
  80. // 液晶输出数字
  81. /*********************************************************/
  82. void LcdPrintNum(uchar num)
  83. {
  84.         LcdWriteData(num/10+48);                // 十位
  85.         LcdWriteData(num%10+48);                 // 个位
  86. }


  87. /*********************************************************/
  88. // 液晶显示内容的初始化
  89. /*********************************************************/
  90. void LcdShowInit()
  91. {
  92.         LcdGotoXY(0,0);                                                                                // 光标定位
  93.         LcdPrintStr("  DHT11 System  ");        // 第0行显示的内容
  94.         LcdGotoXY(1,0);                                                                           // 光标定位       
  95.         LcdPrintStr("T:   C   H:  %RH");        // 第1行显示的内容
  96.         LcdGotoXY(1,4);                                                                                // 温度单位摄氏度上面的圆圈符号
  97.         LcdWriteData(0xdf);       
  98. }


  99. /*********************************************************/
  100. // 10us级延时程序
  101. /*********************************************************/
  102. void Delay10us()
  103. {
  104.         _nop_();        // 执行一条指令,延时1微秒
  105.         _nop_();
  106.         _nop_();
  107.         _nop_();
  108.         _nop_();
  109.         _nop_();
  110.         _nop_();
  111.         _nop_();
  112.         _nop_();
  113.         _nop_();
  114. }


  115. /*********************************************************/
  116. // 读取DHT11单总线上的一个字节
  117. /*********************************************************/
  118. uchar DhtReadByte(void)
  119. {   
  120.         bit bit_i;
  121.         uchar j;
  122.         uchar dat=0;

  123.         for(j=0;j<8;j++)   
  124.         {
  125.                 while(!DHT11_P);        // 等待低电平结束       
  126.                 Delay10us();                        // 延时
  127.                 Delay10us();
  128.                 Delay10us();
  129.                 if(DHT11_P==1)                // 判断数据线是高电平还是低电平
  130.                 {
  131.                         bit_i=1;
  132.                         while(DHT11_P);
  133.                 }
  134.                 else
  135.                 {
  136.                         bit_i=0;
  137.                 }
  138.                 dat<<=1;                                   // 将该位移位保存到dat变量中
  139.                 dat|=bit_i;   
  140.         }
  141.     return(dat);  
  142. }


  143. /*********************************************************/
  144. // 读取DHT11的一帧数据,湿高、湿低(0)、温高、温低(0)、校验码
  145. /*********************************************************/
  146. void ReadDhtData()
  147. {             
  148.         uchar HumiHig;                // 湿度高检测值
  149.         uchar HumiLow;          // 湿度低检测值
  150.         uchar TemHig;                        // 温度高检测值
  151.         uchar TemLow;                        // 温度低检测值
  152.     uchar check;                // 校验字节
  153.        
  154.         DHT11_P=0;                                // 主机拉低20ms
  155.         DelayMs(20);
  156.         DHT11_P=1;                                // DATA总线由上拉电阻拉高 主机延时40us               

  157.         Delay10us();                         // 延时等待30us
  158.         Delay10us();
  159.         Delay10us();

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

  162.         //进入数据接收状态
  163.         HumiHig = DhtReadByte();         // 湿度高8位
  164.         HumiLow = DhtReadByte();         // 湿度低8为,总为0
  165.         TemHig  = DhtReadByte();         // 温度高8位
  166.         TemLow  = DhtReadByte();         // 温度低8为,总为0
  167.         check   = DhtReadByte();        // 8位校验码,其值等于读出的四个字节相加之和的低8位

  168.         while(!DHT11_P);
  169.         DHT11_P=1;                                                                // 拉高总线

  170.         if(check==HumiHig + HumiLow + TemHig + TemLow)                 // 如果收到的数据无误
  171.         {
  172.                 temp=TemHig;                         // 将温度的检测结果赋值给全局变量temp
  173.                 humi=HumiHig;                        // 将湿度的检测结果赋值给全局变量humi
  174.         }
  175. }


  176. /*********************************************************/
  177. // 串口初始化
  178. /*********************************************************/
  179. void UartInit()
  180. {
  181.         SCON = 0x50;        // 配置串口寄存器
  182.         TMOD = 0x20;        // 配置定时器寄存器
  183.         TH1  = 0xfd;        // 计算波特率的值为9600
  184.         TL1  = 0xfd;        // 计算波特率的值为9600
  185.         EA   = 1;                        // 打开总中断
  186.         ES   = 1;                        // 打开串口中断
  187.         TR1  = 1;                        // 启动定时器
  188. }



  189. /*********************************************************/
  190. // 串口发送数据函数
  191. /*********************************************************/
  192. void UartSendNum(uchar num)
  193. {
  194.         ES=0;                                                        // 发送过程关闭串口中断
  195.         SBUF=num/10+48;                // 十位
  196.         while(!TI);
  197.         TI=0;
  198.         SBUF=num%10+48;          // 个位
  199.         while(!TI);
  200.         TI=0;
  201.         ES=1;                                                        // 发送结束打开串口中断
  202. }       


  203. /*********************************************************/
  204. // 主函数
  205. /*********************************************************/
  206. void main(void)
  207. {
  208.         UartInit();                                                // 串口初始化
  209.         LcdInit();                                                // 液晶功能的初始化                       
  210.         LcdShowInit();                                 // 液晶显示的初始化

  211.         DelayMs(1200);                                // 上电后等一下再开始读取
  212.        
  213.         while(1)
  214.         {
  215.                  EA=0;                                                                // 读取温湿度数值前,关闭总中断
  216.                 ReadDhtData();                        // 读取温湿度数据
  217.                 EA=1;                                                                // 读取温湿度数值后,开启总中断
  218.        
  219.                 LcdGotoXY(1,2);                         // 定位到要显示温度的地方
  220.                 LcdPrintNum(temp);        // 显示温度值
  221.                 LcdGotoXY(1,11);                // 定位到要显示湿度的地方
  222.                 LcdPrintNum(humi);        // 显示湿度值

  223.                 UartSendNum(temp);        // 串口发送温度
  224.                 UartSendNum(humi);        // 串口发送湿度

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


  228. /*********************************************************/
  229. // 串口中断服务程序
  230. /*********************************************************/
  231. void UartInt(void) interrupt 4
  232. {
  233.         uchar dat;
  234.        
  235.         if(RI==1)                                                        // 是否收到串口数据
  236.         {
  237.                 RI=0;
  238.                 dat=SBUF;                                                // 把串口收到的数据保存在dat变量里
  239.                
  240.                 if(dat==0x01)                                // 如果串口收到的值是0x01
  241.                         Buzzer_P=0;                                // 那么打开蜂鸣器
  242.                 if(dat==0x02)                                // 如果串口收到的值是0x02
  243.                         Buzzer_P=1;                                // 那么关闭蜂鸣器
  244.         }
  245. }
复制代码


上位机VB代码: 上位机程序.rar (69.67 KB, 下载次数: 178)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:824799 发表于 2020-11-5 12:31 | 显示全部楼层
有仿真图吗proteus的
回复

使用道具 举报

ID:468240 发表于 2020-11-10 21:49 | 显示全部楼层
楼主,有原理图吗?PDF也可以
回复

使用道具 举报

ID:900757 发表于 2021-4-5 12:17 来自手机 | 显示全部楼层
楼主你好,我再调试的时候遇到找不到串口,这个是什么原因呢?能帮忙解答一下吗
回复

使用道具 举报

ID:900757 发表于 2021-4-5 17:45 来自手机 | 显示全部楼层
我按照你的思路和方法做好的仿真,但是VB上数据接收不了单片机传过来的数据,不知道那一步错了,我用串口发送是可以到VB是没问题的
回复

使用道具 举报

ID:915955 发表于 2021-5-17 22:48 | 显示全部楼层
兄弟你现在这个弄好了吗,VB上可以接收到单片机的数据了吗
回复

使用道具 举报

ID:915955 发表于 2021-5-17 22:55 | 显示全部楼层
老李家呀 发表于 2021-4-5 17:45
我按照你的思路和方法做好的仿真,但是VB上数据接收不了单片机传过来的数据,不知道那一步错了,我用串口发 ...

兄弟现在搞定了吗
回复

使用道具 举报

ID:320250 发表于 2022-5-15 21:53 | 显示全部楼层
老李家呀 发表于 2021-4-5 12:17
楼主你好,我再调试的时候遇到找不到串口,这个是什么原因呢?能帮忙解答一下吗

要安装好控件
回复

使用道具 举报

ID:1029268 发表于 2022-5-24 15:58 | 显示全部楼层
你好,请问可以帮我看看程序吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表