概念
傳感器輸出經(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í)鐘高電平期間拉低總線(xiàn);
數(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í)鐘高電平期間釋放總線(xiàn),主機(jī)在低電平期間保持不變;
可使用的I2C通信模式有經(jīng)典型和高速模式,經(jīng)典模式最小時(shí)鐘周期是250us,高速模式最小時(shí)鐘周期是100us;
AHT10配置與通信
I2C通信通過(guò)設(shè)備地址與從機(jī)進(jìn)行通信,
首先上電啟動(dòng)傳感器,啟動(dòng)后需要先等待40ms(設(shè)備才開(kāi)始正常工作),然后發(fā)送8‘h71 來(lái)獲取狀態(tài)字節(jié),狀態(tài)寄存器說(shuō)明如下:
獲取到校準(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)成
相對(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ù)碼管顯示;
I2C模塊
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總線(xiàn)? ? ? ? ? ? ? ? ?sda_out <=?1'b1; ? ? ? ? ? ?endelseif(cnt_scl == `HIGH_HALF)begin//時(shí)鐘高電平時(shí)拉低sda總線(xiàn)?? ? ? ? ? ? ? ? ?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總線(xiàn)? ? ? ? ? ? ? ? ?sda_out <=?1'b0; ? ? ? ? ? ?endelseif(cnt_scl == `HIGH_HALF)begin//時(shí)鐘高電平時(shí)拉高sda總線(xiàn)?? ? ? ? ? ? ? ? ?sda_out <=?1'b1; ? ? ? ? ? ? ? ?//保證從機(jī)能檢測(cè)到停止位endendend//sda_out_en ?總線(xiàn)輸出數(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ù)碼管上;
-
FPGA
+關(guān)注
關(guān)注
1644文章
22007瀏覽量
616295 -
數(shù)字信號(hào)
+關(guān)注
關(guān)注
2文章
996瀏覽量
48233 -
溫濕度傳感器
+關(guān)注
關(guān)注
5文章
593瀏覽量
36437 -
I2C接口
+關(guān)注
關(guān)注
1文章
141瀏覽量
25970
原文標(biāo)題:基于FPGA的AHT10(溫濕度傳感器)驅(qū)動(dòng)設(shè)計(jì)
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
AHT20溫濕度傳感器的數(shù)據(jù)采集
aht10溫濕度傳感器的特點(diǎn)有哪些呢
W601之AHT10溫濕度傳感器簡(jiǎn)介
AHT20溫濕度傳感器簡(jiǎn)介
怎樣去讀取溫濕度傳感器(AHT10)及無(wú)線(xiàn)發(fā)送數(shù)據(jù)呢
【沁恒微CH32V307評(píng)估板試用體驗(yàn)】使用AHT10獲取溫濕度
在Art-Pi開(kāi)發(fā)板上使用AHT10溫濕度模塊
MSP430 F149 單片機(jī) AHT10 溫濕度 LCD1602 顯示

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

14、W601之AHT10溫濕度傳感器

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

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

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

評(píng)論