打印
[应用相关]

STM32 AM2305高精度温湿度传感器驱动

[复制链接]
806|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
heimaojingzhang|  楼主 | 2021-8-2 13:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近用到的温湿度传感器,AM2305驱动,单总线,上电后至少要延时2S才能读取温湿度,温度精度很高,跟DS18B20一样,数据带校验,不会出现DS18B20那样,并且时序要求不高


/*************************************************************************************************************
* 文件名:                        AM2305.c
* 功能:                        STM32 AM2305高精度温湿度传感器驱动
* 作者:                        cp1300@139.com
* 创建时间:                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复位
*参数                :        无
*返回                :        无
*依赖                        :         底层宏定义
*作者               :        cp1300@139.com
*时间                     :        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:检测成功
*依赖                        :         底层宏定义
*作者               :        cp1300@139.com
*时间                     :        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数据
*参数                :        无
*返回                :        数据
*依赖                        :         底层宏定义
*作者               :        cp1300@139.com
*时间                     :        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;               
}


使用特权

评论回复
沙发
heimaojingzhang|  楼主 | 2021-8-2 13:31 | 只看该作者
/*************************************************************************************************************************
*函数                :        u8 AM2305_ReadByte(void)
*功能                :        从AM2305读取一个字节
*参数                :        无
*返回                :        读取到的数据
*依赖                        :         底层宏定义
*作者               :        cp1300@139.com
*时间                     :        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:读取成功
*依赖                        :         底层宏定义
*作者               :        cp1300@139.com
*时间                     :        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=AM2305_ReadByte();
                }
//               
//                uart_printf("\nAM2305:");
//                for(i=0;i<5;i++)//读取40位数据
//                {
//                        uart_printf("0x%02X\t",buf);
//                }
//                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:成功
*依赖                        :         底层宏定义
*作者               :        cp1300@139.com
*时间                     :        2014-09-20
*最后修改时间        :        2014-09-20
*说明                :        无
*************************************************************************************************************************/
bool AM2305_Init(void)
{
        AM2305_CLK_INIT();
        AM2305_IO_OUT();       
        AM2305_Reset();
        return AM2305_Check();
}


使用特权

评论回复
板凳
heimaojingzhang|  楼主 | 2021-8-2 13:31 | 只看该作者
头文件
/*************************************************************************************************************
* 文件名:                        AM2305.c
* 功能:                        STM32 AM2305高精度温湿度传感器驱动
* 作者:                        cp1300@139.com
* 创建时间:                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_*/


使用特权

评论回复
地板
heimaojingzhang|  楼主 | 2021-8-2 13:31 | 只看该作者
读取温湿度
AM2305_ReadData(&temp, &hum);

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

85

主题

4142

帖子

4

粉丝