找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 474|回复: 9
收起左侧

用51单片机串口打印DHT11温湿度数据显示乱码

[复制链接]
ID:1144670 发表于 2025-3-2 12:54 | 显示全部楼层 |阅读模式
芯片是STC89C52RC,在csdn等地方试了很多人的代码都不成功,所以来求助各位大佬,我想把dht11采集到的温湿度打印到串口上。
在Keil5点击build以后,烧录到单片机上,打开串口打印的都是“?借鉴的main.c代码:DHT11温湿度传感器连接51单片机打印到串口_dht11与51单片机怎么连接-CSDN博客
main.c
  1. #include <at89c51RC2.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit Data=P3^6;   //定义数据线
  6. uchar rec_dat[9];   //用于显示的接收数据数组

  7. void DHT11_delay_us(uchar n)
  8. {
  9.     while(--n);
  10. }

  11. void DHT11_delay_ms(uint z)
  12. {
  13.    uint i,j;
  14.    for(i=z;i>0;i--)
  15.       for(j=110;j>0;j--);
  16. }

  17. void DHT11_start()
  18. {
  19.    Data=1;
  20.    DHT11_delay_us(2);
  21.    Data=0;
  22.    DHT11_delay_ms(20);   //延时18ms以上
  23.    Data=1;
  24.    DHT11_delay_us(30);
  25. }

  26. uchar DHT11_rec_byte()      //接收一个字节
  27. {
  28.    uchar i,dat=0;
  29.   for(i=0;i<8;i++)    //从高到低依次接收8位数据
  30.    {         
  31.       while(!Data);   等待50us低电平过去
  32.       DHT11_delay_us(8);     //延时60us,如果还为高则数据为1,否则为0
  33.       dat<<=1;           //移位使正确接收8位数据,数据为0时直接移位
  34.       if(Data==1)    //数据为1时,使dat加1来接收数据1
  35.          dat+=1;
  36.       while(Data);  //等待数据线拉低   
  37.     }  
  38.     return dat;
  39. }

  40. void DHT11_receive()      //接收40位的数据
  41. {
  42.     uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
  43.     DHT11_start();
  44.     if(Data==0)
  45.     {
  46.         while(Data==0);   //等待拉高     
  47.         DHT11_delay_us(40);  //拉高后延时80us
  48.         R_H=DHT11_rec_byte();    //接收湿度高八位  
  49.         R_L=DHT11_rec_byte();    //接收湿度低八位  
  50.         T_H=DHT11_rec_byte();    //接收温度高八位  
  51.         T_L=DHT11_rec_byte();    //接收温度低八位
  52.         revise=DHT11_rec_byte(); //接收校正位

  53.         DHT11_delay_us(25);    //结束

  54.         if((R_H+R_L+T_H+T_L)==revise)      //校正
  55.         {
  56.             RH=R_H;
  57.             RL=R_L;
  58.             TH=T_H;
  59.             TL=T_L;
  60.         }
  61.         /*数据处理,方便显示*/
  62.         rec_dat[0]='0'+(RH/10);
  63.         rec_dat[1]='0'+(RH%10);
  64.         rec_dat[2]='R';
  65.         rec_dat[3]='H';
  66.         rec_dat[4]=' ';
  67.         rec_dat[5]=' ';
  68.         rec_dat[6]='0'+(TH/10);
  69.         rec_dat[7]='0'+(TH%10);
  70.         rec_dat[8]='C';
  71.     }
  72. }

  73. void initSBUF()        //设定定时器1,用于串口中断
  74. {
  75.         TMOD=0x20;        //设定T1定时器工作方式2
  76.         TH1=0xfd;                //T1定时器装初值
  77.         TL1=0xfd;                //T1定时器装初值
  78.         TR1=1;                        //启动T1定时器
  79.         REN=1;                        //允许串口接收
  80.         SM0=0;                        //设定串口工作方式1
  81.         SM1=1;                        //设定串口工作方式1
  82.         EA=1;                                //开总中断
  83.         ES=1;                                //开串口中断
  84. }

  85. void main()
  86. {
  87.          char code Ready_dat[13]="\tReady OK!\n";
  88.      uchar i;
  89.      initSBUF(); //串口初始化
  90.         //每次使用printf函数TI要先置1
  91.          ES=0;
  92.          for(i=0 ;i<13 ;i++)        //修改输出的字符数量
  93.          {
  94.                 SBUF=Ready_dat[i];
  95.                 while(!TI);
  96.                 TI=0;
  97.          }
  98.         
  99.    while(1)
  100.    {   
  101.        DHT11_delay_ms(4500);    //DHT11上电后要等待1S以越过不稳定状态在此期间不能发送任何指令
  102.        DHT11_receive();
  103.            ES=0;
  104.            for(i=0 ;i<9 ;i++)        //修改输出的字符数量
  105.            {
  106.           SBUF=rec_dat[i];
  107.           while(!TI);
  108.           TI=0;
  109.           }
  110.                                  
  111.          for(i=0 ;i<13 ;i++)        //修改输出的字符数量
  112.          {
  113.                 SBUF=Ready_dat[i];
  114.                 while(!TI);
  115.                 TI=0;
  116.          }
  117.    }
  118. }
复制代码

intrins.h
  1. #ifndef __INTRINS_H__
  2. #define __INTRINS_H__

  3. extern void          _nop_     (void);
  4. extern bit           _testbit_ (bit);
  5. extern unsigned char _cror_    (unsigned char val, unsigned char n);
  6. extern unsigned int  _iror_    (unsigned int val,  unsigned char n);
  7. extern unsigned long _lror_    (unsigned long val, unsigned char n);
  8. extern unsigned char _crol_    (unsigned char val, unsigned char n);
  9. extern unsigned int  _irol_    (unsigned int val,  unsigned char n);
  10. extern unsigned long _lrol_    (unsigned long val, unsigned char n);
  11. extern unsigned char _chkfloat_(float);
  12. extern void          _push_    (unsigned char _sfr);
  13. extern void          _pop_     (unsigned char _sfr);

  14. #endif
复制代码












Keil界面

Keil界面

实物接线

实物接线

串口助手

串口助手

csdn3.zip

24.92 KB, 下载次数: 0

压缩包里是所有代码文件

回复

使用道具 举报

ID:57657 发表于 2025-3-3 08:28 | 显示全部楼层
楼主把串口中断打开了,串口中断的入口函数去哪了?
另外把 intrins.h 等Keil自带的头文件贴出来没有任何意义,这个指令在Keil内部。
回复

使用道具 举报

ID:583948 发表于 2025-3-3 09:06 | 显示全部楼层
你讲仿真调试平台软件串口波特率设置为9600试一试呢?是不是波特率两边不一致导致的
回复

使用道具 举报

ID:446156 发表于 2025-3-3 09:57 | 显示全部楼层
你第一次使用串口吗,之前有没有串口发送正常的程序
回复

使用道具 举报

ID:1144670 发表于 2025-3-3 21:25 | 显示全部楼层
qinlu123 发表于 2025-3-3 09:57
你第一次使用串口吗,之前有没有串口发送正常的程序

之前有用过串口
串口.png
回复

使用道具 举报

ID:1144670 发表于 2025-3-3 21:27 | 显示全部楼层
zpwgf 发表于 2025-3-3 09:06
你讲仿真调试平台软件串口波特率设置为9600试一试呢?是不是波特率两边不一致导致的

看“打开串口”右上角波特率那里我调的就是9600
回复

使用道具 举报

ID:1144670 发表于 2025-3-3 21:48 | 显示全部楼层
npn 发表于 2025-3-3 08:28
楼主把串口中断打开了,串口中断的入口函数去哪了?
另外把 intrins.h 等Keil自带的头文件贴出来没有任何意 ...

没有串口中断的入口函数,应该没有关系吧,我把串口中断关闭了以后也是这样。
回复

使用道具 举报

ID:446156 发表于 2025-3-4 07:48 | 显示全部楼层
LEVKAY 发表于 2025-3-3 21:25
之前有用过串口

你为什么不把你好用的串口程序和DHT11读取程序结合一下试试呢
回复

使用道具 举报

ID:446156 发表于 2025-3-4 07:58 | 显示全部楼层
LEVKAY 发表于 2025-3-3 21:25
之前有用过串口

你抄的这个程序PCON寄存器没有设置啊
回复

使用道具 举报

ID:1110945 发表于 2025-3-4 09:16 | 显示全部楼层
用Hex模式看看接收到的是啥数据,再分析。
如果只有一个字节,说明串口中断有问题,比如没开中断或中断函数出错等,
如果有很多字节的数据,那就要对着ASCII码表分析数据了,波特率不对或中
断函数有问题没有按顺序发送数据等。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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