找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5457|回复: 6
收起左侧

单片机AM2302湿度温度+lcd1602+蓝牙

  [复制链接]
ID:166598 发表于 2018-1-1 19:46 | 显示全部楼层 |阅读模式
经过几天的努力,终于搞出了89C51单片机控制AM2302湿度温度传感器+lcd1602+蓝牙上显示!
被店家坑死喽,还好我会改电路,把传感器模块的电路改为单总线模式,接法如图:(一定记得接地哦)

实物图:

实物图

实物图


手绘电路原理图:

接线方法

接线方法

电路板封装图

电路板封装图


仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)

电路原理图

电路原理图


这是部分程序:

  1. /*
  2. humidity  RH就是相对湿度        日常生活中所指的湿度为相对湿度,%rh表示
  3. 温度(temperature)
  4. */

  5. #include<reg52.h>
  6. #include <intrins.h>
  7. #define uint unsigned int
  8. #define uchar unsigned char

  9. //uchar code table[]="    WELCOME ";
  10. uchar code table0[]="T:       'C";
  11. uchar code table1[]="RH:      %";
  12. uchar code table2[]="Sensor Not";
  13. uchar code table3[]="Connected";
  14. uchar code table4[]="Check wrong";

  15. sbit Sensor_SDA = P3^4;
  16. sbit lcdrs=P1^3;
  17. sbit lcdwr=P1^4;
  18. sbit lcden=P1^5;
  19. /*
  20. sbit lcdrs=P2^6;
  21. sbit lcdwr=P2^5;
  22. sbit lcden=P2^7;
  23. */
  24. uchar Sensor_Data[5]={0x00,0x00,0x00,0x00,0x00};
  25. uchar Sensor_AnswerFlag;  //收到起始标志位
  26. uchar Sensor_ErrorFlag;   //读取传感器错误标志
  27. uchar Sensor_Check;                  //校验和
  28. uint Sys_CNT;
  29. uint Tmp;
  30. uint T;
  31. uint Rh;
  32. uint t0;
  33. uchar num;
  34. uchar flag;

  35. void sendDataToProcessing(char symbol, int dat);                //串发送数据
  36. void Init_Timer0(void);//定时器初始化


  37. //串口发送函数
  38. void sendDataToProcessing(char symbol, int dat )
  39. {
  40.     putchar(symbol);              
  41.         printf("%d\r\n",dat);                                       
  42. }


  43. void UART_Init(void)
  44. {
  45.     SCON=0X50;                        //设置为工作方式1
  46.         TMOD=0X20;                        //设置计数器工作方式2
  47.         PCON=0X80;                        //波特率加倍
  48.         TH1=0XF3;                                //计数器初始值设置,注意波特率是4800的
  49.         TL1=0XF3;
  50. //        ES=1;                                                //打开接收中断
  51. //        EA=1;                                                //打开总中断
  52.         TR1=1;                                        //打开计数器
  53. }
  54. char putchar(unsigned char dat)
  55. {
  56.         TI=0;
  57.         SBUF=dat;
  58.         while(!TI);
  59.         TI=0;
  60.         return SBUF;
  61. }


  62.   //延时函数
  63. void delay(uint z)
  64. {
  65.         uint x,y;
  66.         for(x=z;x>0;x--)
  67.                 for(y=123;y>0;y--);
  68. }

  69. /********************************************\
  70. |* 功能: 延时        晶振为12M时                                    *|
  71. |*  t = 1 为 20us  然后成倍增加10us左右                *|
  72. \********************************************/
  73. void Delay_N10us(unsigned char t)
  74. {
  75.     while(t--)
  76.    {
  77.             _nop_();
  78.    }
  79. }
  80. /********************************************\
  81. |* 功能: 延时        晶振为12M时                                        *|
  82. |* 延时大约 1ms                                                            *|
  83. \********************************************/
  84. void Delay_N1ms(unsigned int t)
  85. {
  86.   unsigned int i;
  87.   unsigned int j;
  88.   for(j=t;j>0;j--)
  89.      for(i=124;i>0;i--);  //延时大约 1ms
  90. }
  91. void write_com(uchar com)                 //写入命令
  92. {
  93.         lcdrs=0;
  94.         P0=com;
  95.         lcden=1;
  96.         delay(5);
  97.         lcden=0;
  98. }
  99. void write_date(uchar date)                 //写入数据
  100. {
  101.         lcdrs=1;
  102.         P0=date;
  103.         lcden=1;
  104.         delay(5);
  105.         lcden=0;
  106. }
  107. void diyihang(uint z)                          //第一行
  108. {
  109.         z--;
  110.         write_com(0x80+z);
  111. }           
  112. void dierhang(uint z)                           //第二行
  113. {
  114.         z--;
  115.         write_com(0x80+0x40+z);
  116. }                                                                          
  117. void init_1602()                                        //1602初始化
  118. {
  119.         lcdwr=0;
  120.         lcden=0;
  121.         write_com(0x38);//模式
  122.         write_com(0x0c);//无光标不闪
  123.         write_com(0x01);//清屏

  124.         diyihang(1);                                                //显示位置 第一行
  125.         for(num=0;num<11;num++)
  126.         {
  127.                 write_date(table0[num]);                         //显示"    温度 ";
  128.                 //delay(10);
  129.         }
  130.         
  131.         dierhang(1);                                                //换行显示 第二行
  132.         for(num=0;num<10;num++)
  133.         {
  134.                 write_date(table1[num]);                          //显示"RH:      %";
  135.                 //delay(10);
  136.         }
  137. }
  138. void Clear_Data (void)                                         
  139. {
  140.         int i;
  141.         for(i=0;i<5;i++)
  142.         {
  143.            Sensor_Data[i] = 0x00;
  144.         }                                                                        //接收数据清零
  145. }


  146. /********************************************\
  147. |* 功能: 读传感器发送的单个字节                *|
  148. \********************************************/
  149. unsigned char Read_SensorData(void)                         //读取传感器信号
  150. {
  151.         unsigned char i,cnt;
  152.         unsigned char buffer,tmp;
  153.         buffer = 0;
  154.         for(i=0;i<8;i++)
  155.         {
  156.                 cnt=0;
  157.                 while(!Sensor_SDA)        //检测上次低电平是否结束
  158.                 {
  159.                   if(++cnt >= 300)
  160.                    {
  161.                           break;
  162.                    }
  163.                 }
  164.                 //延时Min=26us Max50us 跳过数据"0" 的高电平
  165.                 Delay_N10us(2);         //延时30us   
  166.                
  167.                 //判断传感器发送数据位
  168.                 tmp =0;
  169.                 if(Sensor_SDA)         
  170.                 {
  171.                   tmp = 1;
  172.                 }  
  173.                 cnt =0;
  174.                 while(Sensor_SDA)                //等待高电平 结束
  175.                 {
  176.                            if(++cnt >= 200)
  177.                         {
  178.                           break;
  179.                         }
  180.                 }
  181.                 buffer <<=1;
  182.                 buffer |= tmp;        
  183.         }
  184.         return buffer;
  185.   }

  186. /********************************************\
  187. |* 功能: 读传感器                              *|
  188. \********************************************/
  189. unsigned char Read_Sensor(void)
  190. {        
  191.         unsigned char i;
  192.         //主机拉低(Min=800US Max=20Ms)
  193.     Sensor_SDA = 0;
  194.         Delay_N1ms(2);  //延时2Ms
  195.          
  196.         //释放总线 延时(Min=30us Max=50us)
  197.         Sensor_SDA = 1;         
  198.         Delay_N10us(2);//延时30us
  199.         //主机设为输入 判断传感器响应信号
  200.         Sensor_SDA = 1;
  201.                
  202.         Sensor_AnswerFlag = 0;  // 传感器响应标志         

  203.         //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行         
  204.         if(Sensor_SDA == 0)
  205.         {
  206.            Sensor_AnswerFlag = 1;//收到起始信号
  207.            
  208.            Sys_CNT = 0;
  209.            //判断从机是否发出 80us 的低电平响应信号是否结束         
  210.            while((!Sensor_SDA))
  211.            {
  212.              if(++Sys_CNT>300) //防止进入死循环
  213.                  {
  214.                    Sensor_ErrorFlag = 1;
  215.                    return 0;
  216.                  }
  217.            }
  218.            
  219.             Sys_CNT = 0;
  220.             //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  221.             while((Sensor_SDA))
  222.             {
  223.                if(++Sys_CNT>300) //防止进入死循环
  224.                    {
  225.                      Sensor_ErrorFlag = 1;
  226.                      return 0;
  227.                    }
  228.             }                  

  229.                                                                                                 /*****************************************************************************************\
  230.                                                                                                 |*      // 数据接收        传感器共发送40位数据                                                                                                  *|
  231.                                                                                                 |*            // 即5个字节 高位先送  5个字节分别为湿度高位 湿度低位 温度高位 温度低位 校验和         *|
  232.                                                                                                 |*            // 校验和为:湿度高位+湿度低位+温度高位+温度低位                                       *|
  233.                                                                                                 \*****************************************************************************************/
  234.             for(i=0;i<5;i++)
  235.             {
  236.               Sensor_Data[i] = Read_SensorData();
  237.             }
  238.         }
  239.         else
  240.         {
  241.           Sensor_AnswerFlag = 0;          // 未收到传感器响应        
  242.         }
  243.         return 1;
  244. }
  245. void display()                                                                         //显示
  246. {
  247.         Tmp = Sensor_Data[2]*256+Sensor_Data[3];        // 温度高位 温度低位
  248.         T=Tmp/10;
  249.         diyihang(5);                                                                  //第一行第5个位置开始显示
  250.         write_date(Tmp/100%10 + '0');                                        //十位
  251.         write_date(Tmp/10%10 + '0');                                        //个位
  252.         write_date('.');                                                                //小数点
  253.         write_date(Tmp%10 + '0');                                                 //小数位

  254.         Tmp = Sensor_Data[0]*256+Sensor_Data[1];         //湿度高位 湿度低位
  255.         Rh=Tmp/10;
  256.         dierhang(5);                                                                 //第二行第5个位置开始显示
  257.         write_date(Tmp/100%10 + '0');                                        //十位
  258.         write_date(Tmp/10%10 + '0');                                        //个位
  259.         write_date('.');                                                                //小数点
  260.         write_date(Tmp%10 + '0');                                                 //小数位
  261. }
  262. void check_and_display()
  263. {
  264.         if(Sensor_AnswerFlag == 1)
  265.         {
  266.                 Sensor_Check = Sensor_Data[0]+Sensor_Data[1]+Sensor_Data[2]+Sensor_Data[3];
  267.                                                                                                         
  268.                 if(Sensor_Check ==Sensor_Data[4])        /*校验成功        */
  269.                 {
  270.                         if(flag == 1)
  271.                         {
  272.                                 flag = 0;
  273.                                 write_com(0x01);//清屏
  274.                                 diyihang(1);//显示位置
  275.                                 for(num=0;num<11;num++)
  276.                                 {
  277.                                         write_date(table0[num]);         //显示温度
  278.                                         //delay(10);
  279.                                 }
  280.                                 dierhang(1);//换行显示
  281.                                 for(num=0;num<10;num++)
  282.                                 {
  283.                                         write_date(table1[num]); //显示RH:....%
  284.                                         //delay(10);
  285.                                 }
  286.                         }
  287.                         display();                                                                  //显示温度  湿度
  288.                 }
  289.                 else                                                                /*校验失败*/
  290.                 {        
  291.                          write_com(0x01);//清屏
  292.                         diyihang(1);//显示位置
  293.                         for(num=0;num<10;num++)
  294.                         {
  295.                                 write_date(table4[num]);        //显示 Check wrong
  296.                                 //delay(10);
  297.                         }
  298.                         flag=1;
  299.                 }
  300.         }
  301.         else                                                                    /*没有连接上 */
  302.         {
  303.                 write_com(0x01);//清屏
  304.                 diyihang(1);//显示位置
  305.                 for(num=0;num<10;num++)
  306.                 {
  307.                         write_date(table2[num]);           //显示 Sensor Not
  308.                         //delay(10);
  309.                 }
  310.                 dierhang(1);//换行显示
  311.                 for(num=0;num<8;num++)
  312.                 {
  313.                         write_date(table3[num]);                //显示  Connected
  314.                         //delay(10);
  315.                 }
  316.                 flag=1;
  317.         }        
  318. }

  319. /*void init_t0()
  320. {
  321.         TMOD=0x01;
  322.         TH0=(65536-50000)/256;
  323.         TL0=(65536-50000)%256;
  324.         EA=1;
  325.         ET0=1;
  326.         TR0=1;
  327. }*/

  328. void main()
  329. {        Init_Timer0();
  330.         UART_Init();                          //串口初始化
  331.         init_1602();
  332.         while(1)
  333.         {
  334.                  

  335.                 Delay_N1ms(2000);          // 延时 2S(两次读取间隔至少2S)
  336.                 Clear_Data();         // 清除收到数据
  337.                 Read_Sensor();                  // 读取传感器数据         
  338.                 check_and_display();  // 检测并显示数据         
  339.                 sendDataToProcessing('T',T);   //发送脉率值
  340.                 sendDataToProcessing('H',Rh);   //发送脉率值
  341.         }
  342. }
  343. /*------------------------------------------------
  344.                     定时器初始化子程序
  345. ------------------------------------------------*/
  346. void Init_Timer0(void)
  347. {
  348. TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
  349. //TH0=0x00;              //给定初值
  350. //TL0=0x00;
  351. EA=1;            //总中断打开
  352. ET0=1;           //定时器中断打开
  353. TR0=1;           //定时器开关打开
  354. }
  355. /*------------------------------------------------
  356.                  定时器中断子程序
  357. ------------------------------------------------*/
  358. void Timer0_isr(void) interrupt 1
  359. {
  360. static unsigned int num;
  361. TH0=(65536-2000)/256;                  //重新赋值 2ms
  362. TL0=(65536-2000)%256;

  363. num++;
  364. if(num==300)        
  365.    {
  366.     num=0;
  367.         }
  368. }
复制代码

全部资料51hei下载地址:

湿度 温度 蓝牙 lcd1602.zip

44.64 KB, 下载次数: 74, 下载积分: 黑币 -5

程序

电路.zip

160.99 KB, 下载次数: 37, 下载积分: 黑币 -5

原理图,封装图

AM2302模块资料.zip

2.77 MB, 下载次数: 31, 下载积分: 黑币 -5

单总线方式

评分

参与人数 3黑币 +113 收起 理由
siyaqq + 5 很给力!
a752333902 + 8
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:289262 发表于 2018-3-9 11:14 | 显示全部楼层
非常感谢!。咱们互相帮助吧。

非常好的资料。 下载学习下
回复

使用道具 举报

ID:208271 发表于 2018-3-18 14:15 | 显示全部楼层
楼主,DHT22说明书上不是说1脚VCC,2脚SDA,4脚GND,3脚悬空的吗?
是要把3,4接到GND才能准确读数吗
回复

使用道具 举报

ID:208271 发表于 2018-3-18 14:17 | 显示全部楼层
楼主,DHT22说明书上不是说1:VCC  2:SDA   3.NC   4.GND 的吗?是要将3,4接GND才能正确读数吗?急
回复

使用道具 举报

ID:104846 发表于 2018-8-23 09:32 | 显示全部楼层
//楼主,DHT22说明书上不是说1:VCC  2:SDA   3.NC   4.GND 的吗?是要将3,4接GND才能正确读数吗?急//
3脚接不接都可以,本来就是空脚。
回复

使用道具 举报

ID:104846 发表于 2018-8-23 17:06 | 显示全部楼层
附件的程序有问题,和帖子的内容有差异,对不上!
回复

使用道具 举报

ID:186936 发表于 2018-10-28 20:23 | 显示全部楼层
有没有蓝牙E4A相关的资料
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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