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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章