最新动态

工业物联网通讯专家!
认真做好每一件事,设计简单、可靠、价格合理的产品!

操作温湿度传感器AM2301(又名DHT21)AVR单片机atmega16

AM2301是国产的温湿度传感器,想较瑞士的SHT1X,价格低廉,但性能有所降低,在对性能 要求不是很高的情况下,可以考虑用该款温湿度传感器。 AM2301/DHT21电容型数字温湿度传感器(替代SHT10 SHT11 SHT15)。

AM2301


单片机对AM2301的操作非常简单,通过AM2301的数据手册,便可写出访问它的程序,例程如下,期望能达到抛砖引玉的目的,以AVR系列的Mega16为例:

一、头文件

/******************************************************************************* 
文件:am2301.h 
作者:wxxujian 
用途:温湿度传感器AM2301(又名:DHT21)的驱动程序 
MCU: AVR Mega16 晶振:8MHz 
编译器:WinAVR2010 
版本:1.0(创建日期:2010-7-27) 能正常显示湿度,仅能显示正温度 
1.1(修改日期:2010-7-28) 能正常显示湿度和温度(正、负温度均可) 
日期:2010-7-27 
*********************************************************************************/ 

#include <avr/io.h> 

#ifndef AM2301_H 
#define AM2301_H 

////////////////////////////// 宏定义(须根据实际情况而修改) /////////////////////////////// 

//功能:定义与AM2301的数据位相连的单片机的端口及数据位 
//注意:这些宏须随着实际的硬件电路情况而修改 

#define AM2301_DATA_DDR DDRD 
#define AM2301_DATA_PORT PORTD 
#define AM2301_DATA_PIN PIND 
#define AM2301_DATA_BIT PD2 

////////////////////////////// 宏定义(结束) /////////////////////////////// 


////////////////////////////// 函数声明 ////////////////////////////////////////////////// 
//说明:共2个函数,分别是: 
// AM2301_CollectCharData(int *pvHumidity,int *pvTemperature) 
// AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature) 
//详细内容如下: 


/******************************************************************************** 
函数名:AM2301_CollectCharData(int *pvHumidity,int *pvTemperature) 
功 能:获得数据(湿度、温度),获得的数据保存于形参所提供的指针所指向的变量中 
返回值: 
0:数据校验正确; 
1:数据校验错误 
2:获取数据错误 
3: 等待响应信号错误 
参 数: 
pvHumidity: 湿度变量的指针,用于保存采集到的湿度,数据类型为:signed char,得到的数据仅为湿度的整数部分,小数部分自动舍弃 
pvTemperature:温度变量的指针,用于保存采集到的温度,数据类型为:signed char,得到的数据仅为温度的整数部分,小数部分自动舍弃 


说 明:建议执行此函数的间隔为2秒,绝不能小1秒。若间隔时间很长,建议采集2次,以2次为准 
当发生错误,即返回值为1、2或3时,应间隔2秒后重新读取数据 
注 意:因为:WinAVR默认将char 视为unsigned char 
所以:参数必须定义为signed char,-128<signed char<127,足以保存所得到的数据 
原 理:详见AM2301的数据手册 
*********************************************************************************/ 
unsigned char AM2301_CollectCharData(signed char *pvHumidity,signed char *pvTemperature); 

/******************************************************************************** 
函数名:AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature) 
功 能:获得数据(湿度、温度),获得的数据保存于形参所提供的指针所指向的变量中 
返回值: 
0:数据校验正确; 
1:数据校验错误 
2:获取数据错误 
3: 等待响应信号错误 
参 数: 
pvHumidity: 湿度变量的指针,用于保存采集到的湿度,数据类型为:float,得到的数据为完整的数据,但不要用此float数据去比较 
pvTemperature:温度变量的指针,用于保存采集到的温度,数据类型为:float,得到的数据为完整的数据,但不要用此float数据去比较 说 明:建议执行此函数的间隔为2秒,绝不能小1秒。若间隔时间很长,建议采集2次,以2次为准 
当发生错误,即返回值为1、2或3时,应间隔2秒后重新读取数据 
原 理:详见AM2301的数据手册 
*********************************************************************************/ 
unsigned char AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature); 

////////////////////////////// 函数声明(结束) ////////////////////////////////////////////////// 

#endif 


二、实现文件

/*********************************************************************************************** 
文件:am2301.c 
作者:wxxujian 
用途:温湿度传感器AM2301(又名:DHT21)的驱动程序 
MCU: AVR Mega16 晶振:8MHz 
编译器:WinAVR2010 
版本:1.0(创建日期:2010-7-27) 能正常显示湿度,仅能显示正温度 
  1.1(修改日期:2010-7-28) 能正常显示湿度和温度(正、负温度均可) 
日期:2010-7-27 
***********************************************************************************************/ 

#include "am2301.h" 
#include <util/delay.h> 
#include "common.h" 
#include "display.h" 


//////////////////////////////   宏定义(函数样式)   /////////////////////////////////////////// 

//功能:操作与am2301的数据位相连的单片机端口与相应位,包括:输入、输出、置1和清0 
//注意:这些宏只供此文件使用 
#define SetDataBitOutput() SetBit(AM2301_DATA_DDR,AM2301_DATA_BIT) 
#define SetDataBitInput() ClearBit(AM2301_DATA_DDR,AM2301_DATA_BIT) 
#define SetDataBit() SetBit(AM2301_DATA_PORT,AM2301_DATA_BIT) 
#define ClearDataBit() ClearBit(AM2301_DATA_PORT,AM2301_DATA_BIT) 
#define TestDataBit() TestBit(AM2301_DATA_PIN,AM2301_DATA_BIT) 

//////////////////////////////   宏定义(结束)   /////////////////////////////////////////// 


//////////////////////////////      函数实现    ////////////////////////////////////////////////// 
//说明:共3个函数,分别是: 
// AM2301_ReadByte(unsigned char *pvData) 
// AM2301_CollectCharData(int *pvHumidity,int *pvTemperature) 
// AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature) 
//详细内容如下: 

/******************************************************************************** 
函数名:AM2301_ReadByte(unsigned char *pvData) 
功  能:读取1个字节的数据 
返回值:0:成功;2:读数据错误 
参  数:pvData:所读取的数据 
条  件:与am2301的数据位相连的单片机端口为“输入模式” 
注  意:此函数为辅助函数,仅供本文件使用,外部无法访问 
原  理:数据是从高位往低位依次读取,读得数据的顺序为:湿度高位+湿度低位+温度高位+温度低位+校验位 
*********************************************************************************/ 
unsigned char AM2301_ReadByte(unsigned char *pvData) 
{ 
unsigned char lvReturn=0,lvI,lvCount,lvBit; 

for(lvI=0;lvI<8;lvI++) //循环8次,得到1个字节(含8个数据位)的数据 
{ 
lvCount=1; 
while( ! TestDataBit()  && lvCount>0 ) //判断丛机是否发来50us的低电平信号,若超时返回2 
lvCount++; 
if(lvCount==0) 
{ 
lvReturn=2; 
break; 
} 

_delay_us(35); //延时35us 

//判断数据是0或1 
lvBit=0; 
if(TestDataBit()) 
lvBit=1; 

lvCount=1; 
while( TestDataBit()  && lvCount>0 ) //判断丛机是否发来26-28us的高电平信号,若超时返回2 
lvCount++; 
if(lvCount==0) 
{ 
lvReturn=2; 
break; 
} 

//把得到的每一位数据保存于pvData中 
if(lvBit) 
*pvData |= 1<<(7-lvI); 
else 
*pvData &= ~1<<(7-lvI); 

} 

return lvReturn; 
} 


/******************************************************************************** 
函数名:AM2301_CollectCharData(int *pvHumidity,int *pvTemperature) 
功  能:获得数据(湿度、温度),获得的数据保存于形参所提供的指针所指向的变量中 
返回值: 
0:数据校验正确; 
1:数据校验错误 
2:获取数据错误 
3: 等待响应信号错误 
参  数: 
pvHumidity:   湿度变量的指针,用于保存采集到的湿度,数据类型为:signed char,得到的数据仅为湿度的整数部分,小数部分自动舍弃 
pvTemperature:温度变量的指针,用于保存采集到的温度,数据类型为:signed char,得到的数据仅为温度的整数部分,小数部分自动舍弃 


说  明:建议执行此函数的间隔为2秒,绝不能小1秒。若间隔时间很长,建议采集2次,以2次为准 
当发生错误,即返回值为1、2或3时,应间隔2秒后重新读取数据 
注  意:因为:WinAVR默认将char 视为unsigned char  
所以:参数必须定义为signed char,-128<signed char<127,足以保存所得到的数据 
原  理:详见AM2301的数据手册 
*********************************************************************************/ 
unsigned char AM2301_CollectCharData(signed char *pvHumidity,signed char *pvTemperature) 
{ 
unsigned char lvReturn=3,lvCount; 
unsigned int  lvTemp16; 
int lvTemp; 

unsigned char lvHumidityHigh; //湿度高位 
unsigned char lvHumidityLow;          //湿度低位 
unsigned char lvTemperatureHigh; //温度高位 
unsigned char lvTemperatureLow; //温度低位 
unsigned char lvCheck; //校验位 


//主机的操作 
SetDataBitOutput(); 
ClearDataBit(); //拉低总线 
_delay_us(500); //持续500us 
SetDataBit(); //释放总线 

//主机检测丛机 
SetDataBitInput(); 
_delay_us(40); 

if(! TestDataBit()) 
{ 
lvCount=1; 
while( ! TestDataBit() && lvCount >0)  //判断丛机是否发送了80us的高电平信号 
lvCount++; 
if(lvCount==0) 
return 3; 

lvCount=1; 
while( TestDataBit() && lvCount >0)  //判断丛机是否发送了80us的高电平信号 
lvCount++; 
if(lvCount==0)return 3; 

if(AM2301_ReadByte(&lvHumidityHigh)) //获得湿度高位 
return 2; 

if(AM2301_ReadByte(&lvHumidityLow)) //获得湿度高位 
return 2; 

if(AM2301_ReadByte(&lvTemperatureHigh)) //获得湿度高位 
return 2; 

if(AM2301_ReadByte(&lvTemperatureLow)) //获得湿度高位 
return 2; 

if(AM2301_ReadByte(&lvCheck)) //获得湿度高位 
return 2; 

lvCount=lvHumidityHigh+lvHumidityLow+lvTemperatureHigh+lvTemperatureLow;//计算湿度高位+湿度低位+温度高位+温度低位的和 

if(lvCount==lvCheck) //数据校验,若正确则获得正确的湿度和温度,并返回1 
{ 
//lvTemperatureHigh |=0x80; 

//把湿度的高位和地位组合,得到完整的湿度 
lvTemp16=lvHumidityHigh; 
lvTemp16 <<=8; 
lvTemp16 |= lvHumidityLow; 
*pvHumidity=lvTemp16/10; 

//把温度的高位和地位组合,得到完整的温度 
lvTemp16=lvTemperatureHigh; 
lvTemp16 <<=8; 
lvTemp16 |= lvTemperatureLow; 

if(lvTemp16 & 0x8000) //如果温度是负值,则转化 
{ 
lvTemp16 &=0x7FFF; 
lvTemp=0-lvTemp16; 

*pvTemperature=lvTemp /10 ; }

else

{

*pvTemperature=lvTemp16/10 ;

} lvReturn=0; } else //数据校验,若错误,则返回1 lvReturn=1; } return lvReturn; } /******************************************************************************** 函数名:AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature) 功  能:获得数据(湿度、温度),获得的数据保存于形参所提供的指针所指向的变量中 返回值: 0:数据校验正确; 1:数据校验错误 2:获取数据错误 3: 等待响应信号错误 参  数: pvHumidity:   湿度变量的指针,用于保存采集到的湿度,数据类型为:float,得到的数据为完整的数据,但不要用此float数据去比较 pvTemperature:温度变量的指针,用于保存采集到的温度,数据类型为:float,得到的数据为完整的数据,但不要用此float数据去比较 说  明:建议执行此函数的间隔为2秒,绝不能小1秒。若间隔时间很长,建议采集2次,以2次为准 当发生错误,即返回值为1、2或3时,应间隔2秒后重新读取数据 原  理:详见AM2301的数据手册 *********************************************************************************/ unsigned char AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature) { unsigned char lvReturn=0; signed   char lvHumidity; //湿度 signed   char lvTemperature; //温度 lvReturn=AM2301_CollectCharData(&lvHumidity,&lvTemperature); if(lvReturn) //若出错,则直接返回 return lvReturn; //若正确读取了数据,则转化为float型数据 *pvHumidity=lvHumidity/10; *pvTemperature=lvTemperature/10; return lvReturn; }



//////////////////////////////      函数实现(结束)    //////////////////////////////////////////////////



上一篇: 标准串口定义-9转25的串口线接法图
下一篇: 华为前高管讲述:华为为什么不上市

发表评论