STM32传感器外设集--温湿度模块(AH120)

目录

一、前言

原理图

1.优点

二、资料获取

关注微信公众号--星之援工作室 发送关键字(AHT20)

三、代码部分

 main.c

myiic.h

myiic.c

temhum.h

temhum.c

四、参考


一、前言

AH120是一种温湿度模块,它是由传感器和信号处理电路组成的,用于测量周围环境的温度和湿度。 AH120模块具有以下特点和优势:

1. 高精度测量:AH120采用高精度的温湿度传感器,能够提供准确的温湿度测量结果。温度测量精度一般可以达到±0.5℃,湿度测量精度一般可以达到±3%RH。

2. 宽工作范围:AH120模块的温度测量范围一般为-40℃至+125℃,湿度测量范围一般为0%RH至100%RH,可以满足多种应用场景的需求。

3. 数字输出:AH120模块通常采用数字接口输出,如I2C或SPI接口,方便和微控制器或其他数字设备进行连接和通信。

4. 低功耗:AH120模块通常具有低功耗特性,适合在电池供电的设备中使用,可以有效延长设备的工作时间。

5. 小型化设计:AH120模块通常采用紧凑的封装,体积小、重量轻,便于集成到各种设备和系统中。

AH120温湿度模块常见于室内温湿度监测、气象仪器、智能家居设备、空调系统、温室监测等领域,为用户提供准确的温湿度数据,以便进行数据分析、环境控制和决策制定等。

原理图

在这里插入图片描述

1.优点

  • 高精度,完全校准
  • 极高的可靠性与卓越的长期稳定性(较上一代aht10有极大的提升)
  • 抗干扰能力强
  • 性价比极高
  • 适用于恶劣的环境条件下

AH120相比与DHT11,采用的IIC数据采集协议,精度实现更高,耐用性与稳定性更好

二、资料获取

关注微信公众号--星之援工作室 发送关键字(AHT20

➡️🫡🫡🫡🫡🫡🫡🫡🫡➡️

 

三、代码部分

 main.c

 int main(void)
 {	 	
    u32 CT_data[2]={0};
    volatile float  hum=0,tem=0;     
     
    delay_init();	    	 //延时函数初始化	  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init(115200);	 //串口初始化为115200
    LED_Init();			     //LED端口初始化
    temphum_init();     //ATH20初始化    
	
	while(1)
	{
        AHT20_Read_CTdata(CT_data);       //不经过CRC校验,直接读取AHT20的温度和湿度数据 

        hum = CT_data[0]*100*10/1024/1024;  //计算得到湿度值(放大了10倍)
        tem = CT_data[1]*200*10/1024/1024-500;//计算得到温度值(放大了10倍)

        printf("湿度:%.1f%%\r\n",(hum/10));
        printf("温度:%.1f度\r\n",(tem/10));
        printf("\r\n");
        
        //延时2s,LED闪烁提示串口发送状态
        LED=0;
        delay_ms(1000);
        LED=1;
        delay_ms(1000);
	 }

}

myiic.h

#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"

//IO方向设置
 
#define SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}

//IO操作函数	 
#define IIC_SCL    PBout(6) //SCL
#define IIC_SDA    PBout(7) //SDA	 
#define READ_SDA   PBin(7)  //输入SDA 

//IIC所有操作函数
void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);	  
#endif

myiic.c

#include "myiic.h"
#include "delay.h"
 
//初始化IIC
void IIC_Init(void)
{					     
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); 	//PB6,PB7 输出高
}
//产生IIC起始信号
void IIC_Start(void)
{
	SDA_OUT();     //sda线输出
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(4);
 	IIC_SDA=0;//START:when CLK is high,DATA change form high to low 
	delay_us(4);
	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	  
//产生IIC停止信号
void IIC_Stop(void)
{
	SDA_OUT();//sda线输出
	IIC_SCL=0;
	IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
 	delay_us(4);
	IIC_SCL=1; 
	IIC_SDA=1;//发送I2C总线结束信号
	delay_us(4);							   	
}
等待应答信号到来
返回值:1,接收应答成功
        0,接收应答失败
u8 IIC_Wait_Ack(void)
{
	u8 ucErrTime=0;
	SDA_IN();      //SDA设置为输入  
	IIC_SDA=1;delay_us(1);	   
	IIC_SCL=1;delay_us(1);	 
	while(READ_SDA)
	{
		ucErrTime++;
		if(ucErrTime>250)
		{
			IIC_Stop();
			return 0;
		}
	}
	IIC_SCL=0;//时钟输出0 	   
	return 1; 
}    

//产生ACK应答
void IIC_Ack(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=0;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}
//不产生ACK应答		    
void IIC_NAck(void)
{
	IIC_SCL=0;
	SDA_OUT();
	IIC_SDA=1;
	delay_us(2);
	IIC_SCL=1;
	delay_us(2);
	IIC_SCL=0;
}					 				     
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答			  
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
	SDA_OUT(); 	    
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        IIC_SDA=(txd&0x80)>>7;
        txd<<=1; 	  
		delay_us(2);   //对TEA5767这三个延时都是必须的
		IIC_SCL=1;
		delay_us(2); 
		IIC_SCL=0;	
		delay_us(2);
    }	 
} 	    
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
	{
        IIC_SCL=0; 
        delay_us(2);
		IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
		delay_us(1); 
    }					 
    if (!ack)
        IIC_NAck();//发送nACK,表示停止接收
    else
        IIC_Ack(); //发送ACK,表示继续接收   
    return receive;
}


temhum.h

#ifndef __TEMHUM_H
#define __TEMHUM_H

/*******************
*
*  @file    temhum.h 
*  @author  LYJ
*  @version V1.0
*  @attention
*       用于AHT20温湿度传感器通信的相关函数
*
********************/

#include "myiic.h"
#include "delay.h"

void temphum_init(void);
u8 AHT20_Read_Status(void);
void AHT20_SendAC(void);
void AHT20_Init(void);
void AHT20_Read_CTdata(u32 *ct);


#endif

temhum.c

#include "temhum.h"

//读取AHT20的状态寄存器
u8 AHT20_Read_Status(void)
{
	u8 Byte_first,flag;	
	IIC_Start();
    IIC_Send_Byte(0x71);
	flag=IIC_Wait_Ack();
	Byte_first = IIC_Read_Byte(flag);
	IIC_NAck();
	IIC_Stop();

	return Byte_first;
}

//向AHT20发送AC命令
void AHT20_SendAC(void) 
{
	IIC_Start();
	IIC_Send_Byte(0x70);    //启动传输后发送的01110000 (最后1bit表示读/写 0--写,1--读)
	IIC_Wait_Ack();
	IIC_Send_Byte(0xac);//0xAC采集命令 命令参数有两个字节,第一个字节为 0x33,第二个字节为0x00。
	IIC_Wait_Ack();
	IIC_Send_Byte(0x33);
	IIC_Wait_Ack();
	IIC_Send_Byte(0x00);
	IIC_Wait_Ack();
	IIC_Stop();

}

//初始化AHT20
void AHT20_Init(void)   
{	
	IIC_Init();
	IIC_Start();
	IIC_Send_Byte(0x70);
	IIC_Wait_Ack();
	IIC_Send_Byte(0xa8);//0xA8进入NOR工作模式
	IIC_Wait_Ack();
	IIC_Send_Byte(0x00);
	IIC_Wait_Ack();
	IIC_Send_Byte(0x00);
	IIC_Wait_Ack();
	IIC_Stop();

	delay_ms(10);//延时10ms左右

	IIC_Start();
	IIC_Send_Byte(0x70);
	IIC_Wait_Ack();
	IIC_Send_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE,   AHT10的初始化命令是0xE1
	IIC_Wait_Ack();
	IIC_Send_Byte(0x08);//相关寄存器bit[3]置1,为校准输出
	IIC_Wait_Ack();
	IIC_Send_Byte(0x00);
	IIC_Wait_Ack();
	IIC_Stop();
	delay_ms(10);//延时10ms左右
}

void temphum_init()
{
	delay_ms(40);//刚上电,延时40ms才可以读取状态
	
    //首先发0x71读取状态字bit[3],如果=1,为校准输出,无须初始化!!!正常情况下读回来的状态是0x1C或者是0x18,读回来是0x80表示忙状态;
	if(!((AHT20_Read_Status()&0x08)==0x08))
	{
        AHT20_Init(); //初始化AHT20 
	}
}

//没有CRC校验,直接读取AHT20的温度和湿度数据    
void AHT20_Read_CTdata(u32 *ct) 
{
	volatile u8 Byte_1th=0,Byte_2th=0,Byte_3th=0;
    volatile u8 Byte_4th=0,Byte_5th=0,Byte_6th=0;
	u32 RetuData = 0;
	u16 cnt = 0,flag;
	AHT20_SendAC();//向AHT20发送AC命令
	delay_ms(80);	//大约延时80ms
    
	while(((AHT20_Read_Status()&0x80)==0x80))//直到状态bit[7]为0,表示为空闲状态,若为1,表示忙状态
	{
		delay_ms(1);
		if(cnt++>=100) break;
	}
    
	IIC_Start();
	IIC_Send_Byte(0x71);
	flag=IIC_Wait_Ack();
	Byte_1th = IIC_Read_Byte(flag);//状态字
	Byte_2th = IIC_Read_Byte(flag);//湿度,发送ACK(继续发送)
	Byte_3th = IIC_Read_Byte(flag);//湿度
	Byte_4th = IIC_Read_Byte(flag);//湿度/温度
	Byte_5th = IIC_Read_Byte(flag);//温度
	Byte_6th = IIC_Read_Byte(!flag);//温度,发送NACK(停止发送)  
	IIC_Stop();
    
    //保存得到的数据到RetuData中
	RetuData = (RetuData|Byte_2th)<<8;  
	RetuData = (RetuData|Byte_3th)<<8;
	RetuData = (RetuData|Byte_4th);
	RetuData =RetuData >>4;
	ct[0] = RetuData;//湿度
    
	RetuData = 0;
	RetuData = (RetuData|Byte_4th)<<8;
	RetuData = (RetuData|Byte_5th)<<8;
	RetuData = (RetuData|Byte_6th);
	RetuData = RetuData&0x0fffff;
	ct[1] =RetuData; //温度
}

四、参考

Arduino uno R3结合温湿度模块AHT10的参考代码icon-default.png?t=N7T8https://blog.csdn.net/qq_45512059/article/details/106281476?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170218292516800182154274%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=170218292516800182154274&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-106281476-null-null.142^v96^pc_search_result_base7&utm_term=%E6%B8%A9%E6%B9%BF%E5%BA%A6%E6%A8%A1%E5%9D%97AH120&spm=1018.2226.3001.4187

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿柒学起来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值