亚洲一区二区三区国产日韩欧美_日韩无码动漫精品一区_欧美日韩另类视频在线_国产极品美女扒开粉嫩小泬91_无遮挡又爽又刺激的视频_综合高清亚洲无码_天天躁夜夜躁狠狠85台湾_一区二区日韩精选_精品国产第一网站_先锋影音中文字幕51啪啪

新聞資訊
操作溫濕度傳感器AM2301(又名DHT21)AVR單片機atmega16
2010-11-10


AM2301是國產(chǎn)的溫濕度傳感器,想較瑞士的SHT1X,價格低廉,但性能有所降低,在對性能 要求不是很高的情況下,可以考慮用該款溫濕度傳感器。 AM2301/DHT21電容型數(shù)字溫濕度傳感器(替代SHT10 SHT11 SHT15)。

AM2301


單片機對AM2301的操作非常簡單,通過AM2301的數(shù)據(jù)手冊,便可寫出訪問它的程序,例程如下,期望能達到拋磚引玉的目的,以AVR系列的Mega16為例:

一、頭文件

[code="CSHARP"]
/*******************************************************************************
文件:am2301.h
作者:wxxujian
用途:溫濕度傳感器AM2301(又名:DHT21)的驅(qū)動程序
MCU: AVR Mega16 晶振:8MHz
編譯器:WinAVR2010
版本:1.0(創(chuàng)建日期:2010-7-27) 能正常顯示濕度,僅能顯示正溫度
1.1(修改日期:2010-7-28) 能正常顯示濕度和溫度(正、負溫度均可)
日期:2010-7-27
*********************************************************************************/

#include <avr/io.h>

#ifndef AM2301_H
#define AM2301_H

////////////////////////////// 宏定義(須根據(jù)實際情況而修改) ///////////////////////////////

//功能:定義與AM2301的數(shù)據(jù)位相連的單片機的端口及數(shù)據(jù)位
//注意:這些宏須隨著實際的硬件電路情況而修改

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

////////////////////////////// 宏定義(結(jié)束) ///////////////////////////////


////////////////////////////// 函數(shù)聲明 //////////////////////////////////////////////////
//說明:共2個函數(shù),分別是:
// AM2301_CollectCharData(int *pvHumidity,int *pvTemperature)
// AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature)
//詳細內(nèi)容如下:


/********************************************************************************
函數(shù)名:AM2301_CollectCharData(int *pvHumidity,int *pvTemperature)
功 能:獲得數(shù)據(jù)(濕度、溫度),獲得的數(shù)據(jù)保存于形參所提供的指針所指向的變量中
返回值:
0:數(shù)據(jù)校驗正確;
1:數(shù)據(jù)校驗錯誤
2:獲取數(shù)據(jù)錯誤
3: 等待響應(yīng)信號錯誤
參 數(shù):
pvHumidity: 濕度變量的指針,用于保存采集到的濕度,數(shù)據(jù)類型為:signed char,得到的數(shù)據(jù)僅為濕度的整數(shù)部分,小數(shù)部分自動舍棄
pvTemperature:溫度變量的指針,用于保存采集到的溫度,數(shù)據(jù)類型為:signed char,得到的數(shù)據(jù)僅為溫度的整數(shù)部分,小數(shù)部分自動舍棄


說 明:建議執(zhí)行此函數(shù)的間隔為2秒,絕不能小1秒。若間隔時間很長,建議采集2次,以2次為準
當發(fā)生錯誤,即返回值為1、2或3時,應(yīng)間隔2秒后重新讀取數(shù)據(jù)
注 意:因為:WinAVR默認將char 視為unsigned char
所以:參數(shù)必須定義為signed char,-128<signed char<127,足以保存所得到的數(shù)據(jù)
原 理:詳見AM2301的數(shù)據(jù)手冊
*********************************************************************************/
unsigned char AM2301_CollectCharData(signed char *pvHumidity,signed char *pvTemperature);

/********************************************************************************
函數(shù)名:AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature)
功 能:獲得數(shù)據(jù)(濕度、溫度),獲得的數(shù)據(jù)保存于形參所提供的指針所指向的變量中
返回值:
0:數(shù)據(jù)校驗正確;
1:數(shù)據(jù)校驗錯誤
2:獲取數(shù)據(jù)錯誤
3: 等待響應(yīng)信號錯誤
參 數(shù):
pvHumidity: 濕度變量的指針,用于保存采集到的濕度,數(shù)據(jù)類型為:float,得到的數(shù)據(jù)為完整的數(shù)據(jù),但不要用此float數(shù)據(jù)去比較
pvTemperature:溫度變量的指針,用于保存采集到的溫度,數(shù)據(jù)類型為:float,得到的數(shù)據(jù)為完整的數(shù)據(jù),但不要用此float數(shù)據(jù)去比較 說 明:建議執(zhí)行此函數(shù)的間隔為2秒,絕不能小1秒。若間隔時間很長,建議采集2次,以2次為準
當發(fā)生錯誤,即返回值為1、2或3時,應(yīng)間隔2秒后重新讀取數(shù)據(jù)
原 理:詳見AM2301的數(shù)據(jù)手冊
*********************************************************************************/
unsigned char AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature);

////////////////////////////// 函數(shù)聲明(結(jié)束) //////////////////////////////////////////////////

#endif
[/code]

二、實現(xiàn)文件

[code="c"]
/***********************************************************************************************
文件:am2301.c
作者:wxxujian
用途:溫濕度傳感器AM2301(又名:DHT21)的驅(qū)動程序
MCU: AVR Mega16 晶振:8MHz
編譯器:WinAVR2010
版本:1.0(創(chuàng)建日期:2010-7-27) 能正常顯示濕度,僅能顯示正溫度
  1.1(修改日期:2010-7-28) 能正常顯示濕度和溫度(正、負溫度均可)
日期:2010-7-27
***********************************************************************************************/

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


//////////////////////////////   宏定義(函數(shù)樣式)   ///////////////////////////////////////////

//功能:操作與am2301的數(shù)據(jù)位相連的單片機端口與相應(yīng)位,包括:輸入、輸出、置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)

//////////////////////////////   宏定義(結(jié)束)   ///////////////////////////////////////////


//////////////////////////////      函數(shù)實現(xiàn)    //////////////////////////////////////////////////
//說明:共3個函數(shù),分別是:
// AM2301_ReadByte(unsigned char *pvData)
// AM2301_CollectCharData(int *pvHumidity,int *pvTemperature)
// AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature)
//詳細內(nèi)容如下:

/********************************************************************************
函數(shù)名:AM2301_ReadByte(unsigned char *pvData)
功  能:讀取1個字節(jié)的數(shù)據(jù)
返回值:0:成功;2:讀數(shù)據(jù)錯誤
參  數(shù):pvData:所讀取的數(shù)據(jù)
條  件:與am2301的數(shù)據(jù)位相連的單片機端口為“輸入模式”
注  意:此函數(shù)為輔助函數(shù),僅供本文件使用,外部無法訪問
原  理:數(shù)據(jù)是從高位往低位依次讀取,讀得數(shù)據(jù)的順序為:濕度高位+濕度低位+溫度高位+溫度低位+校驗位
*********************************************************************************/
unsigned char AM2301_ReadByte(unsigned char *pvData)
{
unsigned char lvReturn=0,lvI,lvCount,lvBit;

for(lvI=0;lvI<8;lvI++) //循環(huán)8次,得到1個字節(jié)(含8個數(shù)據(jù)位)的數(shù)據(jù)
{
lvCount=1;
while( ! TestDataBit()  && lvCount>0 ) //判斷叢機是否發(fā)來50us的低電平信號,若超時返回2
lvCount++;
if(lvCount==0)
{
lvReturn=2;
break;
}

_delay_us(35); //延時35us

//判斷數(shù)據(jù)是0或1
lvBit=0;
if(TestDataBit())
lvBit=1;

lvCount=1;
while( TestDataBit()  && lvCount>0 ) //判斷叢機是否發(fā)來26-28us的高電平信號,若超時返回2
lvCount++;
if(lvCount==0)
{
lvReturn=2;
break;
}

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

}

return lvReturn;
}


/********************************************************************************
函數(shù)名:AM2301_CollectCharData(int *pvHumidity,int *pvTemperature)
功  能:獲得數(shù)據(jù)(濕度、溫度),獲得的數(shù)據(jù)保存于形參所提供的指針所指向的變量中
返回值:
0:數(shù)據(jù)校驗正確;
1:數(shù)據(jù)校驗錯誤
2:獲取數(shù)據(jù)錯誤
3: 等待響應(yīng)信號錯誤
參  數(shù):
pvHumidity:   濕度變量的指針,用于保存采集到的濕度,數(shù)據(jù)類型為:signed char,得到的數(shù)據(jù)僅為濕度的整數(shù)部分,小數(shù)部分自動舍棄
pvTemperature:溫度變量的指針,用于保存采集到的溫度,數(shù)據(jù)類型為:signed char,得到的數(shù)據(jù)僅為溫度的整數(shù)部分,小數(shù)部分自動舍棄


說  明:建議執(zhí)行此函數(shù)的間隔為2秒,絕不能小1秒。若間隔時間很長,建議采集2次,以2次為準
當發(fā)生錯誤,即返回值為1、2或3時,應(yīng)間隔2秒后重新讀取數(shù)據(jù)
注  意:因為:WinAVR默認將char 視為unsigned char 
所以:參數(shù)必須定義為signed char,-128<signed char<127,足以保存所得到的數(shù)據(jù)
原  理:詳見AM2301的數(shù)據(jù)手冊
*********************************************************************************/
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); //持續(xù)500us
SetDataBit(); //釋放總線

//主機檢測叢機
SetDataBitInput();
_delay_us(40);

if(! TestDataBit())
{
lvCount=1;
while( ! TestDataBit() && lvCount >0)  //判斷叢機是否發(fā)送了80us的高電平信號
lvCount++;
if(lvCount==0)
return 3;

lvCount=1;
while( TestDataBit() && lvCount >0)  //判斷叢機是否發(fā)送了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) //數(shù)據(jù)校驗,若正確則獲得正確的濕度和溫度,并返回1
{
//lvTemperatureHigh |=0x80;

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

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

if(lvTemp16 & 0x8000) //如果溫度是負值,則轉(zhuǎn)化
{
lvTemp16 &=0x7FFF;
lvTemp=0-lvTemp16;

*pvTemperature=lvTemp /10 ;
}

else

{

*pvTemperature=lvTemp16/10 ;

}

lvReturn=0;
}
else //數(shù)據(jù)校驗,若錯誤,則返回1
lvReturn=1;

}
return lvReturn;

}
/********************************************************************************
函數(shù)名:AM2301_CollectFloatData(float *pvHumidity,float *pvTemperature)
功  能:獲得數(shù)據(jù)(濕度、溫度),獲得的數(shù)據(jù)保存于形參所提供的指針所指向的變量中
返回值:
0:數(shù)據(jù)校驗正確;
1:數(shù)據(jù)校驗錯誤
2:獲取數(shù)據(jù)錯誤
3: 等待響應(yīng)信號錯誤
參  數(shù):
pvHumidity:   濕度變量的指針,用于保存采集到的濕度,數(shù)據(jù)類型為:float,得到的數(shù)據(jù)為完整的數(shù)據(jù),但不要用此float數(shù)據(jù)去比較
pvTemperature:溫度變量的指針,用于保存采集到的溫度,數(shù)據(jù)類型為:float,得到的數(shù)據(jù)為完整的數(shù)據(jù),但不要用此float數(shù)據(jù)去比較


說  明:建議執(zhí)行此函數(shù)的間隔為2秒,絕不能小1秒。若間隔時間很長,建議采集2次,以2次為準
當發(fā)生錯誤,即返回值為1、2或3時,應(yīng)間隔2秒后重新讀取數(shù)據(jù)
原  理:詳見AM2301的數(shù)據(jù)手冊
*********************************************************************************/
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;

//若正確讀取了數(shù)據(jù),則轉(zhuǎn)化為float型數(shù)據(jù)
*pvHumidity=lvHumidity/10;
*pvTemperature=lvTemperature/10;

return lvReturn;
}
[/code]

//////////////////////////////      函數(shù)實現(xiàn)(結(jié)束)    //////////////////////////////////////////////////


關(guān)注有人微信公眾號
了解更多信息