AVR单片机操作AM2301(即DHT21)

 

am2301为国产的温湿度传感器,价格便宜,适合对精度要求不是很高的场合。

一、am2301数据手册

二、头文件

/***********************************************************************************************

文件: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

 

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

 

 

//////////////////////////////      函数声明    //////////////////////////////////////////////////

//说明:共3个函数,分别是:

// AM2301_CollectIntData(int *pvHumidity,int *pvTemperature)

// AM2301_CollectCharData(int *pvHumidity,int *pvTemperature)

// AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature)

//详细内容如下:

 

/********************************************************************************

函数名: AM2301_CollectIntData(int *pvHumidity,int *pvTemperature)

功  能: 获得数据(湿度、温度),获得的数据保存于形参所提供的指针所指向的变量中

返回值:

0:数据校验正确;

1:数据校验错误

2:获取数据错误

3: 等待响应信号错误

参  数:

pvHumidity:   湿度变量的指针,用于保存采集到的湿度,数据类型为:int,此数据未经任何处理

pvTemperature:温度变量的指针,用于保存采集到的温度,数据类型为:int,此数据未经任何处理

 

 

说  明: 建议执行此函数的间隔为2秒,绝不能小1秒。若间隔时间很长,建议采集2次,以2次为准

    当发生错误,即返回值为1、2或3时,应间隔2秒后重新读取数据

注  意: 因为:WinAVR默认将char 视为unsigned char 

所以:参数必须定义为signed char,-128<signed char<127,足以保存所得到的数据

原  理:详见AM2301的数据手册

*********************************************************************************/

unsigned char AM2301_CollectIntData(int *pvHumidity,int *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)
//////////////////////////////   宏定义(结束)   ///////////////////////////////////////////
//////////////////////////////      函数实现    //////////////////////////////////////////////////
//说明:共4个函数,分别是:
// AM2301_ReadByte(unsigned char *pvData)
// AM2301_CollectIntData(int *pvHumidity,int *pvTemperature)
// 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)
return 2;
_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)
return 2;
//把得到的每一位数据保存于pvData中
*pvData<<=1;
*pvData|=lvBit;
}
return lvReturn;
}
/********************************************************************************
函数名:AM2301_CollectIntData(int *pvHumidity,int *pvTemperature)
功  能:获得数据(湿度、温度),获得的数据保存于形参所提供的指针所指向的变量中
返回值:
0:数据校验正确;
1:数据校验错误
2:获取数据错误
3: 等待响应信号错误
参  数:
pvHumidity:   湿度变量的指针,用于保存采集到的湿度,数据类型为:int,此数据未经任何处理
pvTemperature:温度变量的指针,用于保存采集到的温度,数据类型为:int,此数据未经任何处理
说  明: 建议执行此函数的间隔为2秒,绝不能小1秒。若间隔时间很长,建议采集2次,以2次为准
当发生错误,即返回值为1、2或3时,应间隔2秒后重新读取数据
注  意: 因为:WinAVR默认将char 视为unsigned char 
所以:参数必须定义为signed char,-128<signed char<127,足以保存所得到的数据
原  理:详见AM2301的数据手册
*********************************************************************************/
unsigned char AM2301_CollectIntData(int *pvHumidity,int *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(600); //持续至少500us,现取600us
SetDataBit(); //释放总线
//主机检测丛机
SetDataBitInput();
_delay_us(40+5); //应延时20-40us
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;
//把温度的高位和地位组合,得到完整的温度
lvTemp16=lvTemperatureHigh;
lvTemp16 <<=8;
lvTemp16 |= lvTemperatureLow;
if(lvTemp16 & 0x8000) //如果温度是负值,则转化
{
lvTemp16 &=0x7FFF;
lvTemp=0-lvTemp16;
*pvTemperature=lvTemp;
}
else
*pvTemperature=lvTemp16;
lvReturn=0; //执行到此处,说明无任何错误
}
else //数据校验,若错误,则返回1
lvReturn=1;
}
return lvReturn;
}
/********************************************************************************
函数名:AM2301_CollectCharData(signed char *pvHumidity,signed char *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)
{
int lvHumidity;
int lvTemperature;
unsigned char lvReturn=0;
lvReturn=AM2301_CollectIntData(&lvHumidity,&lvTemperature);
if(lvReturn)
return lvReturn;
*pvHumidity=lvHumidity /10;
*pvTemperature=lvTemperature/10;
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)
{
int lvHumidity;
int lvTemperature;
unsigned char lvReturn=0;
lvReturn=AM2301_CollectIntData(&lvHumidity,&lvTemperature);
if(lvReturn)
return lvReturn;
*pvHumidity=lvHumidity/10;
*pvTemperature=lvTemperature/10;
return lvReturn;
}
//////////////////////////////      函数实现(结束)    //////////////////////////////////////////////////

 

发布了23 篇原创文章 · 获赞 0 · 访问量 5万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章