菜鸟初学C51单片机,不容易啊,仅与一步一步走来的菜鸟分享,大师们忽视!
今天刚收到某宝快递来的DHT11,马上焊接,早上就一直再看规格书,网上看别人的例程,以为很顺利,结果从下午4点开始,
一直弄到12点多,就是读不出数据,网上看了很多例程,就是不行。都快崩溃得想放弃了,最后还是有显示了
不敢独享,分享给很多像我一样的菜鸟
(参照:http://www.51hei.com/bbs/dpj-154092-1.html,fumily 发表于 2019-3-23 18:57)感谢作者fumily
/*****************************************************************************
*MCU 型号:STC15W404AS
*开发环境:Keil uVision5
*晶震频率:11.0592MHZ
*完成日期:2019-08-20
*程序功能:DHT11读取
/********************定义数据*************************/
- #include <STC15F2K60S2.H>
- #include <intrins.h>
- #define uchar unsigned char //无符号字符型类型数据
- #define uint unsigned int //无符号整型数据
- uchar dat_r[4]; //用于存放从DHT11读取到的数值
- sbit DATA=P3^3; //定义数据线,DHT11的2脚,2脚要上拉5.1K电阻
- /*-------30US延时---11.0592MHz(Copy自STC-ISP(v6.86).exe)----------------------------*/
- void Delay30us()
- {
- unsigned char i;
- _nop_();
- _nop_();
- i = 80;
- while (--i);
- }
- /*-------20MS延时----11.0592MHz(Copy自STC-ISP(v6.86).exe)---------------------------*/
- void Delay20ms()
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 1;
- j = 216;
- k = 35;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- /*-------1S延时-----11.0592MHz(Copy自STC-ISP(v6.86).exe)--------------------------*/
- void Delay1s()
- {
- unsigned char i, j, k;
- _nop_();
- _nop_();
- i = 43;
- j = 6;
- k = 203;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- /*********************************************************************************************
- 函数名:DHT11启动函数
- 调 用:无
- 参 数:无
- 返回值:无
- 结 果:DHT11开始工作
- 备 注:
- **********************************************************************************************/
- void DHT11_start() // 主机控制DHT11开始工作
- {
- DATA=1; // 主线空闲状态
- _nop_();
- _nop_();
- DATA=0; // 主机发送开始工作信号
- Delay20ms(); //延时18ms以上
- DATA=1; // 拉高并延时等待DHT11响应
- Delay30us();
- }
- /*********************************************************************************************
- 函数名:DHT11读数据函数
- 调 用:? = DHT11_rec_byte();
- 参 数:无
- 返回值:
- 结 果:读DHT11数据并保存到dat
- 备 注:
- **********************************************************************************************/
- uchar DHT11_rec_byte() //接收一个字节
- {
- uchar i,dat=0;
- for(i=0;i<8;i++) //从高到低依次接收8位数据
- {
- while(!DATA); //等待50us低电平过去
- Delay30us();
- Delay30us(); //延时60us,如果还为高则数据为1,否则为0
- dat<<=1; //左移位使正确接收8位数据,数据为0时直接移位
- if(DATA==1) //数据为1时,使dat加1来接收数据1
- dat+=1;
- while(DATA); //等待数据线拉低
- }
- return dat;
- }
- /*********************************************************************************************
- 函数名:接收DHT11的40位的数据并校验
- 调 用:? = DHT11_receive();
- 参 数:无
- 返回值:无
- 结 果:结果保存到dat_r[i]中
- 备 注:
- **********************************************************************************************/
- void DHT11_receive() //接收40位的数据
- {
- uchar R_H,R_L,T_H,T_L,RH,RL,TH,TL,revise;
- DHT11_start(); // 主机控制DHT11开始工作
- if(DATA==0)
- {
- while(DATA==0); //等待拉高
- Delay30us();
- Delay30us();
- Delay30us(); //拉高后延时80us
- R_H=DHT11_rec_byte(); //接收湿度高八位
- R_L=DHT11_rec_byte(); //接收湿度低八位
- T_H=DHT11_rec_byte(); //接收温度高八位
- T_L=DHT11_rec_byte(); //接收温度低八位
- revise=DHT11_rec_byte(); //接收校正位[/i][/color][/font][/u][i]
- [u][font=宋体][color=#336699] Delay30us(); //结束[/color][/font][/u]
- [u][font=宋体][color=#336699] if((R_H+R_L+T_H+T_L)==revise) //校正
- {
- RH=R_H;
- RL=R_L;
- TH=T_H;
- TL=T_L;
- }
- /*数据处理,方便显示*/
- dat_r[0]='0'+(RH/10);
- dat_r[1]='0'+(RH%10);
- dat_r[2]='0'+(TH/10);
- dat_r[3]='0'+(TH%10);
- }
- }
- /*========串口初始化函数=================================================*/
- void UartInit() [url=]//9600bps@11.0592MHz[/url]
- {
- SCON = 0x50; //8位数据,可变波特率
- AUXR |= 0x04;
- //AUXR |= 0x01; //串口1选择定时器2为波特率发生器
- T2L =0xE0; // 65536-(11059200/4/9600); //设定定时初值
- T2H =0xFE; // (65536-(11059200/4/9600))>>8; //设定定时初值
- AUXR |= 0x10;
- }
- /*===========串口发送函数(字节)=======================================*/
- void Uartsend_1(unsigned char send)
- {
- SBUF=send; //发送数据
- while(!TI); //等待前一帧数据发送完毕
- TI=0; //复位标志位
- }
- //----------串口发送函数(字符串)-----------------------------------------
- void PrintString(unsigned char code *puts) //发送一串字符串
- {
- for (; *puts != 0;
- puts++) Uartsend_1(*puts); //遇到停止符0结束
- }
- /*********************************************************************************************
- 函数名:主函数
- 调 用:无
- 参 数:无
- 返回值:无
- 结 果:读DHT11数据并送到1602显示
- 备 注:
- **********************************************************************************************/
- void main (void)
- {
- UartInit();
- Delay20ms();
- while(1)
- {
- Delay1s(); //经测试,两次连读要至少延时80ms
- DHT11_receive();//接受数据
- //RH:XX%
- PrintString("RH:");
- Uartsend_1(dat_r[0]);
- Uartsend_1(dat_r[1]);
- PrintString("%; ");
- //TMP:XXC
- PrintString("Tempreture:");
- Uartsend_1(dat_r[2]);
- Uartsend_1(dat_r[3]);
- Uartsend_1(0xdf);
- PrintString("C ");
- Delay1s();
-
-
- }
- }
复制代码
|