FPGA驱动设计:AHT10温湿度传感器详解

半导体产业 47 次阅读

概念

传感器输出经过标定的数字信号输出,通过标准的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通信通过设备地址与从机进行通信,

d6b9bb7e-500c-11f0-b715-92fbcf53809c.jpg

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

d6c8cfd8-500c-11f0-b715-92fbcf53809c.jpg

获取到校准使能位后,查看其是否已校准,若已校准则跳过当前步骤;若未校准则发送8‘hE1,进行初始化,然后发送8’h08,8‘h00;

接着开始触发测量,测量先发送8’hAC,然后发送8‘h33,8'h00;

测量命令发送完成后,需要等待80ms,用于温湿度的测量;之后再发送命令8‘h71,以读取状态寄存器是否处于空闲状态(bit7 => idle);若是空闲状态,可以直接读取之后六个字节的温湿度数值;

读取温湿度数据构成

d6d63498-500c-11f0-b715-92fbcf53809c.png

相对湿度和温度转换公式

将接收到的湿度值转换成%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中,当缓存了一组完整的温度值数据后进行输出,发送给上位机,或是直接通过数码管显示;

d6e2c4ba-500c-11f0-b715-92fbcf53809c.jpg

I2C模块

d6ed0f4c-500c-11f0-b715-92fbcf53809c.jpg

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设计论坛】欢迎添加关注!文章转载请注明出处。

评论区

登录后即可参与讨论

立即登录