找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5916|回复: 13
打印 上一主题 下一主题
收起左侧

DHT11 STC12C5A60S2单片机测试代码(带详细注释)串口输出

  [复制链接]
跳转到指定楼层
楼主
DHT11 C51测试代码,仅供学习。

单片机源程序如下:
  1. /*********************************************************************************************
  2. 程序名:    DHT11驱动程序
  3. 编写人:    王朗的诱惑
  4. 硬件支持:  STC12C5A60S2  DHT11
  5. 接口说明:  DHT11:VCC GND DATA
  6. *********************************************************************************************
  7. 说明:1、单片机是STC12C5A60S2,晶振频率12MHz,实验成功。换用12T单片机或别的晶振的时候要修改
  8.           延时函数和JUDGE。程序里判断超时的变量t的阀值也要改。
  9.           2、好东西要共享,大家随意折腾~~
  10. *********************************************************************************************/
  11. #include <STC12C5A60S2.H>

  12. typedef unsigned char        uchar;
  13. typedef unsigned int        uint;

  14. #define JUDGE  30                //用于判断通信的0和1,与单片机速度和晶振频率有关

  15. sbit DATA = P2^0;                //定义数据引脚

  16. uchar dat_r[5];                        //用于存放从DHT11读取到的数值

  17. /*********************************************************************************************
  18. 函数名:延时函数
  19. 调  用:Delay30us();/Delay20ms();/Delay1s();
  20. 参  数:无
  21. 返回值:无
  22. 结  果:延时相应时间
  23. 备  注:振荡晶体为12MHz(所有延时函数Copy自STC-ISP(v6.85).exe)
  24. **********************************************************************************************/
  25. void Delay30us()                //@11.0592MHz
  26. {
  27.         unsigned char i;

  28.         i = 80;
  29.         while (--i);
  30. }



  31. void Delay20ms()                //@11.0592MHz
  32. {
  33.         unsigned char i, j, k;

  34.         i = 1;
  35.         j = 216;
  36.         k = 35;
  37.         do
  38.         {
  39.                 do
  40.                 {
  41.                         while (--k);
  42.                 } while (--j);
  43.         } while (--i);
  44. }


  45. void Delay1s()                //@12.000MHz
  46. {
  47.         unsigned char i, j, k;

  48.         i = 43;
  49.         j = 6;
  50.         k = 203;
  51.         do
  52.         {
  53.                 do
  54.                 {
  55.                         while (--k);
  56.                 } while (--j);
  57.         } while (--i);
  58. }

  59. /*********************************************************************************************
  60. 函数名:UART串口初始化函数
  61. 调  用:UART_Init();
  62. 参  数:无
  63. 返回值:无
  64. 结  果:启动UART串口接收中断,允许串口接收,启动T/C1产生波特率(占用)
  65. 备  注:振荡晶体为12MHz,PC串口端设置 [ 9600,8,无,1,无 ]
  66. **********************************************************************************************/
  67. void UART_Init (void){
  68.     TMOD |= 0x20;   //定时器1方式2,8位自动重装模式。0010 0000  
  69.     PCON = 0x00;    //SMOD:波特率倍增位 SMOD=0,波特率不备增  
  70.     SCON = 0x50;    //串口模式1,8位UART,波特率可变。  
  71.     /*波特率定时器初始化,定时器初始值0xFD*/  
  72.     TH1 = 0xFD;     //256-(11.5920*10^6)/(384*9600)  
  73.     TL1 = 0xFD;  
  74.     /*启动定时器1*/  
  75.     TR1 = 1;  
  76.     /*中断处理*/   
  77.     ES = 1; //允许串口中断  
  78.     EA = 1; //允许总中断开关  
  79. }

  80. /*********************************************************************************************
  81. 函数名:UART串口发送函数
  82. 调  用:UART_T (?);
  83. 参  数:需要UART串口发送的数据(8位/1字节)
  84. 返回值:无
  85. 结  果:将参数中的数据发送给UART串口,确认发送完成后退出
  86. 备  注:
  87. **********************************************************************************************/
  88. void UART_T (uchar UART_data){ //定义串口发送数据变量
  89.         SBUF = UART_data;        //将接收的数据发送回去
  90.         while(TI == 0);                //检查发送中断标志位
  91.         TI = 0;                        //令发送中断标志位为0(软件清零)
  92. }

  93. /*********************************************************************************************
  94. 函数名:DHT11读数据函数
  95. 调  用:? = GetData();
  96. 参  数:无
  97. 返回值:失败->-1,-2,-3,-4;成功->0
  98. 结  果:读DHT11数据并保存到数组dat_r[]
  99. 备  注:
  100. **********************************************************************************************/
  101. char GetData (void)
  102. {
  103.         uchar i,j;                                //for循环变量
  104.         uchar t;                                //超时判断
  105.         uchar dat8=0;                        //一次读取的8位数据,需要读5次

  106.         DATA = 0;                                //主机发起始信号
  107.         Delay20ms();                        //主机拉低总线至少18ms
  108.         DATA = 1;                                //主机拉高总线20~40us
  109.         Delay30us();

  110.         t = 80;                                        //设置超时等待时间
  111.         while(DATA && t--);                //等待DHT11拉低总线
  112.         if(t == 0)                                //超时
  113.         {
  114.                 DATA = 1;
  115.                 return -1;                        //通信错误退出,返回错误信号:-1
  116.         }

  117.         //等80us响应信号
  118.         t = 250;                                //设置超时等待时间
  119.         while(!DATA && t--);        //等待DHT11拉高总线
  120.         if(t == 0)                                //超时
  121.         {
  122.                 DATA = 1;
  123.                 return -2;                        //通信错误退出,返回错误信号:-2
  124.         }

  125.         //等80us响应信号
  126.         t = 250;                                //设置超时等待时间
  127.         while(DATA && t--);                //等待DHT11拉低总线
  128.         if(t == 0)                                //超时
  129.         {
  130.                 DATA = 1;
  131.                 return -3;                        //通信错误退出,返回错误信号:-3
  132.         }

  133.         for(j=0; j<5; j++)                //5次读取
  134.         {
  135.                 for(i=0; i<8; i++)                        //1次8个位
  136.                 {
  137.                         //等待50us开始时隙
  138.                         t = 150;                                //设置超时等待时间
  139.                         while(!DATA && t--);        //等待DHT11拉高总线
  140.                         if(t == 0)                                //超时
  141.                         {
  142.                                 DATA = 1;
  143.                                 return -4;                        //通信错误退出,返回错误信号:-4
  144.                         }
  145.                         t = 0;                                        //记录时间清零
  146.                         while(DATA && ++t);                //等待并记录高电平持续时间
  147.                         dat8 <<= 1;
  148.                         if(t > JUDGE)                        //高电平持续时间较长(70us)
  149.                                 dat8 += 1;                        //传输值为1
  150.                         //else dat8 += 0;
  151.                 }
  152.                 dat_r[j] = dat8;
  153.         }

  154.         Delay30us();                //等待DHT11拉低50us
  155.         Delay30us();
  156.         DATA = 1;                        //结束,拉高总线
  157.         return 0;                        //返回成功信号
  158. }

  159. /*********************************************************************************************
  160. 函数名:数据校验函数
  161. 调  用:? = Check();
  162. 参  数:无
  163. 返回值:成功->0;失败->-1;
  164. 结  果:数据校验
  165. 备  注:数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
  166. **********************************************************************************************/
  167. char Check (void)
  168. {
  169.         uchar i;                        //for循环变量
  170.         uint chk=0;                        //校验和
  171.         for(i=0; i<4; i++)
  172.                 chk += dat_r[i];                //累加
  173.         if((uchar)chk != dat_r[4])        //比对
  174.                 return -1;                                //返回错误信号:-1
  175.         else
  176.                 return 0;                                //返回正确信号:0
  177. }

  178. /*********************************************************************************************
  179. 函数名:主函数
  180. 调  用:无
  181. 参  数:无
  182. 返回值:无
  183. 结  果:读DHT11数据并送到串口显示
  184. 备  注:
  185. **********************************************************************************************/
  186. void main (void)
  187. {
  188.         char i;
  189.         UART_Init();                //串口初始化
  190.         Delay1s();                        //等待DHT11稳定
  191.         do
  192.         {
  193.                 i = GetData();        //读数据
  194.                 if(i != 0)                //有错误
  195.                 {
  196.                         //UART_T(-i);        //返回错误值
  197.                         break;                //重新开始
  198.                 }

  199.                 i = Check();        //数据校验
  200.                 if(i != 0)                //有错误
  201.                 {
  202.                         //UART_T(-i);        //返回错误值
  203.                         break;                //重新开始
  204.                 }

  205.                 UART_T(dat_r[0]);                //湿度整数
  206.                 //UART_T(dat_r[1]);                //湿度小数(根据数据手册,DHT11小数部分一直是0没用)
  207.                 UART_T(dat_r[2]);                //温度整数
  208.                 UART_T(dat_r[3]);                //温度小数(根据数据手册,DHT11小数部分一直是0没用)
  209.                 UART_T(dat_r[4]);                //校验值

  210.                 Delay1s();                                //经测试,两次连读要至少延时80ms        
  211.         }while(1);
  212. }
复制代码

所有资料51hei提供下载:
DHT11.rar (30.21 KB, 下载次数: 149)


评分

参与人数 1黑币 +35 收起 理由
王朗的诱惑 + 35 把主函数循环里break改成continue吧……抱.

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:408102 发表于 2018-10-11 15:54 | 只看该作者
STC12C5A60S2.H  是自带的吗?
回复

使用道具 举报

板凳
ID:408102 发表于 2018-10-11 17:50 | 只看该作者
你好,我询问下,我出来的结果很奇怪,就是一串的数字,是用的DHT11和STC12C5A60S2单片机,接的也是P20口。但是打印出来就是一串数字接一串的*或者+。因为刚接触单片机,对语言还在学习中,能否指教下。
回复

使用道具 举报

地板
ID:84652 发表于 2018-10-11 18:04 | 只看该作者
q157543347 发表于 2018-10-11 15:54
STC12C5A60S2.H  是自带的吗?

回复

使用道具 举报

5#
ID:84652 发表于 2018-10-11 18:07 | 只看该作者
q157543347 发表于 2018-10-11 17:50
你好,我询问下,我出来的结果很奇怪, 就是一串的数字,是用的DHT11和STC12C5A60S2单片机,接的 ...

接收选择HEX模式
主函数里加上一个发送常量的语句,比如UART_T(0x33)看发来是不是0x33,这样就知道串口通讯有没有问题。
回复

使用道具 举报

6#
ID:137005 发表于 2018-11-22 09:11 | 只看该作者
下载学习,谢谢分享!
回复

使用道具 举报

7#
ID:304849 发表于 2018-12-2 11:35 | 只看该作者
你好,用了这个程序,请问显示的16进制数据怎么看?为什么会每过4个数据显示0?

1.PNG (2.53 KB, 下载次数: 115)

1.PNG
回复

使用道具 举报

8#
ID:501681 发表于 2019-4-27 15:29 | 只看该作者
正好用到,下下来看看效果
回复

使用道具 举报

9#
ID:501681 发表于 2019-4-28 13:36 | 只看该作者
输出串口会乱码是怎么回事呢
回复

使用道具 举报

10#
ID:523982 发表于 2019-4-29 08:07 | 只看该作者
q157543347 发表于 2018-10-11 15:54
STC12C5A60S2.H  是自带的吗?

不是,可以去STC的下载器复制这个头文件
回复

使用道具 举报

11#
ID:501681 发表于 2019-5-16 19:37 | 只看该作者
11.0592M   JUDGE怎么修改
回复

使用道具 举报

12#
ID:359588 发表于 2020-1-31 00:09 | 只看该作者
问什么串口提示乱码?
回复

使用道具 举报

13#
ID:473579 发表于 2024-1-18 13:18 | 只看该作者
说明:1、单片机是STC12C5A60S2,晶振频率12MHz,实验成功。换用12T单片机或别的晶振的时候要修改
          延时函数和JUDGE。程序里判断超时的变量t的阀值也要改。
回复

使用道具 举报

14#
ID:473579 发表于 2024-1-18 13:19 | 只看该作者
说明:1、单片机是STC12C5A60S2,晶振频率12MHz,实验成功。换用12T单片机或别的晶振的时候要修改
          延时函数和JUDGE。程序里判断超时的变量t的阀值也要改。

11.0592M   JUDGE怎么修改,判断超时的变量t的阀值怎么改。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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