一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于FPGA的AHT10溫濕度傳感器驅(qū)動(dòng)設(shè)計(jì)

FPGA設(shè)計(jì)論壇 ? 來(lái)源:FPGA設(shè)計(jì)論壇 ? 2025-06-27 10:12 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

概念

傳感器輸出經(jīng)過(guò)標(biāo)定的數(shù)字信號(hào)輸出,通過(guò)標(biāo)準(zhǔn)的I2C接口傳輸數(shù)據(jù);

相對(duì)濕度的分辨率在0.024%RH,工作范圍為0~100%RH;

溫度值的分辨率在0.01℃,工作范圍為-40~85℃;

AHT10的供電范圍為1.8~3.6V,推薦使用3.3V供電;

接口包含了完全靜態(tài)邏輯,因而不存在最小串行時(shí)鐘SCL頻率;

IIC協(xié)議,同步半雙工通信協(xié)議

起始位:主機(jī)在時(shí)鐘高電平期間拉低總線;

數(shù)據(jù)位:主機(jī)在時(shí)鐘低電平期間發(fā)送數(shù)據(jù),主機(jī)在高電平期間保持不變;從機(jī)在時(shí)鐘高電平期間采樣數(shù)據(jù);

應(yīng)答為:主機(jī)收到數(shù)據(jù)后發(fā)送應(yīng)答,從機(jī)才會(huì)發(fā)送下一字節(jié)數(shù)據(jù);

停止位:主機(jī)在時(shí)鐘高電平期間釋放總線,主機(jī)在低電平期間保持不變;

可使用的I2C通信模式有經(jīng)典型和高速模式,經(jīng)典模式最小時(shí)鐘周期是250us,高速模式最小時(shí)鐘周期是100us;

AHT10配置與通信

I2C通信通過(guò)設(shè)備地址與從機(jī)進(jìn)行通信,

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

首先上電啟動(dòng)傳感器,啟動(dòng)后需要先等待40ms(設(shè)備才開(kāi)始正常工作),然后發(fā)送8‘h71 來(lái)獲取狀態(tài)字節(jié),狀態(tài)寄存器說(shuō)明如下:

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

獲取到校準(zhǔn)使能位后,查看其是否已校準(zhǔn),若已校準(zhǔn)則跳過(guò)當(dāng)前步驟;若未校準(zhǔn)則發(fā)送8‘hE1,進(jìn)行初始化,然后發(fā)送8’h08,8‘h00;

接著開(kāi)始觸發(fā)測(cè)量,測(cè)量先發(fā)送8’hAC,然后發(fā)送8‘h33,8'h00;

測(cè)量命令發(fā)送完成后,需要等待80ms,用于溫濕度的測(cè)量;之后再發(fā)送命令8‘h71,以讀取狀態(tài)寄存器是否處于空閑狀態(tài)(bit7 => idle);若是空閑狀態(tài),可以直接讀取之后六個(gè)字節(jié)的溫濕度數(shù)值;

讀取溫濕度數(shù)據(jù)構(gòu)成

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

相對(duì)濕度和溫度轉(zhuǎn)換公式

將接收到的濕度值轉(zhuǎn)換成%RH的格式:

R H [ % ] = ( S R H / 2 20 ) RH [\%] = (SRH/2^{20}) RH[%]=(SRH/220)

溫度轉(zhuǎn)換成℃表示:

T ( ℃ ) = ( S T / 2 20 ) . T(℃) = (ST/2^{20}). T(℃)=(ST/220).

設(shè)計(jì)框架

整個(gè)模塊的設(shè)計(jì),首先是上位機(jī)通過(guò)UART,發(fā)送命令打開(kāi)AHT10驅(qū)動(dòng)控制模塊、數(shù)碼管顯示模塊以及串口模塊;設(shè)備驅(qū)動(dòng)用控制模塊實(shí)現(xiàn),通信接口使用I2C與AHT10進(jìn)行通信,然后將讀取的溫濕度值先進(jìn)行數(shù)值轉(zhuǎn)換并取整,并轉(zhuǎn)換成ASCII碼方便查看溫濕度值;然后將數(shù)據(jù)緩存到FIFO中,當(dāng)緩存了一組完整的溫度值數(shù)據(jù)后進(jìn)行輸出,發(fā)送給上位機(jī),或是直接通過(guò)數(shù)碼管顯示;

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

I2C模塊

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

I2C接口模塊狀態(tài)機(jī)如上圖所示,從空閑狀態(tài)可以先發(fā)送起始位再讀寫(xiě)一個(gè)字節(jié)數(shù)據(jù),或直接讀寫(xiě)一個(gè)字節(jié)數(shù)據(jù),然后是收發(fā)應(yīng)答位;最后發(fā)送停止位,就完成了一組數(shù)據(jù)的讀寫(xiě);

對(duì)于I2C通信,數(shù)據(jù)的傳輸速率選擇的是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     );//狀態(tài)機(jī)參數(shù)定義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   ;//產(chǎn)生i2c時(shí)鐘wire        add_cnt_scl ;  wire        end_cnt_scl ;  reg  [3:0]    cnt_bit   ;//傳輸數(shù)據(jù) bit計(jì)數(shù)器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   ;//發(fā)送數(shù)據(jù)wire        idle2start ;   wire        idle2write ;   wire        idle2read  ;   wire        start2write ;   wire        start2read ;   wire        write2rack ;   wire        read2sack  ;   wire        rack2stop  ;   wire        sack2stop  ;   wire        rack2idle  ;   wire        sack2idle  ;   wire        stop2idle  ;  //狀態(tài)機(jī)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); ? ??//計(jì)數(shù)器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//開(kāi)始發(fā)送時(shí),拉低? ? ? ? ? ? ?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//發(fā)起始位if(cnt_scl == `LOW_HLAF)begin//時(shí)鐘低電平時(shí)拉高sda總線? ? ? ? ? ? ? ? ?sda_out <=?1'b1; ? ? ? ? ? ?endelseif(cnt_scl == `HIGH_HALF)begin//時(shí)鐘高電平時(shí)拉低sda總線?? ? ? ? ? ? ? ? ?sda_out <=?1'b0; ? ? ? ? ? ? ? ?//保證從機(jī)能檢測(cè)到起始位endendelseif(state_c == WRITE && cnt_scl == `LOW_HLAF)begin//scl低電平時(shí)發(fā)送數(shù)據(jù) ? 并串轉(zhuǎn)換? ? ? ? ? ? ?sda_out <= tx_data[7-cnt_bit]; ? ? ? ? ? ? ??endelseif(state_c == SACK && cnt_scl == `LOW_HLAF)begin//發(fā)應(yīng)答位? ? ? ? ? ? ?sda_out <= (command&`CMD_STOP)?1'b1:1'b0; ? ? ? ?endelseif(state_c == STOP)begin//發(fā)停止位if(cnt_scl == `LOW_HLAF)begin//時(shí)鐘低電平時(shí)拉低sda總線? ? ? ? ? ? ? ? ?sda_out <=?1'b0; ? ? ? ? ? ?endelseif(cnt_scl == `HIGH_HALF)begin//時(shí)鐘高電平時(shí)拉高sda總線?? ? ? ? ? ? ? ? ?sda_out <=?1'b1; ? ? ? ? ? ? ? ?//保證從機(jī)能檢測(cè)到停止位endendend//sda_out_en ?總線輸出數(shù)據(jù)使能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 ? ? ? 接收讀入的數(shù)據(jù)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; ? ?//串并轉(zhuǎn)換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//輸出信號(hào)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//狀態(tài)轉(zhuǎn)移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

其它模塊

然后將溫濕度數(shù)值按照上述格式轉(zhuǎn)換:

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

再將數(shù)據(jù)轉(zhuǎn)換成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

最后將數(shù)值通過(guò)FIFO緩存完整的22字節(jié)數(shù)據(jù)后輸出即可;

同時(shí)還可以將數(shù)據(jù)轉(zhuǎn)換成bcd碼顯示到數(shù)碼管上;

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1644

    文章

    22007

    瀏覽量

    616362
  • 數(shù)字信號(hào)
    +關(guān)注

    關(guān)注

    2

    文章

    996

    瀏覽量

    48235
  • 溫濕度傳感器
    +關(guān)注

    關(guān)注

    5

    文章

    593

    瀏覽量

    36439
  • I2C接口
    +關(guān)注

    關(guān)注

    1

    文章

    141

    瀏覽量

    25973

原文標(biāo)題:基于FPGA的AHT10(溫濕度傳感器)驅(qū)動(dòng)設(shè)計(jì)

文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

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

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    AHT20溫濕度傳感器的數(shù)據(jù)采集

    基于I2C硬件協(xié)議的AHT20溫濕度傳感器的數(shù)據(jù)采集一、軟件I2C二、硬件I2C三、基于I2C硬件協(xié)議的AHT20溫濕度
    發(fā)表于 08-23 06:57

    aht10溫濕度傳感器的特點(diǎn)有哪些呢

    aht10溫濕度傳感器特點(diǎn)及使用介紹前言一、ds18b20數(shù)字溫度傳感器外觀二、原理圖三、相關(guān)參數(shù)講解1.引腳2.溫度測(cè)量范圍3.通訊方式(單總線)4.優(yōu)點(diǎn)4.特點(diǎn)四、內(nèi)部結(jié)構(gòu)圖總結(jié)前
    發(fā)表于 01-25 07:53

    W601之AHT10溫濕度傳感器簡(jiǎn)介

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

    AHT20溫濕度傳感器簡(jiǎn)介

    目錄一、AHT20溫濕度傳感器簡(jiǎn)介二、AHT20 封裝設(shè)計(jì)三、AHT20 元件設(shè)計(jì)四、原理圖設(shè)計(jì)五、總結(jié)博客內(nèi)容:學(xué)習(xí)
    發(fā)表于 02-14 07:29

    怎樣去讀取溫濕度傳感器AHT10)及無(wú)線發(fā)送數(shù)據(jù)呢

    1,讀取溫濕度傳感器AHT10)本項(xiàng)目中,采用的是模擬I2C來(lái)讀取數(shù)據(jù),用STM32G031標(biāo)準(zhǔn)的I2C來(lái)讀不行,不知到為什么,希望看到這個(gè)文章的您多多交流,用標(biāo)準(zhǔn)I2C就非常簡(jiǎn)單了。具體的模擬
    發(fā)表于 02-21 07:35

    【沁恒微CH32V307評(píng)估板試用體驗(yàn)】使用AHT10獲取溫濕度

    : 第二步:讀取溫濕度這個(gè)就更簡(jiǎn)單了,發(fā)送數(shù)據(jù)讀取命令即可。 關(guān)于AHT10更詳細(xì)的說(shuō)明請(qǐng)參看《AHT10技術(shù)手冊(cè)》。2 AHT10配置RT-Thread提供了
    發(fā)表于 05-31 21:37

    在Art-Pi開(kāi)發(fā)板上使用AHT10溫濕度模塊

    開(kāi)發(fā)環(huán)境:rt-thread studio開(kāi)發(fā)板:Art-PiArt-Pi上沒(méi)有溫濕度監(jiān)控的傳感器,需要自己添加,于是近日從某寶上購(gòu)得AHT10溫濕度模塊,于是乎接到Art-Pi上體驗(yàn)
    發(fā)表于 08-17 14:25

    基于51單片機(jī)和AHT10溫濕度傳感器溫濕度計(jì)源碼

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

    MSP430 F149 單片機(jī) AHT10 溫濕度 LCD1602 顯示

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

    aht10溫濕度傳感器特點(diǎn)及使用介紹

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

    14、W601之AHT10溫濕度傳感器

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

    AHT10溫濕度傳感器的使用

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

    用國(guó)產(chǎn)高精度溫濕度傳感器AHT10,接入機(jī)智云實(shí)現(xiàn)數(shù)據(jù)傳輸

    大,價(jià)格大概3塊多一個(gè)吧。在淘寶上搜索溫濕度傳感器,偶然發(fā)現(xiàn)AHT10傳感器,價(jià)格2.5一個(gè),體積小,精度濕度±2%RH,溫度精度±0.3℃
    的頭像 發(fā)表于 07-21 10:48 ?2822次閱讀
    用國(guó)產(chǎn)高精度<b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b><b class='flag-5'>AHT10</b>,接入機(jī)智云實(shí)現(xiàn)數(shù)據(jù)傳輸

    基于RVB2601開(kāi)發(fā)板的AHT10溫濕度傳感器

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

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

    AHT10,新一代溫濕度傳感器在尺寸與智能方面建立了新的標(biāo)準(zhǔn):它嵌入了適于回流焊的雙列扁平無(wú)引腳SMD 封裝,底面 4 x 5mm ,高度1.6mm。傳感器輸出經(jīng)過(guò)標(biāo)定的數(shù)字信號(hào),標(biāo)準(zhǔn)
    的頭像 發(fā)表于 11-28 17:28 ?1018次閱讀
    CW32模塊使用案例 <b class='flag-5'>AHT10</b><b class='flag-5'>溫濕度</b><b class='flag-5'>傳感器</b>