AM2301是国产的温湿度传感器,想较瑞士的SHT1X,价格低廉,但性能有所降低,在对性能 要求不是很高的情况下,可以考虑用该款温湿度传感器。 单片机对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 ; 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; } ////////////////////////////// 函数实现(结束) ////////////////////////////////////////////////// |
欢迎光临 珩源工控论坛 (http://bbs.hymcu.com/) | Powered by Discuz! 7.2 |