FPGA驱动设计:AHT10温湿度传感器详解
概念
传感器输出经过标定的数字信号输出,通过标准的I2C接口传输数据;
相对湿度的分辨率在0.024%RH,工作范围为0~100%RH;
温度值的分辨率在0.01℃,工作范围为-40~85℃;
AHT10的供电范围为1.8~3.6V,推荐使用3.3V供电;
接口包含了完全静态逻辑,因而不存在最小串行时钟SCL频率;
IIC协议,同步半双工通信协议
起始位:主机在时钟高电平期间拉低总线;
数据位:主机在时钟低电平期间发送数据,主机在高电平期间保持不变;从机在时钟高电平期间采样数据;
应答为:主机收到数据后发送应答,从机才会发送下一字节数据;
停止位:主机在时钟高电平期间释放总线,主机在低电平期间保持不变;
可使用的I2C通信模式有经典型和高速模式,经典模式最小时钟周期是250us,高速模式最小时钟周期是100us;
AHT10配置与通信
I2C通信通过设备地址与从机进行通信,

首先上电启动传感器,启动后需要先等待40ms(设备才开始正常工作),然后发送8‘h71 来获取状态字节,状态寄存器说明如下:

获取到校准使能位后,查看其是否已校准,若已校准则跳过当前步骤;若未校准则发送8‘hE1,进行初始化,然后发送8’h08,8‘h00;
接着开始触发测量,测量先发送8’hAC,然后发送8‘h33,8'h00;
测量命令发送完成后,需要等待80ms,用于温湿度的测量;之后再发送命令8‘h71,以读取状态寄存器是否处于空闲状态(bit7 => idle);若是空闲状态,可以直接读取之后六个字节的温湿度数值;
读取温湿度数据构成

相对湿度和温度转换公式
将接收到的湿度值转换成%RH的格式:
R H [ % ] = ( S R H / 2 20 ) RH [%] = (SRH/2^{20}) RH[%]=(SRH/220)
温度转换成℃表示:
T ( ℃ ) = ( S T / 2 20 ) . T(℃) = (ST/2^{20}). T(℃)=(ST/220).
设计框架
整个模块的设计,首先是上位机通过UART,发送命令打开AHT10驱动控制模块、数码管显示模块以及串口模块;设备驱动用控制模块实现,通信接口使用I2C与AHT10进行通信,然后将读取的温湿度值先进行数值转换并取整,并转换成ASCII码方便查看温湿度值;然后将数据缓存到FIFO中,当缓存了一组完整的温度值数据后进行输出,发送给上位机,或是直接通过数码管显示;

I2C模块

I2C接口模块状态机如上图所示,从空闲状态可以先发送起始位再读写一个字节数据,或直接读写一个字节数据,然后是收发应答位;最后发送停止位,就完成了一组数据的读写;
对于I2C通信,数据的传输速率选择的是50M/250 Bps;
include"param.v"modulei2c_master( input clk , input rst_n , input req , input [3:0] cmd , input [7:0] din , output [7:0] dout , output done , output slave_ack , output i2c_scl , input i2c_sda_i , output i2c_sda_o , output i2c_sda_oe );//状态机参数定义localparam IDLE =7'b000_0001, START =7'b000_0010, WRITE =7'b000_0100, RACK =7'b000_1000, READ =7'b001_0000, SACK =7'b010_0000, STOP =7'b100_0000;//reg [6:0] state_c ; reg [6:0] state_n ; reg [8:0] cnt_scl ;//产生i2c时钟wire add_cnt_scl ; wire end_cnt_scl ; reg [3:0] cnt_bit ;//传输数据 bit计数器wire add_cnt_bit ; wire end_cnt_bit ; reg [3:0] bit_num ; reg scl ;//输出寄存器reg sda_out ; reg sda_out_en ; reg [7:0] rx_data ; reg rx_ack ; reg [3:0] command ; reg [7:0] tx_data ;//发送数据wire idle2start ; wire idle2write ; wire idle2read ; wire start2write ; wire start2read ; wire write2rack ; wire read2sack ; wire rack2stop ; wire sack2stop ; wire rack2idle ; wire sack2idle ; wire stop2idle ; //状态机always@(posedgeclkornegedgerst_n)beginif(rst_n==0)begin state_c`include"param.v"moduleaht_ctrl ( input sys_clk , input rst_n ,inputdriver_en, output req , output [3:0] cmd , output [7:0] data , input done , input [7:0] rd_data , output[19:0]hum_data, output [19:0]temp_data, output dout_vld );//localparam START = 7'b000_0001, INIT = 7'b000_0010, CHECK_INIT =7'b000_0100, IDLE = 7'b000_1000, TRIGGER = 7'b001_0000, WAIT = 7'b010_0000, READ = 7'b100_0000; parameterDELAY_40MS =200_0000 , DELAY_80MS =400_0000 , DELAY_500MS =2500_0000; reg [7:0] state_c ; reg [7:0] state_n ; reg [2:0] cnt_byte ; wire add_cnt_byte ; wire end_cnt_byte ; reg tx_req ; reg [3:0] tx_cmd ; reg [7:0] tx_data ; reg[47:0]read_data; reg[27:0]cnt; wireadd_cnt; wireend_cnt; reg[24:0]delay; regfinish_init; wirestart2init; wireinit2check; wirecheck2idle; wirecheck2init; wireidle2trigger; wiretrigger2wait; wirewait2read; wireread2idle;regdriver_en_r1;regdriver_en_r2;wirene_driver;// ne_driveralways@(posedgesys_clkornegedgerst_n)beginif(!rst_n)begindriver_en_r1 0&& done)begin read_data其它模块
然后将温湿度数值按照上述格式转换:
temp_data_r>12) - (500)); hum_data_r>12);再将数据转换成ASCII码:
always@(posedge sys_clk or negedge rst_n)begin case(cnt) 1: dout_r最后将数值通过FIFO缓存完整的22字节数据后输出即可;
同时还可以将数据转换成bcd码显示到数码管上;
原文标题:基于FPGA的AHT10(温湿度传感器)驱动设计
文章出处:【微信号:gh_9d70b445f494,微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。



