在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于FPGA的AHT10溫濕度傳感器驅動設計

FPGA設計論壇 ? 來源:FPGA設計論壇 ? 2025-06-27 10:12 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

概念

傳感器輸出經過標定的數字信號輸出,通過標準的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 <= IDLE ; ? ? ? ?endelsebegin? ? ? ? ? ? ?state_c <= state_n; ? ? ??endendalways?@(*)?begincase(state_c) ? ? ? ? ? ? ? IDLE :beginif(idle2start) ? ? ? ? ? ? ? ? ? ? state_n = START ; ? ? ? ? ? ? ? ?elseif(idle2write) ? ? ? ? ? ? ? ? ? ? state_n = WRITE ; ? ? ? ? ? ? ? ?elseif(idle2read) ? ? ? ? ? ? ? ? ? ? state_n = READ ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?START :beginif(start2write) ? ? ? ? ? ? ? ? ? ? state_n = WRITE ; ? ? ? ? ? ? ? ?elseif(start2read) ? ? ? ? ? ? ? ? ? ? state_n = READ ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?WRITE :beginif(write2rack) ? ? ? ? ? ? ? ? ? ? state_n = RACK ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?RACK :beginif(rack2stop) ? ? ? ? ? ? ? ? ? ? state_n = STOP ; ? ? ? ? ? ? ? ?elseif(rack2idle) ? ? ? ? ? ? ? ? ? ? state_n = IDLE ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?READ :beginif(read2sack) ? ? ? ? ? ? ? ? ? ? state_n = SACK ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?SACK :beginif(sack2stop) ? ? ? ? ? ? ? ? ? ? state_n = STOP ; ? ? ? ? ? ? ? ?elseif(sack2idle) ? ? ? ? ? ? ? ? ? ? state_n = IDLE ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?STOP :beginif(stop2idle) ? ? ? ? ? ? ? ? ? ? state_n = IDLE ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?enddefault?: state_n = IDLE ; ? ? ? ?endcaseendassign?idle2start ?= state_c==IDLE ?&& (req && (cmd&`CMD_START)); ? ?assign?idle2write ?= state_c==IDLE ?&& (req && (cmd&`CMD_WRITE)); ? ?assign?idle2read ? = state_c==IDLE ?&& (req && (cmd&`CMD_READ )); ? ?assign?start2write = state_c==START && (end_cnt_bit && (command&`CMD_WRITE)); ? ?assign?start2read ?= state_c==START && (end_cnt_bit && (command&`CMD_READ )); ? ?assign?write2rack ?= state_c==WRITE && (end_cnt_bit); ? ?assign?read2sack ? = state_c==READ ?&& (end_cnt_bit); ? ?assign?rack2stop ? = state_c==RACK ?&& (end_cnt_bit && (command&`CMD_STOP )); ? ?assign?sack2stop ? = state_c==SACK ?&& (end_cnt_bit && (command&`CMD_STOP )); ? ?assign?rack2idle ? = state_c==RACK ?&& (end_cnt_bit && (command&`CMD_STOP ) ==?0); ? ?assign?sack2idle ? = state_c==SACK ?&& (end_cnt_bit && (command&`CMD_STOP ) ==?0); ? ?assign?stop2idle ? = state_c==STOP ?&& (end_cnt_bit); ? ??//計數器always?@(posedge?clk?ornegedge?rst_n)?beginif?(rst_n==0)?begin? ? ? ? ? ? ?cnt_scl <=?0; ? ? ? ? ?endelseif(add_cnt_scl)?beginif(end_cnt_scl) ? ? ? ? ? ? ? ? cnt_scl <=?0; ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ?cnt_scl <= cnt_scl+1?; ? ? ??endendassign?add_cnt_scl = (state_c != IDLE); ? ?assign?end_cnt_scl = add_cnt_scl ?&& cnt_scl == (`SCL_PERIOD)-1?; ? ?always?@(posedge?clk?ornegedge?rst_n)?beginif?(rst_n==0)?begin? ? ? ? ? ? ?cnt_bit <=?0; ? ? ? ? ?endelseif(add_cnt_bit)?beginif(end_cnt_bit) ? ? ? ? ? ? ? ? cnt_bit <=?0; ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ?cnt_bit <= cnt_bit+1?; ? ? ??endendassign?add_cnt_bit = (end_cnt_scl); ? ?assign?end_cnt_bit = add_cnt_bit ?&& cnt_bit == (bit_num)-1?; ? ?always? @(*)beginif(state_c == WRITE | state_c == READ)?begin? ? ? ? ? ? ?bit_num =?8; ? ? ? ?endelsebegin? ? ? ? ? ? ? bit_num =?1; ? ? ? ?endend//commandalways? @(posedge?clk?ornegedge?rst_n)beginif(~rst_n)begin? ? ? ? ? ? ?command <=?0; ? ? ? ?endelseif(req)begin? ? ? ? ? ? ?command <= cmd; ? ? ? ?endend//tx_dataalways? @(posedge?clk?ornegedge?rst_n)beginif(~rst_n)begin? ? ? ? ? ? ?tx_data <=?0; ? ? ? ?endelseif(req)begin? ? ? ? ? ? ?tx_data <= din; ? ? ? ?endend//sclalways? @(posedge?clk?ornegedge?rst_n)beginif(~rst_n)begin? ? ? ? ? ? ?scl <=?1'b1; ? ? ? ?endelseif(idle2start | idle2write | idle2read)begin//開始發送時,拉低? ? ? ? ? ? ?scl <=?1'b0; ? ? ? ?endelseif(add_cnt_scl && cnt_scl == `SCL_HALF-1)begin? ? ? ? ? ? ? scl <=?1'b1; ? ? ? ?endelseif(end_cnt_scl && ~stop2idle)begin? ? ? ? ? ? ? scl <=?1'b0; ? ? ? ?endend//sda_outalways? @(posedge?clk?ornegedge?rst_n)beginif(~rst_n)begin? ? ? ? ? ? ?sda_out <=?1'b1; ? ? ? ?endelseif(state_c == START)begin//發起始位if(cnt_scl == `LOW_HLAF)begin//時鐘低電平時拉高sda總線? ? ? ? ? ? ? ? ?sda_out <=?1'b1; ? ? ? ? ? ?endelseif(cnt_scl == `HIGH_HALF)begin//時鐘高電平時拉低sda總線?? ? ? ? ? ? ? ? ?sda_out <=?1'b0; ? ? ? ? ? ? ? ?//保證從機能檢測到起始位endendelseif(state_c == WRITE && cnt_scl == `LOW_HLAF)begin//scl低電平時發送數據 ? 并串轉換? ? ? ? ? ? ?sda_out <= tx_data[7-cnt_bit]; ? ? ? ? ? ? ??endelseif(state_c == SACK && cnt_scl == `LOW_HLAF)begin//發應答位? ? ? ? ? ? ?sda_out <= (command&`CMD_STOP)?1'b1:1'b0; ? ? ? ?endelseif(state_c == STOP)begin//發停止位if(cnt_scl == `LOW_HLAF)begin//時鐘低電平時拉低sda總線? ? ? ? ? ? ? ? ?sda_out <=?1'b0; ? ? ? ? ? ?endelseif(cnt_scl == `HIGH_HALF)begin//時鐘高電平時拉高sda總線?? ? ? ? ? ? ? ? ?sda_out <=?1'b1; ? ? ? ? ? ? ? ?//保證從機能檢測到停止位endendend//sda_out_en ?總線輸出數據使能always? @(posedge?clk?ornegedge?rst_n)beginif(~rst_n)begin? ? ? ? ? ? ?sda_out_en <=?1'b0; ? ? ? ?endelseif(idle2start | idle2write | read2sack | rack2stop)begin? ? ? ? ? ? ?sda_out_en <=?1'b1; ? ? ? ?endelseif(idle2read | start2read | write2rack | stop2idle)begin? ? ? ? ? ? ? sda_out_en <=?1'b0; ? ? ? ?endend//rx_data ? ? ? 接收讀入的數據always? @(posedge?clk?ornegedge?rst_n)beginif(~rst_n)begin? ? ? ? ? ? ?rx_data <=?0; ? ? ? ?endelseif(state_c == READ && cnt_scl == `HIGH_HALF)begin? ? ? ? ? ? ?rx_data[7-cnt_bit] <= i2c_sda_i; ? ?//串并轉換endend//rx_ackalways? @(posedge?clk?ornegedge?rst_n)beginif(~rst_n)begin? ? ? ? ? ? ?rx_ack <=?1'b1; ? ? ? ?endelseif(state_c == RACK && cnt_scl == `HIGH_HALF)begin? ? ? ? ? ? ?rx_ack <= i2c_sda_i; ? ? ? ?endend//輸出信號assign?i2c_scl ? ?= scl ? ? ? ? ; ? ?assign?i2c_sda_o ?= sda_out ? ? ; ? ?assign?i2c_sda_oe = sda_out_en ?; ? ?assign?dout = rx_data; ? ?assign?done = rack2idle | sack2idle | stop2idle; ? ?assign?slave_ack = rx_ack;endmodule

`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?; ?driver_en_r2 ?<=?0?; ?endelsebegin?driver_en_r1 ?<= driver_en ; driver_en_r2 ?<= driver_en_r1 ;endendassign?ne_driver = (~driver_en_r1 && driver_en_r2) ;//statealways?@(posedge?sys_clk?ornegedge?rst_n)?beginif?(rst_n==0)?begin? ? ? ? ? ? ?state_c <= START ; ? ? ? ?endelsebegin? ? ? ? ? ? ?state_c <= state_n; ? ? ??endend//狀態轉移always?@(*)?begincase(state_c) ? ? ? ? ? ? ? START :beginif(ne_driver)?begin?state_n = state_c ; ?endelseif(start2init)?begin? ? ? ? ? ? ? ? ? ? ?state_n = INIT ;endelsebegin? ? ? ? ? ? ? ? ? ? ? state_n = state_c ;endend? ? ? ? ? ? ?INIT :beginif(ne_driver)?begin?state_n = START ;endelseif(init2check)begin? ? ? ? ? ? ? ? ? ? ?state_n = IDLE ;endelse? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?CHECK_INIT :beginif(ne_driver)?begin?state_n = START ;endelseif(check2idle)begin? ? ? ? ? ? ? ? ? ? ?state_n = IDLE ;endelseif(check2init)?begin? ? ? ? ? ? ? ? ? ? ?state_n = INIT; ? ? ? ? ? ? ? ?endelse? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?IDLE :beginif(ne_driver)begin?state_n = START ;endelseif(idle2trigger)begin? ? ? ? ? ? ? ? ? ? ?state_n = TRIGGER ;endelse? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?TRIGGER :beginif(ne_driver)begin?state_n = START ;endelseif(trigger2wait)begin? ? ? ? ? ? ? ? ? ? ?state_n = WAIT ;endelse? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?WAIT :beginif(ne_driver)begin?state_n = START ;endelseif(wait2read) ? ? ? ? ? ? ? ? ? ? state_n = READ ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?end? ? ? ? ? ? ?READ :beginif(ne_driver)begin?state_n = START ;endelseif(read2idle) ? ? ? ? ? ? ? ? ? ? state_n = IDLE ; ? ? ? ? ? ? ? ?else? ? ? ? ? ? ? ? ? ? ? state_n = state_c ; ? ? ? ? ? ?enddefault?: state_n = START ; ? ? ? ?endcaseendassign?start2init = state_c == START && (end_cnt); ? ?assign?init2check = state_c == INIT && (end_cnt_byte); ? ?assign?check2idle = state_c == CHECK_INIT && (finish_init) && end_cnt_byte; ? ?assign?check2init = state_c == CHECK_INIT && (~finish_init)&& end_cnt_byte; ? ?assign?idle2trigger = state_c == IDLE && (end_cnt); ? ?assign?trigger2wait = state_c == TRIGGER && (end_cnt_byte); ? ?assign?wait2read = state_c == WAIT && (end_cnt); ? ?assign?read2idle = state_c == READ && (end_cnt_byte); ? ??// delayalways?@(posedge?sys_clk?ornegedge?rst_n)?beginif(!rst_n)?begin? ? ? ? ? ? ?delay <= DELAY_40MS; ? ? ? ?endelseif(state_c == START)?begin? ? ? ? ? ? ?delay <= DELAY_40MS; ? ? ? ?endelseif(state_c == WAIT)?begin? ? ? ? ? ? ?delay <= DELAY_80MS; ? ? ? ?endelseif(state_c == IDLE)?begin? ? ? ? ? ? ?delay <= DELAY_500MS; ? ? ? ?endend// cntalways?@(?posedge?sys_clk?ornegedge?rst_n )?beginif?( !rst_n )?begin? ? ? ? ? ? ?cnt <=?0; ? ? ? ?endelseif?( add_cnt )?beginif?( end_cnt )?begin? ? ? ? ? ? ? ? ?cnt <=?0; ? ? ? ? ? ?endelsebegin? ? ? ? ? ? ? ? ?cnt <= cnt +?1; ? ? ? ? ? ?endendelsebegin? ? ? ? ? ? ?cnt <=?0; ? ? ? ?endendassign?add_cnt = (state_c == START || state_c == WAIT || state_c == IDLE) && driver_en_r2; ? ?assign?end_cnt = cnt == delay -?1?&& add_cnt || ne_driver ;// cnt_bytealways?@(posedge?sys_clk?ornegedge?rst_n)?beginif(!rst_n)begin? ? ? ? ? ? ?cnt_byte <=?0; ? ? ? ?endelseif(add_cnt_byte)?beginif(end_cnt_byte)?begin? ? ? ? ? ? ? ? ?cnt_byte <=?0; ? ? ? ? ? ?endelse? ? ? ? ? ? ? ? ?cnt_byte <= cnt_byte +?1; ? ? ? ?endendassign?add_cnt_byte = (state_c == INIT || state_c == CHECK_INIT ||state_c == TRIGGER || state_c == READ) && done; ? ?assign?end_cnt_byte = (cnt_byte == (state_c == READ?6:3) && add_cnt_byte) || ne_driver ;//always? @(*)begincase?(state_c) ? ? ? ? ? ? INIT : ? ? ? ? ? ? ? ? ?case(cnt_byte) ? ? ? ? ? ? ? ? ? ?0? ? ? ? ? ?:TX(1'b1,{`CMD_START | `CMD_WRITE},{`I2C_ADR,1'b0}); ? ? ? ? ? ? ? ? ? ?1? ? ? ? ? ?:TX(1'b1, `CMD_WRITE ,`CMD_INIT); ? ? ? ? ? ? ? ? ? ? ??2? ? ? ? ? ?:TX(1'b1,`CMD_WRITE ,8'b000_1000); ? ? ? ? ? ? ? ? ? ? ?3? ? ? ? ? ?:TX(1'b1,{`CMD_WRITE | `CMD_STOP} ,8'b0000_0000); ? ? ? ? ? ? ? ? ? ? ?default? ? ?:TX(1'b0,tx_cmd,tx_data); ? ? ? ? ? ? ? ?endcase? ? ? ? ? ? ? CHECK_INIT: ? ? ? ? ? ? ? ?case(cnt_byte) ? ? ? ? ? ? ? ? ? ?0? ? ? ? ? ?:TX(1'b1,{`CMD_START | `CMD_WRITE},{`I2C_ADR,1'b0}); ? ? ? ? ? ? ? ? ? ?1? ? ? ? ? ?:TX(1'b1,`CMD_WRITE ,`CMD_CHECK); ? ? ? ? ? ? ? ? ? ? ??2? ? ? ? ? ?:TX(1'b1,{`CMD_START | `CMD_WRITE},{`I2C_ADR,1'b1}); ? ? ? ? ? ? ? ? ? ?3? ? ? ? ? ?:TX(1'b1,{`CMD_READ | `CMD_STOP},0); ? ? ? ? ? ? ? ? ? ? ??default? ? ?:TX(1'b0,tx_cmd,tx_data); ? ? ? ? ? ? ? ?endcase? ? ? ? ? ? ?TRIGGER: ? ? ? ? ? ? ? ? ?case(cnt_byte) ? ? ? ? ? ? ? ? ? ?0? ? ? ? ? ?:TX(1'b1,{`CMD_START | `CMD_WRITE},{`I2C_ADR,1'b0});//1? ? ? ? ? ?:TX(1'b1,`CMD_WRITE ,`CMD_TRIGGER); ? ? ? ? ? ? ? ? ? ? ?2? ? ? ? ? ?:TX(1'b1,`CMD_WRITE ,`DATA_0); ? ? ? ? ? ? ? ? ? ? ??3? ? ? ? ? ?:TX(1'b1,{`CMD_WRITE | `CMD_STOP},`DATA_1); ? ? ? ? ? ? ? ? ? ? ?default? ? ?:TX(1'b0,tx_cmd,tx_data); ? ? ? ? ? ? ? ?endcase? ? ? ? ? ? ? ? ?READ : ? ? ? ? ? ? ? ? ? ? ? ? ? ??case(cnt_byte) ? ? ? ? ? ? ? ? ? ?0? ? ? ? ? ?:TX(1'b1,{`CMD_START | `CMD_WRITE},{`I2C_ADR,1'b1}); ? ? ? ? ? ? ? ? ? ?1? ? ? ? ? ?:TX(1'b1,`CMD_READ ,0); ? ? ? ? ? ? ? ? ? ? ??2? ? ? ? ? ?:TX(1'b1,`CMD_READ ,0); ? ? ? ? ? ? ? ? ? ? ??3? ? ? ? ? ?:TX(1'b1,`CMD_READ ,0); ? ? ? ? ? ? ? ? ? ? ??4? ? ? ? ? ?:TX(1'b1,`CMD_READ ,0); ? ? ? ? ? ? ? ? ? ? ??5? ? ? ? ? ?:TX(1'b1,`CMD_READ ,0); ? ? ? ? ? ? ? ? ? ? ??6? ? ? ? ? ?:TX(1'b1,{`CMD_READ | `CMD_STOP},0); ? ? ? ? ? ? ? ? ? ?default? ? ?:TX(1'b0,tx_cmd,tx_data); ? ? ? ? ? ? ? ?endcasedefault: TX(1'b0,0,0); ? ? ? ?endcaseend// finish_initalways?@(posedge?sys_clk?ornegedge?rst_n)?beginif(!rst_n)?begin? ? ? ? ? ? ?finish_init <=?0; ? ? ? ?endelseif(state_c == CHECK_INIT && done && rd_data[3])?begin? ? ? ? ? ? ?finish_init <=?1; ? ? ? ?endend// read_dataalways?@(posedge?sys_clk?ornegedge?rst_n)?beginif(!rst_n)?begin? ? ? ? ? ? ?read_data <=?0; ? ? ? ?endelseif(state_c == READ && cnt_byte >0&& done)begin      read_data <= {read_data[39:0],rd_data}; ? ? ? ?endend//task?TX; ? ? ? ? ? ?input? ? ? ? ? ? ? ? ? ?req ? ? ; ? ? ? ?input? ? ? ?[3:0] ? ? ? command ; ? ? ? ?input? ? ? ?[7:0] ? ? ? data ? ?; ? ? ? ?begin? ? ? ? ? ? ? tx_req ?= req; ? ? ? ? ? ? tx_cmd ?= command; ? ? ? ? ? ? tx_data = data; ? ? ? ?endendtask//outassign?req ? ? = tx_req ; ? ? ?assign?cmd ? ? = tx_cmd ; ? ? ?assign?data ? ?= tx_data; ? ? ?assign?hum_data = read_data[39:20]; ? ?assign?temp_data = read_data[19:0]; ? ?assign?dout_vld = read2idle;endmodule

其它模塊

然后將溫濕度數值按照上述格式轉換:

temp_data_r<= (((temp_data*2000)>>12) - (500)); hum_data_r<= ((hum_data *1000) >>12);

再將數據轉換成ASCII碼:

always@(posedge sys_clk or negedge rst_n)begin  case(cnt)    1: dout_r <=?8'hce; ? ? ? ? ?2?: dout_r <=?8'hc2; ? ? ? ?3?: dout_r <=?8'hb6; ? ? ? ?4?: dout_r <=?8'hc8; ? ? ? ?5?: dout_r <=?8'h3a; ? ? ? ? ?6?: dout_r <= (temp_data_r /?100?%?10?)+48; ? ? ? ?7?: dout_r <= (temp_data_r /?10?%?10? )+48; ? ? ? ?8?: dout_r <=?8'h2e; ? ? ? ?9?: dout_r <= (temp_data_r %?10? )+48; ? ? ? ?10?: dout_r <=?8'ha1; ? ? ? ? ?11?: dout_r <=?8'he6; ? ? ? ?12: dout_r <=?9; ? ? ? ? ?13: dout_r <=?8'hca; ? ? ? ? ?14: dout_r <=?8'haa; ? ? ? ?15: dout_r <=?8'hb6; ? ? ? ?16: dout_r <=?8'hc8; ? ? ? ?17: dout_r <=?8'h3a; ? ? ? ?18: dout_r <= (hum_data_r /?100?%?10?)+48; ? ? ? ?19: dout_r <= (hum_data_r /?10?%?10?)+48; ? ? ? ?20: dout_r <=?8'h2e; ? ? ? ?21: dout_r <= (hum_data_r %?10? )+48; ? ? ? ?22: dout_r <=?8'h25; ? ? ? ?default: dout_r <=?0; ? ?endcaseend

最后將數值通過FIFO緩存完整的22字節數據后輸出即可;

同時還可以將數據轉換成bcd碼顯示到數碼管上;

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1644

    文章

    22007

    瀏覽量

    616333
  • 數字信號
    +關注

    關注

    2

    文章

    996

    瀏覽量

    48234
  • 溫濕度傳感器

    關注

    5

    文章

    593

    瀏覽量

    36439
  • I2C接口
    +關注

    關注

    1

    文章

    141

    瀏覽量

    25972

原文標題:基于FPGA的AHT10(溫濕度傳感器)驅動設計

文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    AHT20溫濕度傳感器的數據采集

    基于I2C硬件協議的AHT20溫濕度傳感器的數據采集一、軟件I2C二、硬件I2C三、基于I2C硬件協議的AHT20溫濕度
    發表于 08-23 06:57

    aht10溫濕度傳感器的特點有哪些呢

    aht10溫濕度傳感器特點及使用介紹前言一、ds18b20數字溫度傳感器外觀二、原理圖三、相關參數講解1.引腳2.溫度測量范圍3.通訊方式(單總線)4.優點4.特點四、內部結構圖總結前
    發表于 01-25 07:53

    W601之AHT10溫濕度傳感器簡介

    14、W601之AHT10溫濕度傳感器一、AHT10簡介AHT10 是一款高精度,完全校準,貼片封裝的
    發表于 02-11 07:45

    AHT20溫濕度傳感器簡介

    目錄一、AHT20溫濕度傳感器簡介二、AHT20 封裝設計三、AHT20 元件設計四、原理圖設計五、總結博客內容:學習
    發表于 02-14 07:29

    怎樣去讀取溫濕度傳感器AHT10)及無線發送數據呢

    1,讀取溫濕度傳感器AHT10)本項目中,采用的是模擬I2C來讀取數據,用STM32G031標準的I2C來讀不行,不知到為什么,希望看到這個文章的您多多交流,用標準I2C就非常簡單了。具體的模擬
    發表于 02-21 07:35

    【沁恒微CH32V307評估板試用體驗】使用AHT10獲取溫濕度

    : 第二步:讀取溫濕度這個就更簡單了,發送數據讀取命令即可。 關于AHT10更詳細的說明請參看《AHT10技術手冊》。2 AHT10配置RT-Thread提供了
    發表于 05-31 21:37

    在Art-Pi開發板上使用AHT10溫濕度模塊

    開發環境:rt-thread studio開發板:Art-PiArt-Pi上沒有溫濕度監控的傳感器,需要自己添加,于是近日從某寶上購得AHT10溫濕度模塊,于是乎接到Art-Pi上體驗
    發表于 08-17 14:25

    基于51單片機和AHT10溫濕度傳感器溫濕度計源碼

    一款基于51單片機和AHT10溫濕度傳感器溫濕度計源碼。
    發表于 10-09 08:39

    MSP430 F149 單片機 AHT10 溫濕度 LCD1602 顯示

    MSP430 F149 單片機 AHT10 溫濕度 LCD1602 顯示
    發表于 11-19 17:06 ?23次下載
    MSP430 F149 單片機 <b class='flag-5'>AHT10</b> <b class='flag-5'>溫濕度</b> LCD1602 顯示

    aht10溫濕度傳感器特點及使用介紹

    aht10溫濕度傳感器特點及使用介紹前言一、ds18b20數字溫度傳感器外觀二、原理圖三、相關參數講解1.引腳2.溫度測量范圍3.通訊方式(單總線)4.優點4.特點四、內部結構圖總結前
    發表于 12-01 09:21 ?19次下載
    <b class='flag-5'>aht10</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>特點及使用介紹

    14、W601之AHT10溫濕度傳感器

    14、W601之AHT10溫濕度傳感器一、AHT10簡介AHT10 是一款高精度,完全校準,貼片封裝的
    發表于 12-08 13:21 ?5次下載
    14、W601之<b class='flag-5'>AHT10</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>

    AHT10溫濕度傳感器的使用

    大,價格大概3塊多一個吧。在淘寶上搜索溫濕度傳感器,偶然發現AHT10傳感器,價格2.5一個,體積小,精度濕度±2%RH,溫度精度±0.3℃
    發表于 07-20 11:08 ?4301次閱讀

    用國產高精度溫濕度傳感器AHT10,接入機智云實現數據傳輸

    大,價格大概3塊多一個吧。在淘寶上搜索溫濕度傳感器,偶然發現AHT10傳感器,價格2.5一個,體積小,精度濕度±2%RH,溫度精度±0.3℃
    的頭像 發表于 07-21 10:48 ?2821次閱讀
    用國產高精度<b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b><b class='flag-5'>AHT10</b>,接入機智云實現數據傳輸

    基于RVB2601開發板的AHT10溫濕度傳感器

    AHT10 是一款高精度,完全校準,貼片封裝的溫濕度傳感器AHT10 通信方式采用標準 IIC 通信方式,支持較寬的工作電源電壓范圍,溫濕度
    發表于 10-07 15:18 ?1535次閱讀
    基于RVB2601開發板的<b class='flag-5'>AHT10</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>

    CW32模塊使用案例 AHT10溫濕度傳感器

    AHT10,新一代溫濕度傳感器在尺寸與智能方面建立了新的標準:它嵌入了適于回流焊的雙列扁平無引腳SMD 封裝,底面 4 x 5mm ,高度1.6mm。傳感器輸出經過標定的數字信號,標準
    的頭像 發表于 11-28 17:28 ?1018次閱讀
    CW32模塊使用案例 <b class='flag-5'>AHT10</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>
    主站蜘蛛池模板: 在线视频亚洲 | 人人97| 欧美日一区 | 免费人成网站线观看合集 | 热久久综合这里只有精品电影 | 青草久草视频 | ww久久| 亚洲日本黄色 | 欧美成人一区二区三区在线视频 | 日本亚洲免费 | 22eee在线播放成人免费视频 | 天天操夜夜操视频 | 成人精品亚洲人成在线 | 宅男666在线永久免费观看 | 国产亚洲卡二卡3卡4卡乱码 | 婷婷啪啪| 色网址在线 | 欧美成人高清性色生活 | 视频在线观看高清免费看 | 日本免费黄色大片 | 国产欧美另类第一页 | av天天看| 丁香激情综合 | 午夜在线播放视频在线观看视频 | xxxx日本69| 久久99热久久精品99 | 亚洲成年人在线 | 黄色免费大全 | 国产精品大尺度尺度视频 | 亚洲最大的黄色网址 | 天天爱天天做久久天天狠狼 | 69pao强力打造免费高速 | 欧美视频一区二区三区在线观看 | 激情97| 白丝丝袜高跟国产在线视频 | 卡一卡二卡三国色天香永不失联 | 国产h在线 | 色网站在线看 | 成人在线免费电影 | 永久黄网站色视频免费观看99 | 免费观看视频在线观看 |