一、前言
AH120是一種溫濕度模塊,它是由傳感器和信號(hào)處理電路組成的,用于測(cè)量周?chē)h(huán)境的溫度和濕度。 AH120模塊具有以下特點(diǎn)和優(yōu)勢(shì):
1. 高精度測(cè)量:AH120采用高精度的溫濕度傳感器,能夠提供準(zhǔn)確的溫濕度測(cè)量結(jié)果。溫度測(cè)量精度一般可以達(dá)到±0.5℃,濕度測(cè)量精度一般可以達(dá)到±3%RH。
2. 寬工作范圍:AH120模塊的溫度測(cè)量范圍一般為-40℃至+125℃,濕度測(cè)量范圍一般為0%RH至100%RH,可以滿(mǎn)足多種應(yīng)用場(chǎng)景的需求。
3. 數(shù)字輸出:AH120模塊通常采用數(shù)字接口輸出,如I2C或SPI接口,方便和微控制器或其他數(shù)字設(shè)備進(jìn)行連接和通信。
4. 低功耗:AH120模塊通常具有低功耗特性,適合在電池供電的設(shè)備中使用,可以有效延長(zhǎng)設(shè)備的工作時(shí)間。
5. 小型化設(shè)計(jì):AH120模塊通常采用緊湊的封裝,體積小、重量輕,便于集成到各種設(shè)備和系統(tǒng)中。
AH120溫濕度模塊常見(jiàn)于室內(nèi)溫濕度監(jiān)測(cè)、氣象儀器、智能家居設(shè)備、空調(diào)系統(tǒng)、溫室監(jiān)測(cè)等領(lǐng)域,為用戶(hù)提供準(zhǔn)確的溫濕度數(shù)據(jù),以便進(jìn)行數(shù)據(jù)分析、環(huán)境控制和決策制定等。
原理圖
1.優(yōu)點(diǎn)
- 高精度,完全校準(zhǔn)
- 極高的可靠性與卓越的長(zhǎng)期穩(wěn)定性(較上一代aht10有極大的提升)
- 抗干擾能力強(qiáng)
- 性?xún)r(jià)比極高
- 適用于惡劣的環(huán)境條件下
AH120相比與DHT11,采用的IIC數(shù)據(jù)采集協(xié)議,精度實(shí)現(xiàn)更高,耐用性與穩(wěn)定性更好
二、資料獲取
關(guān)注微信公眾號(hào)--星之援工作室 發(fā)送關(guān)鍵字(AHT20)
????
三、代碼部分
?main.c
int main(void)
{
u32 CT_data[2]={0};
volatile float hum=0,tem=0;
delay_init(); //延時(shí)函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
uart_init(115200); //串口初始化為115200
LED_Init(); //LED端口初始化
temphum_init(); //ATH20初始化
while(1)
{
AHT20_Read_CTdata(CT_data); //不經(jīng)過(guò)CRC校驗(yàn),直接讀取AHT20的溫度和濕度數(shù)據(jù)
hum = CT_data[0]*100*10/1024/1024; //計(jì)算得到濕度值(放大了10倍)
tem = CT_data[1]*200*10/1024/1024-500;//計(jì)算得到溫度值(放大了10倍)
printf("濕度:%.1f%%rn",(hum/10));
printf("溫度:%.1f度rn",(tem/10));
printf("rn");
//延時(shí)2s,LED閃爍提示串口發(fā)送狀態(tài)
LED=0;
delay_ms(1000);
LED=1;
delay_ms(1000);
}
}
myiic.h
#ifndef __MYIIC_H
#define __MYIIC_H
#include "sys.h"
//IO方向設(shè)置
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
//IO操作函數(shù)
#define IIC_SCL PBout(6) //SCL
#define IIC_SDA PBout(7) //SDA
#define READ_SDA PBin(7) //輸入SDA
//IIC所有操作函數(shù)
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //發(fā)送IIC開(kāi)始信號(hào)
void IIC_Stop(void); //發(fā)送IIC停止信號(hào)
void IIC_Send_Byte(u8 txd); //IIC發(fā)送一個(gè)字節(jié)
u8 IIC_Read_Byte(unsigned char ack);//IIC讀取一個(gè)字節(jié)
u8 IIC_Wait_Ack(void); //IIC等待ACK信號(hào)
void IIC_Ack(void); //IIC發(fā)送ACK信號(hào)
void IIC_NAck(void); //IIC不發(fā)送ACK信號(hào)
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時(shí)鐘
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 輸出高
}
//產(chǎn)生IIC起始信號(hào)
void IIC_Start(void)
{
SDA_OUT(); //sda線(xiàn)輸出
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總線(xiàn),準(zhǔn)備發(fā)送或接收數(shù)據(jù)
}
//產(chǎn)生IIC停止信號(hào)
void IIC_Stop(void)
{
SDA_OUT();//sda線(xiàn)輸出
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;//發(fā)送I2C總線(xiàn)結(jié)束信號(hào)
delay_us(4);
}
等待應(yīng)答信號(hào)到來(lái)
返回值:1,接收應(yīng)答成功
0,接收應(yīng)答失敗
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA設(shè)置為輸入
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;//時(shí)鐘輸出0
return 1;
}
//產(chǎn)生ACK應(yīng)答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不產(chǎn)生ACK應(yīng)答
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發(fā)送一個(gè)字節(jié)
//返回從機(jī)有無(wú)應(yīng)答
//1,有應(yīng)答
//0,無(wú)應(yīng)答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低時(shí)鐘開(kāi)始數(shù)據(jù)傳輸
for(t=0;t<8;t++)
{
IIC_SDA=(txd&0x80)>>7;
txd<<=1;
delay_us(2); //對(duì)TEA5767這三個(gè)延時(shí)都是必須的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//讀1個(gè)字節(jié),ack=1時(shí),發(fā)送ACK,ack=0,發(fā)送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA設(shè)置為輸入
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();//發(fā)送nACK,表示停止接收
else
IIC_Ack(); //發(fā)送ACK,表示繼續(xù)接收
return receive;
}
temhum.h
#ifndef __TEMHUM_H
#define __TEMHUM_H
/*******************
*
* @file temhum.h
* @author LYJ
* @version V1.0
* @attention
* 用于A(yíng)HT20溫濕度傳感器通信的相關(guān)函數(shù)
*
********************/
#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的狀態(tài)寄存器
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發(fā)送AC命令
void AHT20_SendAC(void)
{
IIC_Start();
IIC_Send_Byte(0x70); //啟動(dòng)傳輸后發(fā)送的01110000 (最后1bit表示讀/寫(xiě) 0--寫(xiě),1--讀)
IIC_Wait_Ack();
IIC_Send_Byte(0xac);//0xAC采集命令 命令參數(shù)有兩個(gè)字節(jié),第一個(gè)字節(jié)為 0x33,第二個(gè)字節(jié)為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進(jìn)入NOR工作模式
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Stop();
delay_ms(10);//延時(shí)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);//相關(guān)寄存器bit[3]置1,為校準(zhǔn)輸出
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Stop();
delay_ms(10);//延時(shí)10ms左右
}
void temphum_init()
{
delay_ms(40);//剛上電,延時(shí)40ms才可以讀取狀態(tài)
//首先發(fā)0x71讀取狀態(tài)字bit[3],如果=1,為校準(zhǔn)輸出,無(wú)須初始化!!!正常情況下讀回來(lái)的狀態(tài)是0x1C或者是0x18,讀回來(lái)是0x80表示忙狀態(tài);
if(!((AHT20_Read_Status()&0x08)==0x08))
{
AHT20_Init(); //初始化AHT20
}
}
//沒(méi)有CRC校驗(yàn),直接讀取AHT20的溫度和濕度數(shù)據(jù)
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發(fā)送AC命令
delay_ms(80); //大約延時(shí)80ms
while(((AHT20_Read_Status()&0x80)==0x80))//直到狀態(tài)bit[7]為0,表示為空閑狀態(tài),若為1,表示忙狀態(tài)
{
delay_ms(1);
if(cnt++>=100) break;
}
IIC_Start();
IIC_Send_Byte(0x71);
flag=IIC_Wait_Ack();
Byte_1th = IIC_Read_Byte(flag);//狀態(tài)字
Byte_2th = IIC_Read_Byte(flag);//濕度,發(fā)送ACK(繼續(xù)發(fā)送)
Byte_3th = IIC_Read_Byte(flag);//濕度
Byte_4th = IIC_Read_Byte(flag);//濕度/溫度
Byte_5th = IIC_Read_Byte(flag);//溫度
Byte_6th = IIC_Read_Byte(!flag);//溫度,發(fā)送NACK(停止發(fā)送)
IIC_Stop();
//保存得到的數(shù)據(jù)到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結(jié)合溫濕度模塊AHT10的參考代碼https://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
聯(lián)系方式 微信號(hào):13648103287