当前位置:网站首页>御神楽的学习记录之基于FPGA的AHT10温湿度数据采集
御神楽的学习记录之基于FPGA的AHT10温湿度数据采集
2022-08-04 16:49:00 【YuKaguraNe】
一、AHT10手册解析
1.1 AHT10通信协议
基于标准的I2C协议
串行时钟SCL
SCL用于微处理器与AHT10之间的通讯同步。由于接口包含了完全静态逻辑,因而不存在最小SCL频率。
串行数据SDA
SDA引脚用于传感器的数据输入和输出。当向传感器发送命令时,SDA在串行时钟(SCL)的上升沿有效,且当SCL为高电平时,SDA必须保持稳定。在SCL下降沿之后,SDA值可以被改变。
1.2 传感器启动
启动传感器
将传感器上电后,电压为所选择的VDD电源电压。需要注意的是,上电后传感器需要最多20毫秒时间(此时SCL为高电平)以达到空闲状态,即做好准备接收由主机(MCU)发送的命令。
启动/停止时序
每个传输序列都是以Start状态作为开始以Stop状态结束,如下图
Start状态
当SCL为高电平时,SDA由高电平转换为低电平。开始状态是由主机控制的一种特殊的总线状态,指示从机传输开始。
Stop状态
当SCL高电平时,SDA线上从低电平转换为高电平。停止状态是由主机控制的一种特殊的总线状态,指示从机传输结束。
1.3 发送命令
在启动传输后,随后传输I2C首字节包括7位的I2C设备地址0x38和一个SDA方向位x(读R:‘1’,写W:‘0’)。在第8个SCL时钟下降沿之后,通过拉低SDA引脚(ACK位),指示传感器数据接收正常。在发出初始化命令之后,主机MCU必须等待测量完成。
基本命令集
状态位说明
1.4 传感器读取流程
1.上电后要等待40ms,读取温湿度值之前,首先要看状态字的校准使能位Bit[3]是否位1(通过发送0x71可以获取一个字节的状态字),如果不为1,要发送0xE1命令(初始化),此命令参数有两个字节,第一个字节为0x08,第二个字节为0x00。
2.直接发送0xAC命令(触发测量),此命令参数有两个字节,第一个字节为0x33,第二个字节为0x00。
触发测量数据:
3.等待80ms待测量完成,忙状态Bit[7]为0,然后可以读取六个字节(发送0x71即可以读取)
读取温湿度数据:
1.5数据转换
相对湿度转换
相对湿度计算公式:
R H = ( S R H 2 20 ) ∗ 100 RH=(\frac{S_{RH}}{2^{20}})*100% RH=(220SRH)∗100
温度转换
温度转换公式:
T ( ℃ ) = ( S T 2 20 ) ∗ 200 − 50 T(℃)=(\frac{S_{T}}{2^{20}})*200-50 T(℃)=(220ST)∗200−50
二、项目架构
2.1 项目整体架构
项目总共分为4个小型模块
I2C主机接口模块
实现I2C协议,负责将对传感器的读写操作使用I2C协议发送给AHT10传感器
AHT10配置模块
负责传感器的配置、初始化、发测量使能等,以及将I2C接口模块的数据移位寄存送到串口发送控制模块
串口发送控制模块
负责将AHT配置模块的数据处理并控制串口发送的数据的方式
串口发送模块
标准的串口发送模块,负责发送数据
三、时序设计
传感器配置模块状态机
四、模块解析
4.1 传感器配置模块
发送读写命令
always @(*) begin
if (state_c == INIT) begin
case (cnt_byte)
0 : TX(1'b1,{
`CMD_START|`CMD_WRITE},{
`I2C_ADR,`WR_BIT});//发起始位、设备地址、写控制位
1 : TX(1'b1,`CMD_WRITE,{
`AHT_INIT});//发初始化指令
2 : TX(1'b1,`CMD_WRITE,8'b0000_1000);//初始化指令数据
3 : TX(1'b1,{`CMD_WRITE|`CMD_STOP},8'b0000_0000);
default : TX(1'b1,`CMD_WRITE,8'b0000_0000);
endcase
end
else if (state_c == MEASURE) begin
case (cnt_byte)
0 : TX(1'b1,{
`CMD_START|`CMD_WRITE},{
`I2C_ADR,`WR_BIT});//发起始位、设备地址、写控制位
1 : TX(1'b1,`CMD_WRITE,{
`AHT_MEASURE});//发触发测量指令
2 : TX(1'b1,`CMD_WRITE,8'b0011_0011);//触发测量指令数据
3 : TX(1'b1,{`CMD_WRITE|`CMD_STOP},8'b0000_0000);
default : TX(1'b1,`CMD_WRITE,8'b0000_0000);
endcase
end
else if (state_c == READ) begin
case (cnt_byte)
0 : TX(1'b1,{
`CMD_START|`CMD_WRITE},{
`I2C_ADR,`RD_BIT});//发起始位、设备地址、读控制位
READ_BYTE-1 : TX(1'b1,{
`CMD_READ|`CMD_STOP},0);//最后一个字节读数据和发停止位
default : TX(1'b1,{
`CMD_READ},0);//读数据
endcase
end
else begin
TX(1'b0,tx_cmd,tx_data);
end
end
通过在不同的状态,如在发测量指令和初始化状态,复用计数器,发送对应字节的数据给I2C接口模块
计数器复用
//cnt_byte
always @(posedge clk or negedge rst_n) begin
if (rst_n==0) begin
cnt_byte <= 0;
end
else if(add_cnt_byte) begin
if(end_cnt_byte)
cnt_byte <= 0;
else
cnt_byte <= cnt_byte+1 ;
end
end
assign add_cnt_byte = (state_c==MEASURE | state_c==READ|state_c==INIT)&done;
assign end_cnt_byte = add_cnt_byte && cnt_byte == ((state_c==MEASURE|state_c==INIT)?
(WRITE_BYTE-1):(READ_BYTE-1));
//cnt_ms
always @(posedge clk or negedge rst_n) begin
if (rst_n==0) begin
cnt_ms <= 0;
end
else if(add_cnt_ms) begin
if(end_cnt_ms)
cnt_ms <= 0;
else
cnt_ms <= cnt_ms+1 ;
end
end
assign add_cnt_ms = (state_c== WAIT_40 | state_c == WAIT_80);
assign end_cnt_ms = add_cnt_ms && cnt_ms == ((state_c==WAIT_40)?
(TIME_40MS-1):(TIME_80MS-1));
根据不同的状态实现计数器的结束条件不同,达到复用目的。
4.2 数据处理
使用手册提供的公式计算即可
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
humi_data <= 20'b0;
temp_data <= 20'b0;
end
else if (din_vld) begin
humi_data <= (data_r[39:20]*100>>20);
temp_data <= (data_r[19:0]*200>>20)-50;
end
else begin
humi_data <= humi_data;
temp_data <= temp_data;
end
end
串口发送数据
由于串口发送模块只能接收一字节的数据,过采用计数器计数字节数,分字节发送。
//字节计数器
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt_byte <= 1'b0;
end
else if (end_cnt_byte) begin
cnt_byte <= 1'b0;
end
else if (add_cnt_byte) begin
cnt_byte <= cnt_byte + 1'b1;
end
else begin
cnt_byte <= cnt_byte;
end
end
assign add_cnt_byte = flag;//开始条件
assign end_cnt_byte = add_cnt_byte && cnt_byte == BYTE_MAX -1;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
data_tx_fifo <= 0;
end
else if (flag) begin
case (cnt_byte)
0: data_tx_fifo <= 8'hce;
1: data_tx_fifo <= 8'hc2;//温
2: data_tx_fifo <= 8'hb6;
3: data_tx_fifo <= 8'hc8;//度
4: data_tx_fifo <= 8'h3a;//:
5: data_tx_fifo <= (temp_data /10 %10)+48;
6: data_tx_fifo <= (temp_data %10)+48;
7: data_tx_fifo <= 8'ha1;
8: data_tx_fifo <= 8'he6;//℃
9: data_tx_fifo <= 8'hca;
10: data_tx_fifo <= 8'haa;//湿
11: data_tx_fifo <= 8'hb6;
12: data_tx_fifo <= 8'hc8;//度
13: data_tx_fifo <= 8'h3a;//:
14: data_tx_fifo <= (humi_data /10%10)+48;
15: data_tx_fifo <= (humi_data %10)+48;
16: data_tx_fifo <= 8'h25;//%
default:data_tx_fifo <= 8'h0 ;
endcase
end
end
数据发送缓存FIFO
assign rdreq = busy&&~empty;
assign wrreq = ~full && flag_r;
fifo fifo_inst (
.clock ( clk ),
.data ( data_tx_fifo ),
.rdreq ( rdreq ),
.wrreq ( wrreq ),
.empty ( empty ),
.full ( full ),
.q ( data_tx),
.usedw ( usedw_sig )
);
将处理好的每个字节数据存入FIFO,通过串口的发送完成信号来控制读取FIFO数据到串口发送模块中去
五、模块测试
项目整体仿真
传感器初始化
发送测量命令
发送读命令
SignalTap
串口发送数据控制波形
读状态I2C协议波形及数据
串口发送效果
边栏推荐
猜你喜欢
九联_UNT400G_S905L2_(联通)_线刷固件包
Hubei Mobile HG680-LV_S905L3B_wire brush firmware package
乐享购(分享购)的模式:优势、亮点、收益
转型阵痛期,好未来减亏容易增收难?
安装win11提示开启安全模式如何解决
Mobile Hisense IP102H_905L3-B_wire brush firmware package
WEB 渗透之SSTI 模板注入
花 30 美金请 AI 画家弄了个 logo,网友:画得非常好,下次别画了!
动手学深度学习_AlexNet
Minecraft HMCL 使用认证服务器LittleSkin进行登录
随机推荐
redis
华硕win11安全启动如何开启
测试零基础如何进入大厂?一场面试教会你(附面试题解析)
HCIP笔记(6)
Minecraft HMCL 使用认证服务器LittleSkin进行登录
湖北移动HG680-LV_S905L3B_线刷固件包
SAP ABAP SteammPunk 蒸汽朋克的最新进展 - 嵌入式蒸汽朋克
贝叶斯优化核极限学习机KELM用于回归预测
Mobile Hisense IP102H_905L3-B_wire brush firmware package
生产环境重大bug,update加上索引字段会走索引进行更新?还是走全表扫描
移动百事通BesTV_R3300-L_S905L_8189_线刷固件包
Win10 无线网卡驱动感叹号,显示错误代码56
nyist 301 递推求值(矩阵快速幂)
花 30 美金请 AI 画家弄了个 logo,网友:画得非常好,下次别画了!
码蹄集 - MT2142 - 万民堂大厨
Hubei Mobile ZTE B860AV2.1_S905L_ flash firmware package
"Distributed cloud best practices" BBS, on August 11, shenzhen
在VMD上可视化hdf5格式的分子轨迹文件
codeforces:808D. Array Division【二分 + 找规律】
工龄10年的测试员从大厂“裸辞”后...