基于C8051F410的am2305温湿度传感器的驱动编写

本文介绍了一个改进的DHT11温湿度传感器读取程序,该程序具有更高的精度和自动恢复连线问题的功能。通过优化代码实现,确保了设备在不同环境下的稳定运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个和那个DHT11差不多,精度稍高一点,价格相差十倍呢。程序很有改进,中间如果连线出问题则会自动恢复。

直接上程序吧。

#include <C8051F410.h>                 // SFR declarations
#include <stdio.h>

#define SYSCLK        24500000         // SYSCLK frequency in Hz
#define BAUDRATE      9600           // Baud rate of UART in bps
#define WAIT		  50000

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_am2305(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(1000);
		read_am2305();
   }
}

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);
}

unsigned char am2305_byte(void)
{
	unsigned char tmp1=0,wei=0;
	unsigned int cnt;
	
	for (wei=0;wei<8;wei++)
	{
		tmp1*=2;
		delay(90);
		cnt=0;
		while(0==dht_dat)
		{
			cnt++;
			if(cnt>WAIT)
			{
				printf("\n传输错误1");
				return 0;
			}
		}
		delay(60);
		if(1==dht_dat)
		{
			tmp1++;
			cnt=0;
			delay(80);
			while(1==dht_dat)
			{
				cnt++;
				if(cnt>WAIT)
				{
					printf("\n传输错误2");
					return 0;
				}
			}
		}
	}
	return tmp1;
}

void read_am2305(void)
{
	unsigned char wei=0;
	unsigned char humi_int=0,humi_float=0,temp_int=0,temp_float=0,chk_dat=0;
	float temp,humi;
	unsigned int cnt;

	dht_dat=1;
	printf("\n\n\n开始发送请求。\n");
	delay_ms(5);
	dht_dat=0;
	delay_ms(1);
	dht_dat=1;
	delay(40);
	cnt=0;
	while(1==dht_dat)
	{
		cnt++;
		if(cnt>WAIT)
		{
			printf("\n传感器未响应1。");
			return;
		}
	}
	//printf("下位机已响应--当前低电平。\n");
	delay(160);
	cnt=0;
	while(0==dht_dat)
	{
		cnt++;
		if(cnt>WAIT)
		{
			printf("\n传感器未响应2。");
			return;
		}
	}
	//printf("下位机已响应--当前高电平。\n");
	delay(160);
	cnt=0;
	while(1==dht_dat)
	{
		cnt++;
		if(cnt>WAIT)
		{
			printf("\n传感器未响应3。");
			return;
		}
	}
	//printf("下位机开始传送数据\n");

		//开始接收数据
	//湿度整数接受完成
	humi_int=am2305_byte();
	humi_float=am2305_byte();
	temp_int=am2305_byte();
	temp_float=am2305_byte();
	chk_dat=am2305_byte();
	
	humi=(float)((humi_int*256+humi_float)*0.1);
	temp=(float)(((temp_int & 0x7f)*256+temp_float)*0.1);
	if (temp_int & 0x80)
		temp=-temp;
	printf("湿度为:%2.1f%%。\n",humi);
	printf("温度为:%2.1f。\n",temp);
	printf("校验码为:%d\n",(int)chk_dat);
	// putchar('A');
	// scanf("%c",wei);
	// printf("\nyour input is:%d",(int)wei);
	if(chk_dat==(char)(humi_int+humi_float+temp_int+temp_float))
		printf("校验无误。\n",wei);
	else
		printf("校验出错。\n");
	delay_ms(2500);
}
















评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值