目录
一、关于AHT21
AHT21B数字温湿度模块是一款经过校准数字信号输出的温湿度复合传感器。它以专用的数字模块采集技术和温湿度传感技术,确保产品具有非常高的可靠性与卓越的长期稳定性。该产品具有品质卓越、响应迅速、抗干扰能力强、性价比高等优点。每个传感器都在专业的湿度校验室中进行校准,使产品达到更高的精度标准。标准I²C接口,使系统集成变得简易快捷。产品体积小、功耗低使其成为各类应用甚至最为苛刻的应用场合的最佳选择。
二、关于ABH20的工作流程
1.AHT20的工作流程
从AHT20的产品手册中,我们可以了解到AHT20的工作流程
从上图,我们可以将其总结成以下几个步骤
通电——>初始化(若状态字不为1)——>发送测量命令——>判断状态字为0——>读取测量数据——>计算温湿度——>将得到的数据进行转换——>利用串口输出数据到PC机
下面我将根据此步骤来对本次实验的重点代码进行分析
2.代码分析
此次实验使用的代码是正点原子关于串口通信的库函数模板和在AHT20官网下载的模板代码为基础所进行修改后的代码。
(1)主函数
int main(void)
{
uint32_t CT_data[2]={0};
volatile int c1,t1;
delay_init(); //初始化延时函数
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化115200
delay_ms(40); //上电后,延时40ms开始读取状态
AHT20_Init(); //初始化AHT20
while(1)
{
AHT20_Read_CTdata(CT_data); //不经过CRC校验,直接读取AHT20的温度和湿度数据
c1 = CT_data[0]*100*10/1024/1024/10; //计算得到的湿度值
t1 = (CT_data[1]*200*10/1024/1024-500)/10; //计算得到的温度值
printf("湿度:%d%%\r\n",c1);
printf("温度:%d℃\r\n\n",t1);
delay_ms(5000);
}
}
在主函数中,我们所要做的是将AHT20进行初始化,并调用AHT20_Read_CTdata函数开始启动芯片进行测量,最后将得到的数据进行转化后输出。
(2)读取、测量函数
void AHT20_Read_CTdata(u32 *ct)
{
volatile uint8_t Byte_1th=0;
volatile uint8_t Byte_2th=0;
volatile uint8_t Byte_3th=0;
volatile uint8_t Byte_4th=0;
volatile uint8_t Byte_5th=0;
volatile uint8_t Byte_6th=0;
uint32_t RetuData = 0;
uint16_t cnt = 0;
uint16_t flag;
AHT20_SendAC(); //发送测量命令
delay_ms(80); //等待80ms待测量完成
//如果读取状态字Bit[7]为0,表示测量完成,然后可以连续读取六个字节;否则继续等待。
while(((AHT20_Read_Status()&0x80)==0x80))
{
delay_ms(1);
if(cnt++>=100) break;
}
IIC_Start(); //开启IIC通信
AHT20_WR_Byte(0x71); //读取命令
flag=IIC_Wait_Ack();
Byte_1th = AHT20_RD_Byte(flag); //状态字
Byte_2th = AHT20_RD_Byte(flag); //湿度
Byte_3th = AHT20_RD_Byte(flag); //湿度
Byte_4th = AHT20_RD_Byte(flag); //湿度和温度
Byte_5th = AHT20_RD_Byte(flag); //温度
Byte_6th = AHT20_RD_Byte(!flag); //温度
IIC_Stop();
//处理数据
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; //温度
}
此函数在向AHT20发送测量命令后,通过状态字判断后,开启IIC通信,这一步使用AHT20_WR_Byte函数写入的0x71为IIC的地址和读取的命令
接着用6个Byte来存放从芯片中读取的数据,然后停止IIC通信,最后就是将得到的数据进行处理。
(3)测量命令
void AHT20_SendAC(void)
{
IIC_Start();
AHT20_WR_Byte(0x70);
Receive_ACK();
AHT20_WR_Byte(0xAC); //采集命令
Receive_ACK();
AHT20_WR_Byte(0x33);
Receive_ACK();
AHT20_WR_Byte(0x00);
Receive_ACK();
IIC_Stop();
}
在AHT20工作中,我们需要向其发送一个测量命令才能让芯片开始采集温湿度,并且在每发送一个字节段后还需要从机接收一个ACK应答
由上图可知,我们一共需要发送4个字节段,分别为0x70(pc机的地址和写入)、0xAC(触发测量的命令)、0x33(0xAC的参数1)、0x00(0xAC的参数2)
(4)IIC的启动和停止
void IIC_Start(void)
{
SDA_OUT(); //将SDA设置为输出
IIC_SDA=1;
IIC_SCL=1; //拉高SDA和SCL的电平
IIC_SDA=0;
delay_us(4);
IIC_SCL=0; //拉低SDA的电平后,延时4us后拉低SCL的电平,启动IIC传输
}
void IIC_Stop(void)
{
SDA_OUT();
IIC_SCL=0;
IIC_SDA=0;
IIC_SCL=1;
IIC_SDA=1;
delay_us(4);
}
从图中我们可以看出IIC启动和停止传输状态的条件
且电平宽度为4us左右。
(5)向AHT20写入数据
void AHT20_WR_Byte(uint8_t Byte)
{
uint8_t Data,N;
Data=Byte;
SDA_OUT();
IIC_SCL=0;
for(N=0;N<8;N++)
{
IIC_SDA=(Data&0x80)>>7;
Data<<=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
(6)从AHT20读取数据
uint8_t AHT20_RD_Byte(unsigned char ack)
{
uint8_t Byte,i;
Byte = 0;
SDA_IN();
for(i=0;i<8;i++)
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
if(READ_SDA)Byte++;
delay_us(1);
}
if (!ack)
Send_NOT_ACK();
else
Send_ACK();
return Byte;
}
3.输出结果
将编译好后生成的hex文件烧录进芯片后,打开串口调试,可以发现温度可以正常读出了
常温:
升温:
参考资料
AHT21B温湿度传感器
《AHT20产品手册a2》