Use of DHT11 temperature and humidity sensor based on ATmega128

Publisher:玉米哥哥Latest update time:2012-08-13 Source: 51heiKeywords:ATmega128 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

DHT11, like DS18B20, is a single bus chip. Unlike DHT10, one of its four pins is left empty. Similar to DS18B20, it has higher requirements on timing. The difference is that when writing a program, data collection must be done at intervals of more than 1s, otherwise the collection will fail.

In addition, it is best to connect a pull-up resistor to the data port of DHT11, or the internal pull-up of the microcontroller is also OK.

The data sheet of DHT11 is available online, which has a detailed description of the timing operation. I personally recommend that you write and test this program at the same time (for example, after writing the reset subroutine, call it once in the main function to see if it is executed successfully...), otherwise it is very likely that you will not be able to find where the error is in the end. I have been writing it and it didn’t work, so I rewrote it in the end!

Without further ado, let me help you analyze the timing diagram of DHT11 (in the data sheet). Because DHT11 has very high requirements for timing, it is very likely that the program will not work after writing it. I suggest: It is best to use an oscilloscope to test the delay subfunction yourself. The error calculated by yourself will be very large under 10us.

Let’s get to the point: You can refer to the following program to see what I say below.
You can understand some of the contents in the front of the data sheet by yourself. First, look at the part of the host reset signal and the corresponding signal of DHT11 in the data sheet.

The host first controls the bus, pulls it down for at least 18ms, and then pulls it up for 20~40us. (If there is no problem with the hardware, DHT11 will respond.) So now the host releases the bus (clears the DDRXN register) and waits for the response of DHT11. If successful, DHT11 will generate a low level of 40~50us and a high level of 40~50us. The program can complete the detection here.

Next, in a collection, the bus is always handed over to DHT11, which will send a 40-bit binary number to the host. The first 0~7 bits are the integer part of the humidity, and the 8~15 bits are the decimal part of the humidity; the 16~23 bits are the integer part of the temperature, and the 24~31 bits are the decimal part of the temperature; the last eight bits are the check bits. These data must be processed by the program, converted into the actual values ​​of temperature and humidity, and displayed by the display part. (I use a digital tube, and it is recommended to use 1602 display for more convenience).

I will not explain the following processing part one by one. I have annotated it in the program. It will be much better if you add the program to the project. You can also use special reading software (source insignte), otherwise the fonts are all the same color and very messy.

If you don't understand something or there are any shortcomings in the program, just leave me a message, I will help you solve it in time ^_^!!!
The download address of the complete version of the program code is: http://www.51hei.com/f/dht11.rar [page]
==================================================
//Here is delay.h /*************The crystal oscillator of my development board is 16M, and the specific delay sub-function needs to be written carefully by yourself*************/

#ifndef __DELAY_H
#define __DELAY_H

void delay_us(unsigned int xus);
void delay_ms(unsigned int xms);

#endif
=================================================
//here is delay.c

#include"delay.h"
#include

//Delay in microseconds sub-function
void delay_us(unsigned int xus)
{
unsigned int i,j;
for(i=0;i {
NOP();NOP();NOP();NOP();NOP();NOP();
NOP(); NOP();NOP();NOP();
}
}
//Delay in milliseconds sub-function
void delay_ms(unsigned int xms)
{
unsigned int i,j;
for(i=0;i {
for(j=0;j<2288;j++);
}
}

===================================================
//here is dht11.h

#ifndef __DHT11_H
#define __DHT11_H


#ifndef __IOM128V_H
#include
#endif

#ifndef __MACROS_H
#include
#endif

#define DDR_1 DDRC|=BIT(PC0)
#define DDR_0 DDRC&=~BIT(PC0)
#define PORTC_1 PORTC|=BIT(PC0)
#define PORTC_0 PORTC&=~BIT(PC0)

#define DQ (PINC&0x01)

void caiji(void);
long int dht(void);
void init_dht11(void);
//void ceshi(void);


#endif

===================================================
//Here is dht11.c

#include"dht11.h"
unsigned char dht_data[5],a,b;
unsigned int s1,s0,t1,t0,sd,wd,wsd;
void caiji(void)
{
unsigned char i,j;
//delay_ms(900);
for(i=0;i<5;i++)
{
dht_data[i]=0x00; //clear the arrayfor
(j=0;j<8;j++)
{
while(!DQ); //Judge whether it is a high level
//delay 50us if it is a high level then it is one, otherwise it is
zerodelay_us(50);
if(DQ)
{
dht_data[i]|=BIT(7-j); //save datawhile
(DQ);//low level detection
}
}
}
}
void init_dht11(void)
{
DDR_1; //set host output
PORTC_0; //The bus is pulled low for at least 18ms
delay_ms(20);
PORTC_1; //The bus is pulled high by the host for about 30us
delay_us(30);
DDR_0; //The host is set as input to detect slave signals
while(DQ);
}

long int dht(void)
{
init_dht11();
if(!DQ)
{
while(!DQ);
while(DQ); //Start receiving signal after the above two sentences
caiji();
DDR_1;
PORTC_1;
//Check
a=
(
dht_data[0]+dht_data[1]+dht_data[2]+dht_data[3]
);
if(a==dht_data[4])
{
s1=dht_data[0];
s0=dht_data[1];
t1=dht_data[2];
t0=dht_data[3];
}
//s is humidity, t is temperature
sd=s1;
sd<<=8;
sd|=s0;
wd=t1;
wd<<=8;
wd|=t0;
wsd=sd<<16;
wsd|=wd;
}
return wsd;
}

===================================================
//This is xianshi.h

#ifndef __XIANSHI_H
#define __XIANSHI_H

#ifndef __IOM128V_H
#include
#endif

#define SCK_0 PORTB&=~(1< #define SCK_1 PORTB|=(1< #define LCK_0 PORTB&=~(1< #define LCK_1 PORTB|=(1< #define SDI_0 PORTB&=~(1< #define SDI_1 PORTB|=(1<


void init(void);

void send_595(unsigned char dat);
void digitron_show(unsigned int int_part,unsigned int float_part);

#endif

==================================================
//Here is xianshi.c
#include "xianshi.h"

#ifndef __DELAY_H
#include"delay.h"
#endif

#ifndef __DHT11_H
#include"dht11.h"
#endif

//Definition of digital tube display array
const unsigned char table[] =
{
0x3F,// 0
0x06,// 1
0x5B,// 2
0x4F,// 3
0x66,// 4
0x6D,// 5
0x7D,// 6
0x07,// 7
0x7F,// 8
0x6F,// 9
0x3F+0x80,// 0.
0x06+0x80,// 1.
0x5B+0x80,// 2.
0x4F+0x80,// 3.
0x66+0x80,// 4.
0x6D+0x80,// 5.
0x7D+0x80,// 6.
0x07+0x80,// 7.
0x7F+0x80,// 8.
0x6F+0x80// 9.
};

unsigned int s,t,st,int_part,float_part,temp,SH;

//Send one byte of data to 595
void send_595(unsigned char dat)
{
unsigned char i;
LCK_0;
SDI_1;
SCK_0;
//The above three statements are to initialize the port status
for(i=0;i<8;i++)
{
LCK_0;//Pull the clock line low

if(dat&0x80)
SDI_1;
else SDI_0;
dat=dat<<1;
delay_us(100);
LCK_1; //Pull the clock line high to read the data into the shift register of 595
delay_us(100);
}
SCK_1; //Send data to parallel port
SCK_0;
}

void show(void)
{
unsigned char temp_shi,temp_ge,SH_shi,SH_ge,x,y;
unsigned int i;
st=dht();
t=st&0x0000ffff;
s=st&0xffff0000;
s=s>>16;
//The following is to convert the temperature and humidity into decimal and round them off
temp=(t>>8);
temp_shi=temp/10;
temp_ge=temp%10;
SH=(s>>8);
SH_shi=SH/10;
SH_ge=SH%10;

int_part=SH_shi*10+SH_ge;
float_part=0;
for(i=0;i<50;i++)
{
digitron_show(int_part,float_part);
}
}

void digitron_show(unsigned int int_part,unsigned int float_part)
{
PORTA=0x01;
send_595(table[float_part/10]);
send_595(0x00);
delay_ms(5);

PORTA=0x02;
send_595(table[(int_part%10)+ 10]);
send_595(0x00);
delay_ms(5);

PORTA=0x04;
send_595(table[int_part/10]);
send_595(0x00);
delay_ms(5);
}

==================================================
//This is MAIN.C

#include
#include
#include"delay.h"
#include"dht11.h"
#include"xianshi.h"

#pragma interrupt_handler Timer0_COMP:16
#define uchar unsigned char
uchar k=0;
void init(void);

void main()
{
init(); //initialize
TCCR0=0X0F;
DDRA=0XFF;
TCCR0=0X0f; //CTC mode
OCR0=145; //10ms
TIMSK=0X02;
SEI();
while(1);
}

// Initialization sub-function
void init(void)
{
DDRA=0XFF;
DDRB=0XFF;
}

void Timer0_COMP(void)
{
TCCR0=0X08;
CLI();
k++;
if(k==255)
{
k=0;
show();
}
TCCR0=0X0f;//Reset initial value
SEI();
}

The program ends here, I hope you can give me more valuable suggestions!!!

Keywords:ATmega128 Reference address:Use of DHT11 temperature and humidity sensor based on ATmega128

Previous article:Design of a new type of safety device to prevent rear-end collision based on AVR
Next article:Balancing system based on ATmega128 encoder to control stepper motor

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号