这个也是在暑假培训时做的一个小东西,之前在网上买了一些传感器,还花了不少大洋,于是就拿来练手了。
这个DHT11的输出引脚还要加上拉电阻,真是麻烦,程序也比较不好,如果连线出现问题就会死机,建议
参考下篇文章对AM2305的驱动编写,不过那东西可要一百多呢,这个才几块钱。
#include <C8051F410.h> // SFR declarations
#include <stdio.h>
#define SYSCLK 24500000 // SYSCLK frequency in Hz
#define BAUDRATE 9600 // Baud rate of UART in bps
sbit led1 = P2^1;
sbit led2 = P2^3;
sbit dht_dat = P0^6;
void Oscillator_Init (void);
void Port_Init(void);
void UART0_Init (void);
void delay(unsigned int m);
void delay_ms(unsigned int m);
void read_dth(void);
void main (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
Oscillator_Init (); // Initialize system clock to
// 24.5MHz
Port_Init();
UART0_Init(); // Initialize UART0 for printf's
EA = 1; // Enable global interrupts
printf("初始化完成!\n\n");
delay_ms(5000);
led1 = 1;
led2 = 1;
dht_dat = 1;
while (1)
{
delay_ms(2000);
read_dth();
}
}
void Oscillator_Init (void)
{
OSCICN = 0x87; // Configure internal oscillator for
// its highest frequency
RSTSRC = 0x04; // Enable missing clock detector
}
void Port_Init (void)
{
P1SKIP |= 0x40; // Skip all analog pins
XBR0 = 0x01; // UART0 TX and RX pins enabled
XBR1 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x10; // Enable TX0 as a push-pull output
}
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON |= 0x08; // T1M = 1; SCA1:0 = xx
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x01;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else if (SYSCLK/BAUDRATE/2/256 < 48) {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
} else {
while (1); // Error. Unsupported baud rate
}
TL1 = TH1; // Init Timer1
TMOD &= ~0xF0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
}
void delay(unsigned int m)
{
while(m--);
}
void delay_ms(unsigned int m)
{
while(m--)
delay(2046);
}
void read_dth(void)
{
unsigned char wei=0;
unsigned char humi_int=0,humi_float=0,temp_int=0,temp_float=0,chk_dat=0;
dht_dat=1;
printf("\n\n\n开始发送请求。\n");
delay_ms(100);
dht_dat=0;
delay_ms(25);
dht_dat=1;
delay(64);
while(1==dht_dat);
//printf("下位机已响应--当前低电平。\n");
while(0==dht_dat);
//printf("下位机已响应--当前高电平。\n");
while(1==dht_dat);
//printf("下位机开始传送数据\n");
//开始接收数据
for (wei=0;wei<8;wei++)
{
humi_int*=2;
while(0==dht_dat);
delay(62);
if(1==dht_dat)
{
humi_int++;
while(1==dht_dat);
}
} //湿度整数接受完成
for (wei=0;wei<8;wei++)
{
humi_float*=2;
while(0==dht_dat);
delay(62);
if(1==dht_dat)
{
humi_float++;
while(1==dht_dat);
}
} //湿度小数接收完成
for (wei=0;wei<8;wei++)
{
temp_int*=2;
while(0==dht_dat);
delay(62);
if(1==dht_dat)
{
temp_int++;
while(1==dht_dat);
}
} //温度整数接收完成
for (wei=0;wei<8;wei++)
{
temp_float*=2;
while(0==dht_dat);
delay(62);
if(1==dht_dat)
{
temp_float++;
while(1==dht_dat);
}
} //湿度小数接收完成
for (wei=0;wei<8;wei++)
{
chk_dat*=2;
while(0==dht_dat);
delay(62);
if(1==dht_dat)
{
chk_dat++;
while(1==dht_dat);
}
} //校验码接收完成
printf("湿度为:%d.%d\n",(int)humi_int,(int)humi_float);
printf("温度为:%d.%d\n",(int)temp_int,(int)temp_float);
printf("校验码为:%d\n",(int)chk_dat);
delay_ms(1500);
}
引脚我就不多说了,注意必须有上拉,没上拉不行的,我试过了,AM2305可以不要上拉。