最近用到的温湿度传感器,AM2305驱动,单总线,上电后至少要延时2S才能读取温湿度,温度精度很高,跟DS18B20一样,数据带校验,不会出现DS18B20那样,并且时序要求不高
/************************************************************************************************************* * 文件名: AM2305.c * 功能: STM32 AM2305高精度温湿度传感器驱动 * 作者: [email protected] * 创建时间: 2014-09-20 * 最后修改时间: 2014-09-20 * 详细: 需要延时函数支持 * 注意延时精度尽可能的高 * 读取的时候不要长时间的被中断,因为1wire对时间要求很严格 *************************************************************************************************************/ #include "system.h" #include "delay.h" #include "AM2305.h" //DS18B20使用的是GPIOE0 #define AM2305_CLK_INIT() DeviceClockEnable(AM2305_DEV, ENABLE); //时钟使能 #define AM2305_IO_OUT() GPIOx_Init(AM2305_GPIOx,AM2305_BITx,OUT_PP,SPEED_10M); //设置AM2305 IO为输出, #define AM2305_IO_IN() GPIOx_Init(AM2305_GPIOx,AM2305_BITx,IN_IPU,0); //设置AM2305 IO为上拉输入, #define AM2305_DQ_IN() ((AM2305_IN) ? 1 : 0) //读取AM2305 IO #define AM2305_DQ_OUT(x) (AM2305_OUT = x) //写AM2305 IO #define AM2305_IODown() GPIOx_Init(AM2305_GPIOx,AM2305_BITx,IN_IPT,0); //掉电,下拉输入 //精确us延时 #define AM2305_Delay_US(x) delay_us(x) //AM2305掉电 void AM2305_PowerDown(void) { AM2305_IODown(); } /************************************************************************************************************************* *函数 : void AM2305_Reset(void) *功能 : AM2305复位 *参数 : 无 *返回 : 无 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 2014-09-20 *最后修改时间 : 2014-09-20 *说明 : 无 *************************************************************************************************************************/ void AM2305_Reset(void) { AM2305_IO_OUT(); //SET OUTPUT AM2305_DQ_OUT(0); //拉低DQ AM2305_Delay_US(1000); //拉低至少800uS AM2305_DQ_OUT(1); //DQ=1 AM2305_Delay_US(30); //主机拉高20~40us } /************************************************************************************************************************* *函数 : bool AM2305_Check(void) *功能 : 等待AM2305的回应 *参数 : 无 *返回 : FALSE:检测失败;TRUE:检测成功 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 2014-09-20 *最后修改时间 : 2014-09-20 *说明 : 检测AM2305的存在 *************************************************************************************************************************/ bool AM2305_Check(void) { u32 retry=0; AM2305_IO_IN();//SET INPUT while (AM2305_DQ_IN()&&retry<100)//AM2305会拉低75~85us { retry++; AM2305_Delay_US(1); } if(retry>=100) { uart_printf("AM2305:retry1:%d\r\n",retry); return FALSE; } retry=0; while (!AM2305_DQ_IN()&&retry<100)//AM2305拉低后会再次拉高75~85us { retry++; AM2305_Delay_US(1); } if(retry>=100) { uart_printf("AM2305:retry2:%d\r\n",retry); return FALSE; } return TRUE; } /************************************************************************************************************************* *函数 : u8 AM2305_ReadBit(void) *功能 : 读取AM2305 1bit数据 *参数 : 无 *返回 : 数据 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 2014-09-20 *最后修改时间 : 2014-09-20 *说明 : *************************************************************************************************************************/ u8 AM2305_ReadBit(void) { u8 retry=0; while(AM2305_DQ_IN()&&retry<80)//等待变为低电平 { retry++; AM2305_Delay_US(1); } // if(retry>=80) // { // uart_printf("AM2305:retry3:%d\r\n",retry); // } retry=0; while(!AM2305_DQ_IN()&&retry<60)//等待变高电平 { retry++; AM2305_Delay_US(1); } // if(retry>=60) // { // uart_printf("AM2305:retry4:%d\r\n",retry); // } AM2305_Delay_US(38); if(AM2305_DQ_IN()) return 1; else return 0; } /************************************************************************************************************************* *函数 : u8 AM2305_ReadByte(void) *功能 : 从AM2305读取一个字节 *参数 : 无 *返回 : 读取到的数据 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 2014-09-20 *最后修改时间 : 2014-09-20 *说明 : 无 *************************************************************************************************************************/ u8 AM2305_ReadByte(void) { u8 i,dat; dat=0; for (i=0;i<8;i++) { dat<<=1; dat|=AM2305_ReadBit(); } return dat; } /************************************************************************************************************************* *函数 : bool AM2305_ReadData(s16 *pTemp,u16 *pHumi) *功能 : 从AM2305读取一次数据 *参数 : pTemp:温度指针,pHumi:湿度数据指针 *返回 : FALSE:读取失败;TRUE:读取成功 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 2014-09-20 *最后修改时间 : 2014-09-20 *说明 : 2014-09-29:修复负温度bug *************************************************************************************************************************/ bool AM2305_ReadData(s16 *pTemp,u16 *pHumi) { u8 buf[5]; u8 i; u16 utemp; AM2305_Reset(); if(AM2305_Check()==TRUE) { for(i=0;i<5;i++)//读取40位数据 { buf[i]=AM2305_ReadByte(); } // // uart_printf("\nAM2305:"); // for(i=0;i<5;i++)//读取40位数据 // { // uart_printf("0x%02X\t",buf[i]); // } // uart_printf("\n"); if((u8)(buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) { *pHumi=buf[0]; *pHumi <<= 8; *pHumi|=buf[1]; utemp=buf[2]; utemp<<=8; utemp|=buf[3]; if(utemp > 0x8000) { utemp -= 0x8000; *pTemp = 0-utemp; } else { *pTemp = utemp; } return TRUE; } else { uart_printf("AM2305数据校验失败!\r\n"); return FALSE; } } else { uart_printf("AM2305检测失败!\r\n"); return FALSE; } } /************************************************************************************************************************* *函数 : bool AM2305_Init(void) *功能 : 初始化AM2305,并检测存在 *参数 : 无 *返回 : FALSE:失败;TRUE:成功 *依赖 : 底层宏定义 *作者 : [email protected] *时间 : 2014-09-20 *最后修改时间 : 2014-09-20 *说明 : 无 *************************************************************************************************************************/ bool AM2305_Init(void) { AM2305_CLK_INIT(); AM2305_IO_OUT(); AM2305_Reset(); return AM2305_Check(); }
/************************************************************************************************************* * 文件名: AM2305.c * 功能: STM32 AM2305高精度温湿度传感器驱动 * 作者: [email protected] * 创建时间: 2014-09-20 * 最后修改时间: 2014-09-20 * 详细: 需要延时函数支持 * 注意延时精度尽可能的高 * 读取的时候不要长时间的被中断,因为1wire对时间要求很严格 *************************************************************************************************************/ #ifndef AM2305_H_ #define AM2305_H_ #include "system.h" #if(BOARD_SUPPORT) //需要板级支持 #include "board.h" #else //默认支持 //PC3 #define AM2305_OUT PCout(3) #define AM2305_IN PCin(3) //IO #define AM2305_DEV DEV_GPIOC #define AM2305_GPIOx GPIOC #define AM2305_BITx BIT3 #endif void AM2305_PowerDown(void); //AM2305掉电 bool AM2305_Init(void); //AM2305 初始化 bool AM2305_ReadData(s16 *pTemp,u16 *pHumi) ; //读取温湿度数据 #endif /*AM2305_H_*/
AM2305_ReadData(&temp, &hum);