国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

FPGA實(shí)驗(yàn)筆記_Vivado:DDS信號(hào)發(fā)生器;數(shù)碼管;基于DHT11的溫濕度傳感器

這篇具有很好參考價(jià)值的文章主要介紹了FPGA實(shí)驗(yàn)筆記_Vivado:DDS信號(hào)發(fā)生器;數(shù)碼管;基于DHT11的溫濕度傳感器。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

1、 FPGA的DDS信號(hào)發(fā)生器

1.1、DDS簡(jiǎn)介

1.2、ROM IP核的生成

1.3、波形數(shù)據(jù)的生成

1.4、 ROM的調(diào)用

1.5、 完整代碼(包括拓展部分)

2、數(shù)碼管顯示

2.1、數(shù)碼管簡(jiǎn)要說(shuō)明

2.2、SM410564

3、基于DHT11的溫濕度傳感器

3.1、DHT11

3.2、基本思路

3.3、數(shù)據(jù)分離模塊(BTD)

3.4、數(shù)據(jù)轉(zhuǎn)換模塊(SMG)

3.5、DHT11控制模塊

3.5.1、上升、下降沿的判定

3.5.2、端口IO狀態(tài)控制

3.5.3、狀態(tài)判斷

3.5.4、數(shù)據(jù)讀入

3.5.5、完整代碼

3.6、TOP

3.7、結(jié)果展示


?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-764084.html

1、 FPGA的DDS信號(hào)發(fā)生器

1.1、DDS簡(jiǎn)介

? ? ? ? DSS全稱為“直接數(shù)字式頻率合成”,通過(guò)邏輯高低電平的相加合成數(shù)字信號(hào),在將數(shù)信信號(hào)轉(zhuǎn)換,生成模擬信號(hào)。

? ? ? ? DSS信號(hào)發(fā)生器的實(shí)現(xiàn)主要分為三個(gè)步驟:

  1. ? ? ? ? 生成所需波形數(shù)據(jù)并儲(chǔ)存到IP核“ROM”中;
  2. ? ? ? ? 讀取波形數(shù)據(jù)并輸出數(shù)字信號(hào);
  3. ? ? ? ? 將數(shù)字信號(hào)通過(guò)DA轉(zhuǎn)換模塊轉(zhuǎn)換成模擬信號(hào)。

1.2、ROM IP核的生成

? ? ? ? 調(diào)用ROM,首先需要生成一個(gè)ROM。步驟如下:

????????1.? ? ? ? ?PROJECT MANAGER -- IP Catalog;

????????2.? ? ? ? 在IP Catalog界面搜索ROM,選擇RAMs & ROMs & BRAM -- Block Memory Generator;

????????3.? ? ? ? 選擇所需要的Memory Type ,這里我們選擇Single Port ROM;?

vivado dds,FPGA-Vivado學(xué)習(xí),fpga開(kāi)發(fā),筆記

????????4.? ? ? 設(shè)定Memory Size,根據(jù)所需要的Width 與 Depth,這里我們由于所用的波形數(shù)據(jù)為256個(gè)采樣點(diǎn),故設(shè)定Width = 8;Depth = 256;

vivado dds,FPGA-Vivado學(xué)習(xí),fpga開(kāi)發(fā),筆記

? ? ? ????????5.????????設(shè)定波形文件,在Memory Initialization中勾選 Load Init File,然后在Coe File一欄選擇對(duì)于的文件,隨后點(diǎn)擊OK,這樣ROM就生成完畢了。

? ? ? ? ? ? ? 調(diào)用端口如下:

rom_name rom_name(
.clka( ),
//input ck
.addra( ),
//input address
.douta( )
//output data
);

? ? ? ? ?????????需要注意,rom的地址從0開(kāi)始,依次向上加1。如0地址的下一位地址為1。

1.3、波形數(shù)據(jù)的生成

? ? ? ? 波形數(shù)據(jù)生成較為簡(jiǎn)單,MATLAB代碼如下:

clc;
clear all;
N=2^8;
A=2^8;%振幅
f=1;9
F1=0;%相位
F2=256;
n=[0:N-1];
s1=round((A/2)*sin(2*pi*n/N+pi*F1)+F2/2);%256/2為0    
fild=fopen('wave_dds_sin.coe','wt');
fprintf(fild,'memory_initialization_radix=10;\n');
fprintf(fild,'memory_initialization_vector=\n');
for i=1:N
    if(s1(i)==256)
            s1(i)=255;
    end
    fprintf(fild,'%d,\n',s1(i));
end
fclose(fild);
plot(s1)

? ? ? ? 通過(guò)程序生成單周期有256個(gè)數(shù)據(jù)點(diǎn)的正弦波,A為峰峰值。

? ? ? ? 需要注意最小值為0,而最大值并非256,而是255,因?yàn)镽OM所設(shè)置的Width為8,僅能儲(chǔ)存八位二進(jìn)制數(shù),而256為“ 'b100000000 ” 。若最大值為256,則會(huì)在ROM選擇信號(hào)源文件時(shí)報(bào)錯(cuò)。

1.4、 ROM的調(diào)用

? ? ? ? 假設(shè)系統(tǒng)時(shí)鐘頻率為50MHz,一個(gè)周期輸出一個(gè)數(shù)據(jù)點(diǎn),則輸出波形頻率為

? ? ? ? ? ? ? ? ? ? ? ? Fout = 50M/256 Hz = 195312.5Hz

? ? ? ? 若想要改變輸出波形的頻率,可以生成一個(gè)相位累加器,俗稱加法器,同時(shí)設(shè)置一個(gè)頻率控制字Fword來(lái)控制加法器累加的速度。

? ? ? ? 雖然在固定的時(shí)鐘頻率下加法器每次累加的速度是一樣的,但是可以調(diào)整每次累加的步長(zhǎng)來(lái)控制其達(dá)到最大值的速度。

? ? ? ? 頻率控制字、加法器長(zhǎng)度(位數(shù))N、時(shí)鐘頻率以及輸出波形頻率關(guān)系如下:

? ? ? ? ? ? ? ? Fword * clk = Fout * 2 ^ N

? ? ? ? 加法器控制程序如下:

    always@(posedge dac_clk or negedge rst )//計(jì)數(shù)器,越界歸零, frequency = 50 MHz
        begin
            if(rst)   begin//當(dāng) rst = 1
                Fcnt <= 32'd0;
            end
            else//當(dāng)rst等于0時(shí)     
                Fcnt <= Fcnt + Fword;
        end

? ? ? ? ? ? ? ? 需要注意的是,由于程序中使用的頻率控制字并不一定為整數(shù),故在計(jì)算時(shí)會(huì)產(chǎn)生一定誤差,但此誤差基本可忽略不計(jì)。

? ? ? ? 由于所用的ROM地址為8位二進(jìn)制數(shù),在一個(gè)周期內(nèi)需要從0變化到255 即 11111111 一次,而累加器同樣需要變到 1111 1111……一次,故可以使用累加器的前八位作為調(diào)用ROM的地址。

        assign rom_addr = Fcnt[31:24] + Pword;

1.5、 完整代碼(包括拓展部分)

module DDS_CHEN(
    input clk, //fpga clock
    input rst,//rst is 0 if no act
    input swi,
    input [3:0]bot,//按下時(shí)為高電平,邏輯1,控制頻率以及幅度
    output dac_clk,
    output [7:0]sin_out,  
    output  [4:0] led
 ); 
    reg [31:0] Fword;
    wire [31:0] Pword;
    assign Pword = 8'b0;    
    wire clk50;//標(biāo)準(zhǔn)時(shí)鐘
    wire clk10;//沒(méi)啥用
    
    wire [7:0] wave_data_sin;//讀取數(shù)據(jù)
    wire [7:0] wave_data_sq;
    
    reg [7:0] wave_data_r;//賦值數(shù)據(jù);
    reg [31:0] Fcnt;//計(jì)數(shù)器
    wire [7:0] rom_addr;//地址    
    
    reg [4:0]led_r;//測(cè)試用
    
//實(shí)際時(shí)鐘
    assign dac_clk = clk50;   //輸出時(shí)鐘
 //仿真時(shí)鐘
    //assign dac_clk = clk;

//控頻
    //50M clk 858993-10k 8589933-100k 429497-5k 85899-1k 4295-50 相位累加器步長(zhǎng)誤差最大為7.6E-6
    //Fword = fout*(2^n)/fclk   n = 32 fclk = 50MHz
    always@( posedge clk50)
    begin
        casex(bot)
            4'b11xx: Fword = 4295;//50
            4'b10xx: Fword = 85899;//1k
            4'b01xx: Fword = 429497;//5k
            4'b00xx: Fword = 858993;//10k
            default :Fword = 858993;
        endcase
    end
        
//地址控制 
    always@(posedge dac_clk or negedge rst )//計(jì)數(shù)器,越界歸零, frequency = 50 MHz
        begin
            if(rst)   begin//當(dāng) rst = 1
                Fcnt <= 32'd0;
            end
            else//當(dāng)rst等于0時(shí)     
                Fcnt <= Fcnt + Fword;
        end
        assign rom_addr = Fcnt[31:24] + Pword;//the first 8 bit as the address

//指示燈        
    always@(posedge dac_clk)
        begin
            if(!rst&&!bot)
                led_r <= 5'b1;
            else if(!rst&&bot[0])
                led_r <= 5'b00010;
            else if(!rst&&bot[1])
                led_r <= 5'b00100;
            else if(!rst&&bot[2])
                led_r <= 5'b01000;
            else if(!rst&&bot[3])
                led_r <= 5'b10000;
            else
                led_r <=0;
        end    
    
//賦值與控幅,控幅還可以通過(guò)外部電路改變電壓來(lái)實(shí)現(xiàn)        
    always@(posedge dac_clk)
        begin
          case(swi)
          1'b0:
            casex(bot)
            4'bxx00 : wave_data_r <= wave_data_sin / 4;
            4'bxx01 : wave_data_r <= wave_data_sin / 2;
            4'bxx10 : wave_data_r <= (wave_data_sin / 4)*3 ;
            4'bxx11 : wave_data_r <= wave_data_sin ;
            endcase
          1'b1:
             casex(bot)
             4'bxx00 : wave_data_r <= wave_data_sq / 4;
             4'bxx01 : wave_data_r <= wave_data_sq / 2;
             4'bxx10 : wave_data_r <= (wave_data_sq / 4)*3 ;
             4'bxx11 : wave_data_r <= wave_data_sq;
             default: wave_data_r <= 114;
             endcase
           endcase
         end                
    assign sin_out = wave_data_r;
    assign led = led_r;
    
blk_mem_gen_0 blk_mem_gen_0 (
 //實(shí)際
 .clka(clk50), // input clka
 //仿真
 //.clka(clk),
 .addra(rom_addr), // input [8 : 0] addra
 .douta(wave_data_sin) // output [7 : 0] douta
);

blk_mem_gen_1 sq(
//仿真
//.clka(clk),
//實(shí)際
.clka(clk50),
.addra(rom_addr),
.douta(wave_data_sq)
);
clk_wiz_0 clk_wiz_0 (
    .clk_in1(clk),
    .resetn(1'b1),
    .clk_out50M(clk50),
    .clk_out10M(clk10),
    .locked()
    );
endmodule

2、數(shù)碼管顯示

2.1、數(shù)碼管簡(jiǎn)要說(shuō)明

? ? ? ? 一般而言,數(shù)碼管可以分為共陰、共陽(yáng)兩種。

????????共陰為數(shù)碼管的八個(gè)二極管共用一個(gè)陰極,此時(shí)控制不同二極管陽(yáng)極的電平就可以控制其顯示狀態(tài),當(dāng)陽(yáng)極與陰極形成一定電壓差時(shí),二極管導(dǎo)通發(fā)光,即高電平發(fā)光。一般而言,共極低電平表示數(shù)碼管工作。

? ? ? ? 共陽(yáng)為數(shù)碼管的八個(gè)二極管共用一個(gè)陽(yáng)極。一般當(dāng)共陽(yáng)極為高電平時(shí)二極管工作,相應(yīng)二極管陰極為低電平時(shí)發(fā)光。即低電平發(fā)光。

? ? ? ? 共陽(yáng)、共陰極的數(shù)碼管真值表正好完全相反。??

2.2、SM410564

? ? ? ? 本次實(shí)驗(yàn)所使用的是四位共陽(yáng)數(shù)碼管SM410564。當(dāng)正視顯示面時(shí),其管腳約束如下:

?vivado dds,FPGA-Vivado學(xué)習(xí),fpga開(kāi)發(fā),筆記? ? ? ? s1~s4為四個(gè)共陽(yáng)極,控制四個(gè)顯示數(shù)位,可以同時(shí)為高電平,由于共極管腳分別獨(dú)立,故電平高低與否與其他管腳無(wú)關(guān)。

? ? ? ? a~g為顯示數(shù)字的七個(gè)發(fā)光二極管的陰極管腳,dp為小數(shù)點(diǎn)位置發(fā)光二極管的陰極管腳。

? ? ? ? 整個(gè)模塊共由4*8共32個(gè)發(fā)光二極管組成,顯然控制發(fā)光二極管的8個(gè)陰極管腳不足以同時(shí)顯示四個(gè)不同的符號(hào),但可以同時(shí)顯示相同的符號(hào)。故采用交替顯示的方式進(jìn)行輸出。

? ? ? ? 交替顯示通過(guò)對(duì)于每一時(shí)鐘周期,僅讓一個(gè)共極為高電平,并將相應(yīng)真值賦值,在下一個(gè)周期相鄰共極變?yōu)楦唠娖?,?dāng)前共極變?yōu)榈碗娖?,并重新進(jìn)行賦值,如此循環(huán)。假設(shè)時(shí)鐘周期為50M赫茲,則整個(gè)顯示模塊的刷新率即為50Mhz, 而對(duì)于單一的顯示位,刷新率為50M/4 = 12.5MHz遠(yuǎn)大于人眼25Hz或是80Hz的基本要求。

? ? ? ? 完整代碼如下:(刷新了為1lHz,輸出僅為6.6.6.6.)

`timescale 1ns / 1ps

module SMG(
    input clk,
    input rst,
    output [3:0] numo,
    output [6:0] datao,
    output pointo
    );
    wire clk50;
    reg [3:0]numr;
    wire [3:0]numw;
    reg [6:0]datar;
    wire[6:0]dataw;
    reg 	clk_s;		
    reg       [32:0]        cnt;//微妙時(shí)鐘計(jì)數(shù)器
    reg pointr;
    
    assign pointo = pointr;
    assign numo = numr;
    assign datao = datar;
    
    always@(posedge clk_s)//0.001s
    begin
        datar = 7'b0000_010;//6
        pointr = 1'b0;
        if(rst)
            numr = 4'b0001;
        else if(numr ==4'b1000)
            numr =  4'b0001;//從s4向s1刷新;
        else if(numr !=4'b1000)
                numr = numr << 1;
    end
 //時(shí)鐘   
    always@(posedge clk50 or negedge rst)
    begin//一個(gè)周期為25時(shí)鐘周期,0.02*25*10^6=0.5us,一個(gè)周期0.5us
        if(rst)
            cnt <= 32'd0;
        else if(cnt == 32'd24_999)//毫秒計(jì)數(shù)器
            cnt <= 32'd0;
        else 
            cnt <= cnt + 1'b1;
    end
    //微秒時(shí)鐘2,由cnt控制
    always@(posedge clk50 or negedge rst)
    begin
        if(rst)
            clk_s <= 1'b0;
        else if(cnt== 32'd24_999)//將cnt-us換為cnt,此時(shí)0.5us翻轉(zhuǎn)一次,clk-us一個(gè)周期為0.001s
            clk_s <= ~ clk_s;
        else 
            clk_s <= clk_s;
    end
 clk_wiz_0 clk_wiz_0(
    .reset(1'b0),
    .clk_in1(clk),

3、基于DHT11的溫濕度傳感器

3.1、DHT11

? ? ? ? 詳情參考技術(shù)手冊(cè)。

? ? ? ? 采用單線雙向串口通信,一次性傳輸四十個(gè)字節(jié)的二進(jìn)制數(shù)據(jù),高位先輸出。數(shù)據(jù)每八位分為一組,第一組為溫度整數(shù);第二組為溫度小數(shù);第三組為濕度整數(shù);第四組為濕度小數(shù);第五組為校驗(yàn)碼,在正常情況下第五組應(yīng)為前四組數(shù)據(jù)之和。

? ? ? ? 但對(duì)于簡(jiǎn)單的溫濕度測(cè)量來(lái)說(shuō),實(shí)際上有用的只有前24位,即前三組。因?yàn)樵诓煌卣沟那闆r下,濕度小數(shù)的部分輸出數(shù)據(jù)一直為0,即8'b 0000_0000。

? ? ? ? DHT11的通信串口需要并聯(lián)一個(gè)5K歐姆左右的上拉電阻使其在非工作狀態(tài)保持高電平,其控制主要分為6部分:

  1. ? ? ? ? 主機(jī)拉低電平18ms以上,推薦為20ms,但不要太長(zhǎng);
  2. ? ? ? ? 主機(jī)拉高20~40us等待輔機(jī)(DHT11)應(yīng)答,推薦為30us;
  3. ? ? ? ? 從機(jī)拉低80us;
  4. ? ? ? ? 從機(jī)拉高80us,并進(jìn)入數(shù)據(jù)傳輸階段;
  5. ? ? ? ? 傳輸數(shù)據(jù);
  6. ? ? ? ? 拉低50us后結(jié)束。

? ? ? ? 對(duì)于數(shù)據(jù)采集中0或1的判斷,通過(guò)每個(gè)字節(jié)高電平的時(shí)間來(lái)判斷。每個(gè)字節(jié)由恒定的50us低電平開(kāi)始,若高電平持續(xù)時(shí)間為20~28us,則為0;若高電平持續(xù)時(shí)間為70us,則為1。

? ? ? ? 在此時(shí)需要注意兩個(gè)問(wèn)題:

  1. 由于0與1的高電平持續(xù)時(shí)間相差較大,故可以用一個(gè)閾值來(lái)區(qū)分0與1,如小于50us就為0,大于50us就為1;
  2. 0與1的判定一定要在高電平結(jié)束后,也就是端口的下降沿進(jìn)行,負(fù)責(zé)會(huì)出現(xiàn)錯(cuò)誤數(shù)據(jù)。

3.2、基本思路

? ? ? ? 對(duì)于整個(gè)程序,將其分為三個(gè)模塊進(jìn)行。

  1. 首先DHT11控制模塊讀取數(shù)據(jù),并將數(shù)據(jù)傳輸給數(shù)據(jù)轉(zhuǎn)換模塊;
  2. 數(shù)據(jù)轉(zhuǎn)換將一組八位二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為兩個(gè)四位二進(jìn)制數(shù)據(jù),分別為各位數(shù)據(jù)與十位數(shù)據(jù),以配合數(shù)碼管輸出十進(jìn)制數(shù),并將數(shù)據(jù)傳輸給數(shù)碼管模塊;
  3. 數(shù)碼管模塊將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換為共陽(yáng)二極管所對(duì)應(yīng)的格式,并與相應(yīng)的顯示匹配,最終輸出。

??????????此外,額外設(shè)置一個(gè)按鈕flag_key來(lái)控制溫濕度的切換顯示。vivado dds,FPGA-Vivado學(xué)習(xí),fpga開(kāi)發(fā),筆記

?

3.3、數(shù)據(jù)分離模塊(BTD)

? ? ? ? ?此模塊較為簡(jiǎn)單,有四個(gè)輸入:時(shí)鐘clk、復(fù)位rst、整數(shù)部分輸入int_in、小數(shù)部分輸入dec_in;四個(gè)輸出:int_out1,2和dec_out1,2,分別對(duì)應(yīng)整數(shù)、小數(shù)的十位與個(gè)位。

? ? ? ? 十位分離過(guò)程直接通過(guò)對(duì)10('b1010)整除即可以實(shí)現(xiàn);個(gè)位分離過(guò)程通過(guò)原數(shù)據(jù)減去十倍的十位部分即可得到。

? ? ? ? 代碼如下:

`timescale 1ns / 1ps
module BTD(
    input clk50,
    input [7:0] int_in,
    input [7:0] dec_in,
    output [3:0] int_out1,
    output [3:0] int_out2,
    output [3:0] dec_out1,
    output [3:0] dec_out2,    
    input rst
    );
//定義       
    reg [7:0]intbr;
    reg [3:0]in1;
    reg [3:0]in2;
    
    reg [3:0]de1;
    reg [3:0]de2;
    reg [7:0]decbr;  
 //整數(shù)位   
    always@(posedge clk50)begin
    intbr = int_in;
    in1 = intbr/4'b1010;
    in2 = intbr-in1*4'b1010;
    end
//小數(shù)位    
    always@(posedge clk50)begin
    decbr = dec_in;
    de1 = decbr/4'b1010;
    de2 = decbr-de1*4'b1010;
    end
 //賦值   
    assign int_out1 = in1;
    assign int_out2 = in2;
    assign dec_out1 = de1;
    assign dec_out2 = de2;
endmodule

3.4、數(shù)據(jù)轉(zhuǎn)換模塊(SMG)

? ? ? ? 數(shù)據(jù)轉(zhuǎn)換模塊結(jié)構(gòu)簡(jiǎn)單,主體部分即為四個(gè)數(shù)據(jù)選擇器。

? ? ? ? 需要注意的僅有共陽(yáng)數(shù)碼管為低電平發(fā)光以及數(shù)據(jù)賦值的順序?yàn)閺挠彝鬄閺牡偷礁摺?/p>

? ? ? ? 代碼如下:

`timescale 1ns / 1ps
module SMG(
        input   clk50,
        input   rst,
        input   data_flag,//0-hu    1-te//沒(méi)有用
        input   [3:0] int_in1,//D
        input   [3:0] dec_in1,//D
        input   [3:0] int_in2,//D
        input   [3:0] dec_in2,//D                    
        output  [6:0] data_out1,
        output  [6:0] data_out2,
        output  [6:0] data_out3,
        output  [6:0] data_out4
        );
//定義        
        reg    [3:0]numr;
        reg    [6:0]datar1;
        reg    [6:0]datar2;
        reg    [6:0]datar3;
        reg    [6:0]datar4;
        reg    [31:0]cnt;
        reg    [3:0]temp_data_1;
        reg    [3:0]temp_data_2;
        reg    [3:0]temp_data_3;
        reg    [3:0]temp_data_4;
        
        reg     int1;
        reg     int2;
        reg     dec1;
        reg     dec2;
//輸出賦值       
        assign data_out1 = datar1;
        assign data_out2 = datar2;
        assign data_out3 = datar3;
        assign data_out4 = datar4;
//數(shù)據(jù)選擇器     
//小數(shù)點(diǎn)顯示位數(shù)選擇     轉(zhuǎn)換數(shù)據(jù)選擇
    always@(posedge clk50)//0.02us 一次
        begin
                    temp_data_1 = int_in1;   
                    temp_data_2 = int_in2;
                    temp_data_3 = dec_in1;
                    temp_data_4 = dec_in2;        
        end
//數(shù)據(jù)選擇器     數(shù)據(jù)轉(zhuǎn)換
    always@(posedge clk50)
        begin
            case(temp_data_1)//gfedcba
            4'b0000:datar1 = 7'b1000000;//0
            4'b0001:datar1 = 7'b1111001;
            4'b0010:datar1 = 7'b0100100;
            4'b0011:datar1 = 7'b0110000;
            4'b0100:datar1 = 7'b0011001;
            4'b0101:datar1 = 7'b0010010;
            4'b0110:datar1 = 7'b0000010;
            4'b0111:datar1 = 7'b1111000;
            4'b1000:datar1 = 7'b0000000;
            4'b1001:datar1 = 7'b0010000;
            endcase
        end
    always@(posedge clk50)
        begin
            case(temp_data_2)//gfedcba
            4'b0000:datar2 = 7'b1000000;//0
            4'b0001:datar2 = 7'b1111001;
            4'b0010:datar2 = 7'b0100100;
            4'b0011:datar2 = 7'b0110000;
            4'b0100:datar2 = 7'b0011001;
            4'b0101:datar2 = 7'b0010010;
            4'b0110:datar2 = 7'b0000010;
            4'b0111:datar2 = 7'b1111000;
            4'b1000:datar2 = 7'b0000000;
            4'b1001:datar2 = 7'b0011000;
            endcase
        end
    always@(posedge clk50)
        begin
            case(temp_data_3)//gfedcba
            4'b0000:datar3 = 7'b1000000;//0
            4'b0001:datar3 = 7'b1111001;
            4'b0010:datar3 = 7'b0100100;
            4'b0011:datar3 = 7'b0110000;
            4'b0100:datar3 = 7'b0011001;
            4'b0101:datar3 = 7'b0010010;
            4'b0110:datar3 = 7'b0000010;
            4'b0111:datar3 = 7'b1111000;
            4'b1000:datar3 = 7'b0000000;
            4'b1001:datar3 = 7'b0011000;
            endcase
        end
    always@(posedge clk50)
       begin
           case(temp_data_4)//gfedcba
           4'b0000:datar4 = 7'b1000000;//0
           4'b0001:datar4 = 7'b1111001;
           4'b0010:datar4 = 7'b0100100;
           4'b0011:datar4 = 7'b0110000;
           4'b0100:datar4 = 7'b0011001;
           4'b0101:datar4 = 7'b0010010;
           4'b0110:datar4 = 7'b0000010;
           4'b0111:datar4 = 7'b1111000;
           4'b1000:datar4 = 7'b0000000;
           4'b1001:datar4 = 7'b0011000;
           endcase
       end       
endmodule

3.5、DHT11控制模塊

? ? ? ? DHT11的控制主要有四個(gè)重點(diǎn):

3.5.1、上升、下降沿的判定

? ? ? ? 通過(guò)兩個(gè)指示信號(hào)來(lái)實(shí)現(xiàn),代碼如下:

//通過(guò)dht11的上升下降沿來(lái)控制步進(jìn)次數(shù),確保在輸入一個(gè)字節(jié)是bitcnt等累加器只會(huì)加一次,同時(shí)控制判別器在電平下降時(shí)才進(jìn)行判斷
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)//復(fù)位是兩個(gè)都是1
		begin
			dht11_reg1 <= 1'b1;
			dht11_reg2 <= 1'b1;
		end
	else 
		begin
			dht11_reg1 <= dht11;//讀入數(shù)據(jù),非上升下降沿時(shí),二者相等,pos、neg均為0,
			//上升沿:reg1 = 1,reg2 = 0,pos = 1,neg = 0;
			//下降沿:reg1 = 0,reg2 = 1,pos = 0,neg = 1;
			dht11_reg2 <= dht11_reg1;//reg2 = reg1
		end
end
assign dht11_pos = (dht11_reg1) & (~dht11_reg2);//posedge,時(shí)鐘上升沿
assign dht11_neg = (~dht11_reg1) & (dht11_reg2);//negedge,時(shí)鐘下降沿

3.5.2、端口IO狀態(tài)控制

? ? ? ? 主機(jī)僅在前兩個(gè)階段生成開(kāi)始指示信號(hào)是控制端口,其他階段僅作為接收端。

????????IO狀態(tài)的控制可以通過(guò)對(duì)dht11進(jìn)行賦值來(lái)實(shí)現(xiàn),當(dāng)主機(jī)輸出時(shí)dht11為具體值,當(dāng)輔機(jī)輸出時(shí)dht11為未知量1'bz

? ? ? ? 代碼如下:

//數(shù)值判定 IO狀態(tài) 與 輸出值
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)begin
		dht11_en <= 1'b0;
		dht11_out <= 1'b1;
		end
    else if(state == WAIT_1S)//等待系統(tǒng)穩(wěn)定
    begin
        dht11_en <= 1'b1;
        dht11_out <= 1'b1;
    end
	else if(state == START)//wait 1s or start 
	begin
		dht11_en <= 1'b1;
		dht11_out <= 1'b0;
		if(cnt_us ==  LOW_18MS_MAX)
		  dht11_out <= 1'b1;
	end	  
	else //其他狀態(tài)
	begin
		dht11_en <= 1'b0;	
		dht11_out <=1'b0;
    end
end
//賦值
assign dht11 = dht11_en ? dht11_out : 1'bz;

3.5.3、狀態(tài)判斷

? ? ? ? 狀態(tài)判斷主要通過(guò)兩個(gè)計(jì)數(shù)器進(jìn)行,一個(gè)記錄高電平以及非工作時(shí)間、一個(gè)記錄低電平時(shí)間。狀態(tài)轉(zhuǎn)換的判定通過(guò)上升、下降沿,計(jì)數(shù)器取值來(lái)進(jìn)行,每當(dāng)狀態(tài)進(jìn)行轉(zhuǎn)換,計(jì)數(shù)器清零一次。

? ? ? ? 計(jì)數(shù)器控制代碼:

//DHT11狀態(tài)變量控制	
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)//復(fù)位
		begin
			cnt_low = 20'd0;
			cnt_us  = 20'd0;
		end
	else
	begin
		case(state)
			WAIT_1S:begin//初始狀態(tài),
				if(cnt_us == WAIT_1S_MAX)//若滿足時(shí)間1s
					cnt_us = 20'd0;
				else //not 到1s時(shí),每1us cnt us+1,要加1E6次
					cnt_us = cnt_us + 1'b1;
			end
            START  :begin//主機(jī)拉低頻率18ms
				if(cnt_us == LOW_18MS_MAX)//在清零后cnt us 重新開(kāi)始計(jì)數(shù),直到到達(dá)18ms
					cnt_us = 20'd0;
				else 
					cnt_us = cnt_us + 1'b1;
			end
            DLY_1  :begin//等待從機(jī)發(fā)出信號(hào),延時(shí)30us后 cntus清零
				if(cnt_us == 20'd29)
					cnt_us = 20'd0;
				else 
					cnt_us = cnt_us + 1'b1;
			end
            REPLY  :begin//從機(jī)發(fā)射響應(yīng)信號(hào)
				if(dht11_pos == 1'b1 && (cnt_low > 80))//從機(jī)相應(yīng)80us后,清零、進(jìn)入下一狀態(tài)
					begin
						cnt_low = 20'd0;
						cnt_us  = 20'd0;
					end
				else if(dht11 == 1'b0)//DATA為低電平,但為滿足狀態(tài),持續(xù)計(jì)數(shù)
					begin
						cnt_low = cnt_low + 1'b1;//低電平時(shí)間計(jì)數(shù)
						cnt_us  = cnt_us + 1'b1;//時(shí)間計(jì)數(shù)
					end
				else if(cnt_us > 1000)//若超過(guò)1ms,歸零,重新開(kāi)始
					begin
						cnt_low <= 20'd0;
						cnt_us  <= 20'd0;
					end
				else //系統(tǒng)不穩(wěn)定,計(jì)時(shí)但是不記錄低電平時(shí)間
					begin
						cnt_low = cnt_low;
						cnt_us  = cnt_us + 1'b1;
					end
			end
            DLY_2  :begin//等待
				if(dht11_neg == 1'b1 && (cnt_us > 80))//拉高80us響應(yīng)后,進(jìn)入讀取階段
					cnt_us = 20'd0;
				else 
					cnt_us  = cnt_us + 1'b1;
			end
            RD_DATA:begin//傳輸信號(hào)數(shù)據(jù)
				if(dht11_neg == 1'b1 || dht11_pos == 1'b1)//df與dr均為1時(shí)歸零(電平變化時(shí))
					begin 
					cnt_us  = 1'b0;
					end
				else 
					cnt_us = cnt_us + 1'b1;//計(jì)時(shí)
			end
			default://其他情況歸零
				begin
						cnt_low = 20'd0;
						cnt_us  = 20'd0;
				end
		endcase
	end
end

????????狀態(tài)控制代碼:

//狀態(tài)控制,控制變量在后續(xù)模塊
always@(posedge clk_us or negedge sys_rst)//微妙時(shí)鐘或復(fù)位
begin
	if(sys_rst)//rst = 0
		state <= WAIT_1S; //等待1s,初始狀態(tài)為state = wait 1s
	else 
	begin
		case(state)
		 WAIT_1S:begin
		 	if(cnt_us == WAIT_1S_MAX)//1s后,state = start,同時(shí)cnt us清零
		 		state = START;
		 	else 
		 		state = WAIT_1S;
		 end
		 START	:begin//主機(jī)發(fā)出開(kāi)始信號(hào)
		 	if(cnt_us ==  LOW_18MS_MAX)//到達(dá)18ms后cnt us清零,進(jìn)入等待1狀態(tài)
		 		state = DLY_1; 
		 	else 
		 		state =  START;
		 end
		 DLY_1  :begin//拉高30us表示結(jié)束
		 	if(cnt_us == 20'd30)//10us后進(jìn)入從機(jī)相應(yīng)狀態(tài)
		 		state = REPLY;
		 	else
		 		state = DLY_1;
		 end
		 REPLY  :begin//從機(jī)回應(yīng)
		 	if(dht11_pos == 1'b1 && (cnt_low > 80))//低電平計(jì)數(shù)80us以上,進(jìn)入等待2狀態(tài),等待傳感器數(shù)據(jù)
		 		state = DLY_2;
		 	else if(cnt_us > 1000)//表示等待了1MS,重新開(kāi)始
		 		state = START;
		 	else 
		 		state = REPLY;
		 end
		 DLY_2  :begin//拉高80us后進(jìn)入數(shù)據(jù)讀取
		 	if(dht11_neg == 1'b1 && cnt_us >80)
		 		state = RD_DATA;
		 	else 
		 		state = DLY_2;
		 end
		 RD_DATA:begin
		 	if(bit_cnt == 40 && dht11_pos == 1'b1)//讀取完40bit數(shù)據(jù)后重新開(kāi)始
		 		state = START;//讀完后立刻返回開(kāi)始
		    else//否則持續(xù)進(jìn)行 	
		 		state = RD_DATA;
		 end
		default:state = WAIT_1S;
		endcase
	end
end

3.5.4、數(shù)據(jù)讀入

? ? ? ? 代碼如下:

//依次對(duì)data——temp寫(xiě)入信號(hào)數(shù)據(jù),輸出data-temp
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)
		data_temp <= 40'd0;
	else if(state == RD_DATA && dht11_neg == 1'b1 && cnt_us< 50 ) //下降沿是出發(fā),確保高點(diǎn)平占時(shí)完全被記錄
		data_temp[39 - bit_cnt] <= 1'b0; //DHT11先輸出高位,因此從高位向低位依次賦值
	else if(state == RD_DATA && dht11_neg == 1'b1 && cnt_us > 50)
		data_temp[39 - bit_cnt] <= 1'b1;//小于50us當(dāng)成0,大于50us當(dāng)成1
	else 
		data_temp <= data_temp;
end

//數(shù)據(jù)校驗(yàn)和賦值,輸出data
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)
		data <= 32'd0;
	else if(data_temp[7:0] == data_temp[39:32] + data_temp[31:24] + data_temp[23:16] + data_temp[15:8])
		data <= data_temp[39:8];//校驗(yàn)位無(wú)誤時(shí)將數(shù)據(jù)賦值給data
	else 
		data <= data;
end

3.5.5、完整代碼

? ? ? ? 第一組:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/11 15:49:57
// Design Name: 
// Module Name: dht11_ctrl
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module dht11_ctrl(sys_clk,sys_rst,data_flag,dht11,data_out, test_leds);
	
	input  				sys_clk;//clk-50Mhz
	input 				sys_rst;//rst,觸發(fā)為1
	input 				data_flag;//控制輸出溫度還是濕度
	inout 				dht11;//既可輸入又可輸出,即為DATA線	
	output 	   [15:0]	data_out;//輸出16位信號(hào)
	output     [3:0] test_leds;
	
//狀態(tài)定義
	parameter          WAIT_1S	 =  6'b000_001,//上電等待1s狀態(tài)
						START    =  6'b000_010,//主機(jī)拉低20ms,發(fā)送開(kāi)始信號(hào)狀態(tài)
						DLY_1    =  6'b000_100,//等待從機(jī)答應(yīng)
						REPLY    =  6'b001_000,//從機(jī)對(duì)主機(jī)發(fā)出發(fā)送信號(hào)
						DLY_2    =  6'b010_000,//等待主機(jī)回應(yīng)
						RD_DATA  =  6'b100_000;//開(kāi)始傳輸數(shù)據(jù)
						
	parameter			WAIT_1S_MAX	= 32'd999_999,
						LOW_18MS_MAX = 20'd19_999;
		
	wire 				dht11_pos;
	wire				dht11_neg;
		
    reg 				clk_us;		
	reg 	  [4:0]		cnt;//微妙時(shí)鐘計(jì)數(shù)器
	reg 	  [5:0]		state;
	reg 	  [19:0]	cnt_us;//微秒計(jì)時(shí)器
	reg 	  [19:0]	cnt_low;//低電平計(jì)時(shí)器
	reg 				dht11_reg1;//時(shí)鐘沿計(jì)數(shù)器
	reg 				dht11_reg2;//時(shí)鐘沿計(jì)數(shù)器
	reg 	  [5:0]		bit_cnt;//數(shù)據(jù)寫(xiě)入計(jì)數(shù)器
	reg  	  [39:0]	data_temp;//全部數(shù)據(jù)
	reg 	  [31:0]	data;//校驗(yàn)后數(shù)據(jù)
	reg 				dht11_en;
	reg 				dht11_out;
	reg    [3:0] led;
//微秒時(shí)鐘1,一個(gè)周期0.5us
always@(posedge sys_clk or negedge sys_rst)
begin//一個(gè)周期為25時(shí)鐘周期,0.02*25=0.5us,一個(gè)周期0.5us
	if(sys_rst)
		cnt <= 5'd0;
	else if(cnt == 5'd24)//微秒計(jì)數(shù)器
		cnt <= 5'd0;
	else 
		cnt <= cnt + 1'b1;
end
//微秒時(shí)鐘2,由cnt控制
always@(posedge sys_clk or negedge sys_rst)
begin
	if(sys_rst)
		clk_us <= 1'b0;
	else if(cnt== 5'd24)//將cnt-us換為cnt,此時(shí)一個(gè)沒(méi)0.5us翻轉(zhuǎn)一次,clk-us一個(gè)周期為1us
		clk_us <= ~ clk_us;
	else 
		clk_us <= clk_us;
end

//狀態(tài)控制,控制變量在后續(xù)模塊
always@(posedge clk_us or negedge sys_rst)//微妙時(shí)鐘或復(fù)位
begin
	if(sys_rst)//rst = 0
		state <= WAIT_1S; //等待1s,初始狀態(tài)為state = wait 1s
	else 
	begin
		case(state)
		 WAIT_1S:begin
		 	if(cnt_us == WAIT_1S_MAX)//1s后,state = start,同時(shí)cnt us清零
		 		state = START;
		 	else 
		 		state = WAIT_1S;
		 end
		 START	:begin//主機(jī)發(fā)出開(kāi)始信號(hào)
		 	if(cnt_us ==  LOW_18MS_MAX)//到達(dá)18ms后cnt us清零,進(jìn)入等待1狀態(tài)
		 		state = DLY_1; 
		 	else 
		 		state =  START;
		 end
		 DLY_1  :begin//拉高30us表示結(jié)束
		 	if(cnt_us == 20'd30)//10us后進(jìn)入從機(jī)相應(yīng)狀態(tài)
		 		state = REPLY;
		 	else
		 		state = DLY_1;
		 end
		 REPLY  :begin//從機(jī)回應(yīng)
		 	if(dht11_pos == 1'b1 && (cnt_low > 80))//低電平計(jì)數(shù)80us以上,進(jìn)入等待2狀態(tài),等待傳感器數(shù)據(jù)
		 		state = DLY_2;
		 	else if(cnt_us > 1000)//表示等待了1MS,重新開(kāi)始
		 		state = START;
		 	else 
		 		state = REPLY;
		 end
		 DLY_2  :begin//拉高80us后進(jìn)入數(shù)據(jù)讀取
		 	if(dht11_neg == 1'b1 && cnt_us >80)
		 		state = RD_DATA;
		 	else 
		 		state = DLY_2;
		 end
		 RD_DATA:begin
		 	if(bit_cnt == 40 && dht11_pos == 1'b1)//讀取完40bit數(shù)據(jù)后重新開(kāi)始
		 		state = START;//讀完后立刻返回開(kāi)始
		    else//否則持續(xù)進(jìn)行 	
		 		state = RD_DATA;
		 end
		default:state = WAIT_1S;
		endcase
	end
end

//DHT11狀態(tài)變量控制	
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)//復(fù)位
		begin
			cnt_low = 20'd0;
			cnt_us  = 20'd0;
		end
	else
	begin
		case(state)
			WAIT_1S:begin//初始狀態(tài),
				if(cnt_us == WAIT_1S_MAX)//若滿足時(shí)間1s
					cnt_us = 20'd0;
				else //not 到1s時(shí),每1us cnt us+1,要加1E6次
					cnt_us = cnt_us + 1'b1;
			end
            START  :begin//主機(jī)拉低頻率18ms
				if(cnt_us == LOW_18MS_MAX)//在清零后cnt us 重新開(kāi)始計(jì)數(shù),直到到達(dá)18ms
					cnt_us = 20'd0;
				else 
					cnt_us = cnt_us + 1'b1;
			end
            DLY_1  :begin//等待從機(jī)發(fā)出信號(hào),延時(shí)30us后 cntus清零
				if(cnt_us == 20'd29)
					cnt_us = 20'd0;
				else 
					cnt_us = cnt_us + 1'b1;
			end
            REPLY  :begin//從機(jī)發(fā)射響應(yīng)信號(hào)
				if(dht11_pos == 1'b1 && (cnt_low > 80))//從機(jī)相應(yīng)80us后,清零、進(jìn)入下一狀態(tài)
					begin
						cnt_low = 20'd0;
						cnt_us  = 20'd0;
					end
				else if(dht11 == 1'b0)//DATA為低電平,但為滿足狀態(tài),持續(xù)計(jì)數(shù)
					begin
						cnt_low = cnt_low + 1'b1;//低電平時(shí)間計(jì)數(shù)
						cnt_us  = cnt_us + 1'b1;//時(shí)間計(jì)數(shù)
					end
				else if(cnt_us > 1000)//若超過(guò)1ms,歸零,重新開(kāi)始
					begin
						cnt_low <= 20'd0;
						cnt_us  <= 20'd0;
					end
				else //系統(tǒng)不穩(wěn)定,計(jì)時(shí)但是不記錄低電平時(shí)間
					begin
						cnt_low = cnt_low;
						cnt_us  = cnt_us + 1'b1;
					end
			end
            DLY_2  :begin//等待
				if(dht11_neg == 1'b1 && (cnt_us > 80))//拉高80us響應(yīng)后,進(jìn)入讀取階段
					cnt_us = 20'd0;
				else 
					cnt_us  = cnt_us + 1'b1;
			end
            RD_DATA:begin//傳輸信號(hào)數(shù)據(jù)
				if(dht11_neg == 1'b1 || dht11_pos == 1'b1)//df與dr均為1時(shí)歸零(電平變化時(shí))
					begin 
					cnt_us  = 1'b0;
					end
				else 
					cnt_us = cnt_us + 1'b1;//計(jì)時(shí)
			end
			default://其他情況歸零
				begin
						cnt_low = 20'd0;
						cnt_us  = 20'd0;
				end
		endcase
	end
end

reg ct;
always@(posedge clk_us)
    begin
    if(cnt_us == 20'b1000)
        ct = 1;
    if(ct == 1)
        led[0] = 1;
    else if(ct == 0)
        led[0] = 0;
    end
//通過(guò)dht11的上升下降沿來(lái)控制步進(jìn)次數(shù),確保在輸入一個(gè)字節(jié)是bitcnt等累加器只會(huì)加一次,同時(shí)控制判別器在電平下降時(shí)才進(jìn)行判斷
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)//復(fù)位是兩個(gè)都是1
		begin
			dht11_reg1 <= 1'b1;
			dht11_reg2 <= 1'b1;
		end
	else 
		begin
			dht11_reg1 <= dht11;//讀入數(shù)據(jù),非上升下降沿時(shí),二者相等,pos、neg均為0,
			//上升沿:reg1 = 1,reg2 = 0,pos = 1,neg = 0;
			//下降沿:reg1 = 0,reg2 = 1,pos = 0,neg = 1;
			dht11_reg2 <= dht11_reg1;//reg2 = reg1
		end
end
assign dht11_pos = (dht11_reg1) & (~dht11_reg2);//posedge,時(shí)鐘上升沿
assign dht11_neg = (~dht11_reg1) & (dht11_reg2);//negedge,時(shí)鐘下降沿

//數(shù)據(jù)位數(shù)控制,輸出bit-cnt
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)
		bit_cnt <= 6'd0;
	else if(bit_cnt == 40 && dht11_pos == 1'b1)
		bit_cnt <= 6'd0;
	else if((state == RD_DATA) && (dht11_neg == 1'b1))
		bit_cnt <= bit_cnt + 1'b1;//當(dāng)狀態(tài)為寫(xiě)入且dht11-neg = 1時(shí),bit—cnt依次變化
	else
		bit_cnt <= bit_cnt;
end

//依次對(duì)data——temp寫(xiě)入信號(hào)數(shù)據(jù),輸出data-temp
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)
		data_temp <= 40'd0;
	else if(state == RD_DATA && dht11_neg == 1'b1 && cnt_us< 50 ) //下降沿是出發(fā),確保高點(diǎn)平占時(shí)完全被記錄
		data_temp[39 - bit_cnt] <= 1'b0; //DHT11先輸出高位,因此從高位向低位依次賦值
	else if(state == RD_DATA && dht11_neg == 1'b1 && cnt_us > 50)
		data_temp[39 - bit_cnt] <= 1'b1;//小于50us當(dāng)成0,大于50us當(dāng)成1
	else 
		data_temp <= data_temp;
end
always@(posedge clk_us)
    begin
        if(data_temp == 0)
            led[1] = 1;
    end
//數(shù)據(jù)校驗(yàn)和賦值,輸出data
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)
		data <= 32'd0;
	else if(data_temp[7:0] == data_temp[39:32] + data_temp[31:24] + data_temp[23:16] + data_temp[15:8])
		data <= data_temp[39:8];//校驗(yàn)位無(wú)誤時(shí)將數(shù)據(jù)賦值給data
	else 
		data <= data;
end

//IO控制
always@(posedge clk_us or negedge sys_rst)
begin
	if(sys_rst)begin
		dht11_en <= 1'b0;
		dht11_out <= 1'b1;
		end
    else if(state == WAIT_1S)//等待系統(tǒng)穩(wěn)定
    begin
        dht11_en <= 1'b1;
        dht11_out <= 1'b1;
    end
	else if(state == START)//wait 1s or start 
	begin
		dht11_en <= 1'b1;
		dht11_out <= 1'b0;
		if(cnt_us ==  LOW_18MS_MAX)
		  dht11_out <= 1'b1;
	end	  
	else //其他狀態(tài)
	begin
		dht11_en <= 1'b0;	
		dht11_out <=1'b0;
    end
end

assign dht11 = dht11_en ? dht11_out : 1'bz;
//當(dāng)dht11en = 1時(shí),dht11 = dht11 out,當(dāng)en = 0 時(shí),dht11 = 未知
//start時(shí)dht11 受主機(jī)控制,等于0--低電平
//其他時(shí)候,dht11為未知量,由輔機(jī)控制
reg [15:0] datar;
always@(posedge clk_us or negedge sys_rst)//溫濕度選擇器,輸出data-out
begin
	if(sys_rst)
		datar <= 16'd0;//十六位
	else if(data_flag == 1'b0)//data為32位 整溫-小溫-整濕-小濕
		datar <= data[31:16];//濕度數(shù)據(jù)
	else if(data_flag == 1'b1)
		datar <= data[15:0];//濕度數(shù)據(jù)
	else 
		datar <= data_out;
end
assign data_out = datar;
always@(posedge clk_us)
    begin
        if(data == 0 /*&& data_temp != 0*/)
            led[2] = 1;
        else if(datar == 0)
            led[3] = 1;
    end

endmodule

? ? ? ? 第二組:

`timescale 1ns / 1ps

module dht11_2(
	input	sys_clk		,	//system clock
	input	sys_rst_n	,	//system reset negedge	
	inout	dht11_data	,	//dht11 inout port
	output	reg	[39:0]	t_h_data
);
//tate code
parameter	WAIT			=	6'b000_001,//wait state 2s
			START			=	6'b000_010,//make bus low 20ms
			WAIT_RES		=	6'b000_100,//wait respond
			RES_LOW			=	6'b001_000,//respond low
			RES_HIGH		=	6'b010_000,//respong high
			REC_DATA		=	6'b100_000;//receive datas
//time parameter
parameter	CNT_2S_MAX		=	100_000_000	,
			CNT_20MS_MAX	=	1_000_000	,
			CNT_1US_MAX		=	50			;
//state define
reg	[5:0] 	state_cur;//current state
reg [5:0] 	state_nex;//next state
//lag define
wire		end_2s		;	//wait 2s end
wire		end_20ms    ;	//wait 20ms end
wire		res_ok      ;	//respond ok
wire		res_no      ;	//no respond
wire		end_res_low ;	//wait respond low end 83us
wire		end_res_high;	//wait respond high end 87us
wire		end_rec     ;	//data receive end 40bits
//dht11
reg			dht11_data_r1;
reg			dht11_data_r2;
wire		dht11_posedge;
wire		dht11_negedge;
reg			data;
reg			output_en;
wire		check;//校驗(yàn)			
reg	[39:0]	t_h_data_temp;//溫濕度數(shù)據(jù)
//計(jì)數(shù)器
reg	[26:0]	cnt_2s;
reg [19:0]	cnt_20ms;
reg	[6:0]	cnt_nus;
reg	[5:0]	cnt_1us;
reg			cnt_us_rst;
reg	[5:0]	cnt_bit;

//條件判斷
assign	end_2s 			= (state_cur == WAIT && cnt_2s == CNT_2S_MAX - 1'b1) ? 1'b1 : 1'b0;
assign	end_20ms 		= (state_cur == START && cnt_20ms == CNT_20MS_MAX - 1'b1) ? 1'b1 : 1'b0;
assign	res_ok 			= (state_cur == WAIT_RES && cnt_nus < 20 && dht11_negedge) ? 1'b1 : 1'b0;
assign 	res_no 			= (state_cur == WAIT_RES && cnt_nus > 20) ? 1'b1 : 1'b0;
assign 	end_res_low 	= (state_cur == RES_LOW && cnt_nus > 70 && dht11_posedge) ? 1'b1 : 1'b0;
assign 	end_res_high 	= (state_cur == RES_HIGH && cnt_nus > 70 && dht11_negedge) ? 1'b1 : 1'b0;
assign	end_rec 		= (state_cur == REC_DATA && cnt_bit >= 40) ? 1'b1 : 1'b0;

//dht11傳輸上升、下降延判斷
assign dht11_posedge = dht11_data_r1 & ~dht11_data_r2;
assign dht11_negedge = ~dht11_data_r1 & dht11_data_r2;
//生成
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		dht11_data_r1 <= 1'b0;
		dht11_data_r2 <= 1'b0;
	end
	else begin
		dht11_data_r1 <= dht11_data;
		dht11_data_r2 <= dht11_data_r1;
	end
end
//信息校驗(yàn)
assign check = (t_h_data_temp[39:32]+t_h_data_temp[31:24]+
					t_h_data_temp[23:16]+t_h_data_temp[15:8] == t_h_data_temp[7:0])
					? 1'b1 : 1'b0;
//計(jì)數(shù)器群
always@(*)begin
	case(state_cur)
		WAIT		:	cnt_us_rst = 1'b1;
	    START		:	cnt_us_rst = 1'b1;
	    WAIT_RES	:	begin
			if(res_ok)
				cnt_us_rst = 1'b1;
			else
				cnt_us_rst = 1'b0;
		end
	    RES_LOW		:	begin
			if(end_res_low)
				cnt_us_rst = 1'b1;
			else
				cnt_us_rst = 1'b0;
		end
	    RES_HIGH	:	begin
			if(end_res_high)
				cnt_us_rst = 1'b1;
			else
				cnt_us_rst = 1'b0;
		end
	    REC_DATA	:	begin
			if(dht11_posedge || dht11_negedge)
				cnt_us_rst = 1'b1;
			else
				cnt_us_rst = 1'b0;
		end
		default		:cnt_us_rst = 1'b1;
	endcase
end
//cnt_2s
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_2s <= 27'd0;
	end
	else begin
		if(state_cur == WAIT)begin
			if(cnt_2s <= CNT_2S_MAX - 1'b1)
				cnt_2s <= cnt_2s + 1'b1;
			else
				cnt_2s <= cnt_2s;
		end
		else if(state_cur == REC_DATA)begin
			cnt_2s <= 27'd0;
		end
		else begin
			cnt_2s <= cnt_2s;
		end
	end
end
//cnt_20ms
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_20ms <= 20'd0;
	end
	else begin
		if(state_cur == START)begin
			if(cnt_20ms <= CNT_20MS_MAX - 1'b1)
				cnt_20ms <= cnt_20ms + 1'b1;
			else
				cnt_20ms <= cnt_20ms;
		end
		else if(state_cur == REC_DATA)begin
			cnt_20ms <= 20'd0;
		end
		else begin
			cnt_20ms <= cnt_20ms;
		end
	end
end
//cnt_1us
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_1us <= 6'd0;
	end
	else begin
		if(cnt_1us == CNT_1US_MAX - 1'b1)
			cnt_1us <= 6'd0;
		else if(cnt_us_rst)
			cnt_1us <= 6'd0;
		else
			cnt_1us <= cnt_1us + 1'b1;
	end
end
//cnt_nus
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_nus <= 7'd0;
	end
	else begin
		if(cnt_us_rst)
			cnt_nus <= 7'd0;
		else if(cnt_1us == CNT_1US_MAX - 1'b1)
			cnt_nus <= cnt_nus + 1'b1;
		else
			cnt_nus <= cnt_nus;
	end
end
//信號(hào)位數(shù)控制
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		cnt_bit <= 6'd0;
	end
	else begin
		if(state_cur == REC_DATA)begin
			if(dht11_negedge)
				cnt_bit <= cnt_bit + 1'b1;
			else
				cnt_bit <= cnt_bit;
		end
		else begin
			cnt_bit <= 6'd0;
		end
	end
end

//狀態(tài)控制1
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)
		state_cur <= WAIT;
	else
		state_cur <= state_nex;
end
//狀態(tài)控制2
always@(*)begin
	case(state_cur)
		WAIT	:begin
			if(end_2s)
				state_nex = START;	//count 2s finish 
			else
				state_nex = WAIT;
		end		
		START	:begin
			if(end_20ms)
				state_nex = WAIT_RES;//count 20ms finish 
			else
				state_nex = START;
		end			
		WAIT_RES:begin	
			if(res_ok)				//respond 
				state_nex = RES_LOW;	
			else if(res_no)			//no respond 
				state_nex = WAIT;
			else
				state_nex = WAIT_RES;
		end			
		RES_LOW	:begin
			if(end_res_low)
				state_nex = RES_HIGH;
			else
				state_nex = RES_LOW;
		end			
		RES_HIGH:begin
			if(end_res_high)
				state_nex = REC_DATA;
			else
				state_nex = RES_HIGH;
		end			
		REC_DATA:begin
			if(end_rec)
				state_nex = WAIT;
			else
				state_nex = REC_DATA;
		end		
		default	:begin
			state_nex = WAIT;
		end			
	endcase
end
//IO控制
assign dht11_data = output_en ? data : 1'bz;
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		output_en <= 1'b0;
		data <= 1'b0;
	end
	else begin
		case(state_cur)
			WAIT	 :begin
				output_en <= 1'b1;//output
				data <= 1'b1;
			end
		    START	 :begin
				output_en <= 1'b1;//output
				data <= 1'b0;
				if(end_20ms)
					data <= 1'b1;
			end
		    WAIT_RES :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
		    RES_LOW	 :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
		    RES_HIGH :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
		    REC_DATA :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
			default  :begin
				output_en <= 1'b0;//input
				data <= 1'b0;
			end
		endcase
	end
end
//寫(xiě)入1
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		t_h_data_temp <= 40'd0;
	end
	else begin
		if(state_cur == REC_DATA)begin
			if(cnt_nus > 50 && dht11_negedge)
				t_h_data_temp[39 - cnt_bit] <= 1'b1;
			else if(cnt_nus < 50 && dht11_negedge)
				t_h_data_temp[39 - cnt_bit] <= 1'b0;
			else 
				t_h_data_temp <= t_h_data_temp;
		end
		else begin
			t_h_data_temp <= t_h_data_temp;
		end
	end
end
//寫(xiě)入2
always@(posedge sys_clk or negedge sys_rst_n)begin
	if(~sys_rst_n)begin
		t_h_data <= 40'd0;
	end
	else begin
		if(state_cur == REC_DATA)begin
			if(end_rec && check)
				t_h_data <= t_h_data_temp;
			else
				t_h_data <= t_h_data;
		end
		else begin
			t_h_data <= t_h_data;
		end
	end
end
endmodule

3.6、TOP

? ? ? ? 頂層模塊需要注意兩點(diǎn):

? ? ? ? 1、若數(shù)據(jù)只是“經(jīng)過(guò)”頂層模塊或是作為賦值對(duì)象而不對(duì)其改變,則需要用wire型變量,否則將會(huì)報(bào)錯(cuò);

? ? ? ? 2、最好保持輸出位置與輸出數(shù)據(jù)的控制時(shí)序相同,千萬(wàn)不要讓輸出數(shù)據(jù)的改變快于輸出位置的改變,否則數(shù)碼管最終會(huì)顯示非理想的輸出。而非理想輸出的原因可能在于:數(shù)據(jù)轉(zhuǎn)換模塊有問(wèn)題;DHT11控制模塊有問(wèn)題;數(shù)碼管模塊有問(wèn)題。本人就因此將所有代碼從頭到尾檢查了一遍。

????????代碼如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/06/11 14:45:14
// Design Name: 
// Module Name: DHT_TOP
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module DHT_TOP(
    input sys_clk,
    input sys_rst,//觸發(fā)為1    D20
    input tap8421, 
    input key,  //D19
    inout dht11,    //V17       AR8
    output point,   //AR7
    output [3:0]num,    //A0-5
    output [6:0]abcdefg,     //AR0-6
    output [3:0]leds
    );
				
	reg        data_flag;
//顯示切換  1--溫度   0--濕度
	wire   [15:0]  data_ctrl;
	wire   [39:0]  thdata;
//不同模塊之間傳輸而不在頂層改變的變量用wire型	
//應(yīng)用時(shí)鐘  自用    輸出給dht11——ctrl  輸出給——SMG
	wire     clk50; 
//數(shù)據(jù)選擇器所用變量
	reg    [7:0]   data_hu_int;//十位濕度整數(shù)
	reg    [7:0]   data_te_int;//十位溫度整數(shù)
 	reg    [7:0]   data_hu_dec;//十位濕度小數(shù)
    reg    [7:0]   data_te_dec;//十位溫度小數(shù)         
//SMG 4個(gè)數(shù)據(jù)信號(hào)
//BTD 小數(shù)點(diǎn)內(nèi)設(shè),不需要輸入  
    reg    [7:0]   data_smg_int;   
    reg    [7:0]   data_smg_dec;
//SMG的輸入    BTD的輸出     
    wire    [3:0]    int_d1;//四位十進(jìn)制
    wire    [3:0]    int_d2;//四位十進(jìn)制
    wire    [3:0]    dec_d1;//四位十進(jìn)制
    wire    [3:0]    dec_d2;//四位十進(jìn)制    
    reg [3:0] numr;
    reg pointr;
//test
    wire [6:0] a1;
    wire [6:0] a2;
    wire [6:0] a3;
    wire [6:0] a4;
    reg [6:0] ar;
    
    assign abcdefg = ar;
    assign num = numr;
    assign point = pointr;
//dht11控制程序	
/*
dht11_ctrl dht11_ctrl
(
    .sys_clk(clk50), //input
    .sys_rst(sys_rst),//input 
    .data_flag(data_flag), //input 溫濕度選擇
    .dht11(dht11), //DHT11數(shù)據(jù) input
    .data_out(data_ctrl),//輸出數(shù)據(jù) output
    .test_leds(leds)
);
*/
//輸出控制  8421BCD TO ABCDEFG
dht11_2 dht11_2
(
    .sys_clk(clk50),
    .sys_rst_n(!sys_rst),
    .dht11_data(dht11),
    .t_h_data(thdata)
);
assign leds = int_d1;
//assign leds = dec_d1;
SMG SMG 
(
    .clk50(clk50),//in
    .rst(sys_rst),//in normal = 0
    .data_flag(data_flag),//in  0h  1t
    .int_in1(int_d1),//in   d
    .dec_in1(dec_d1),//in   d
    .int_in2(int_d2),//in   d
    .dec_in2(dec_d2),//in   d
    .data_out1(a1),
    .data_out2(a2),
    .data_out3(a3),
    .data_out4(a4)    
//out 8421bcd to abcdefg
);
//BTD   SMG TO 4 8421 BCD
BTD BTD
(
    .clk50(clk50),
   .int_in(data_smg_int[7:0]),
   .dec_in(data_smg_dec[7:0]),
    //.int_in('b01010100),//
    //.dec_in('b00010101),//
    //DHT11有效測(cè)試范圍不過(guò)100,因此僅前7位信號(hào)有效
    .int_out1(int_d1),
    .dec_out1(dec_d1),
    .int_out2(int_d2),
    .dec_out2(dec_d2),
    .rst(sys_rst)
);
//溫濕度切換
//通過(guò)按鍵的key信號(hào),轉(zhuǎn)換data_out輸出的是濕度還是溫度,沒(méi)按一次按鈕,轉(zhuǎn)換一次
always@(posedge clk50 or negedge sys_rst)
begin
	if(sys_rst)
		data_flag <= 1'b0;
	else if(key == 1'b1)
		data_flag <= ~data_flag;
	else 
		data_flag <= data_flag;
end
//溫濕度選擇器,輸出data-out
always@(posedge clk50 or negedge sys_rst)
begin
	if(sys_rst)
	   begin
	   end
	else if(data_flag == 1'b0)//data為32位 整溫-小溫-整濕-小濕
        //data_flag為0時(shí)data_crtl為濕度數(shù)據(jù)
        begin
		    data_hu_int <= thdata[39:32];//濕度數(shù)據(jù)
	  	    data_hu_dec <= thdata[31:24];//濕度數(shù)據(jù)
	    end
	else if(data_flag == 1'b1)//te
	    begin
		    data_te_int <= thdata[23:16];//溫度數(shù)據(jù)
            data_te_dec <= thdata[15:8];//溫度數(shù)據(jù)
 
        end
end
//數(shù)據(jù)選擇器1
always@(posedge clk50)
    begin
        if(sys_rst)begin
            numr = 4'b1111;
            end
         else if(numr == 4'b1000)
            numr = 4'b0001;
         else
            numr = numr <<1;
     end
always@(posedge clk50)
    begin 
        case(numr)
        4'b0001:begin ar = a1;
            end
        4'b0010:begin ar = a2;
            end
        4'b0100:begin ar = a3;
            end
        4'b1000:begin ar = a4;
            end
        4'b1111:begin ar = 7'b0111111;
            end
        endcase
    end
always@(posedge clk50)
    begin
        if(numr == 4'b0010)
            pointr = 1'b0;
        else
            pointr = 1'b1;
    end
 
//smg賦值
always@(posedge clk50 or negedge sys_rst)
    begin
        if(sys_rst)
            begin
                data_smg_int <= 8'b0000_0000; 
                data_smg_dec <= 8'b0000_0000;                
            end
        else if (tap8421)
            begin 
                 data_smg_int <= 8'b0101_0100;//84 
                 data_smg_dec <= 8'b0001_0101;//21          
            end         
        else if(data_flag == 1'b1 && !tap8421)//溫度
            begin
                data_smg_int <= data_te_int;
                data_smg_dec <= data_te_dec; 
            end
         else if(data_flag == 1'b0 && !tap8421)//濕度
            begin
                data_smg_int <= data_hu_int; 
                data_smg_dec <= data_hu_dec;                
            end   
     end
        
//時(shí)鐘
clk_wiz_0 clk0(
.reset(1'b0),
.clk_in1(sys_clk),
.clk50(clk50)
);

endmodule

3.7、結(jié)果展示

? ? ? ? 濕度:37%

vivado dds,FPGA-Vivado學(xué)習(xí),fpga開(kāi)發(fā),筆記????????

? ? ? ? ?溫度:28.09

vivado dds,FPGA-Vivado學(xué)習(xí),fpga開(kāi)發(fā),筆記

?????????城市參考值:

vivado dds,FPGA-Vivado學(xué)習(xí),fpga開(kāi)發(fā),筆記

? ? ? ? ?可以看到實(shí)際數(shù)據(jù)與城市參考值基本上差不多,同時(shí)證明在旁邊放一桶水確實(shí)能夠提高空氣濕度。

?

到了這里,關(guān)于FPGA實(shí)驗(yàn)筆記_Vivado:DDS信號(hào)發(fā)生器;數(shù)碼管;基于DHT11的溫濕度傳感器的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 基于AD9767高速DAC的DDS信號(hào)發(fā)生器(Verilog&Vivado)

    基于AD9767高速DAC的DDS信號(hào)發(fā)生器(Verilog&Vivado)

    基于AD9767高速DAC的DDS信號(hào)發(fā)生器 提示:以下是本篇文章正文內(nèi)容,下面案例可供參考 1.做一個(gè)雙通道的信號(hào)發(fā)生器; 2.簡(jiǎn)單調(diào)整每個(gè)通道的頻率輸出; 3.能夠調(diào)整每個(gè)通道的輸出相位; 4.能夠輸出正弦波,三角波,方波。 代碼如下(示例): 代碼如下(示例): 【附件:】

    2024年02月06日
    瀏覽(56)
  • FPGA之簡(jiǎn)易DDS信號(hào)發(fā)生器設(shè)計(jì)

    FPGA之簡(jiǎn)易DDS信號(hào)發(fā)生器設(shè)計(jì)

    設(shè)計(jì)一個(gè)能產(chǎn)生頻率可變、相位可調(diào)的能產(chǎn)生正弦波、三角波、方波、鋸齒波的信號(hào)發(fā)生器。 DDS 是直接數(shù)字式頻率合成器(Direct Digital Synthesizer)的英文縮寫(xiě),是一項(xiàng)關(guān)鍵的數(shù)字化技術(shù)。與傳統(tǒng)的頻率合成器相比,DDS 具有低成本、低功耗、高分辨率和快速轉(zhuǎn)換時(shí)間等優(yōu)點(diǎn),

    2024年02月02日
    瀏覽(18)
  • 基于FPGA的簡(jiǎn)易 DDS 信號(hào)發(fā)生器的設(shè)計(jì)

    基于FPGA的簡(jiǎn)易 DDS 信號(hào)發(fā)生器的設(shè)計(jì)

    DDS 是直接數(shù)字式頻率合成器(Direct Digital Synthesizer)的英文縮寫(xiě),是一項(xiàng)關(guān)鍵的數(shù)字化技術(shù)。與傳統(tǒng)的頻率合成器相比, DDS 具有低成本、低功耗、高分辨率和快速轉(zhuǎn)換時(shí)間等優(yōu)點(diǎn),廣泛使用在電信與電子儀器領(lǐng)域,是實(shí)現(xiàn)設(shè)備全數(shù)字化的一個(gè)關(guān)鍵技術(shù)。作為設(shè)計(jì)人員,我們

    2024年02月07日
    瀏覽(41)
  • 信號(hào)發(fā)生器:Intel FPGA DDS(NCO)+雙路DAC(AD9767)輸出正余弦信號(hào)

    信號(hào)發(fā)生器:Intel FPGA DDS(NCO)+雙路DAC(AD9767)輸出正余弦信號(hào)

    Quartus18.1 小梅哥AC620開(kāi)發(fā)板+ACM9767模塊 示波器 ACM9767模塊使用的是ADI公司的AD9767芯片,14位CMOS 雙通道DAC,125Msps轉(zhuǎn)換率。 輸出形式為差分電流輸出,輸出電流滿量程范圍為可設(shè)置為 2~20mA。 AD9767的兩路DA輸出都為補(bǔ)碼形式的電流輸出IoutA和IoutB。當(dāng)AD9767數(shù)字輸入為滿量程時(shí)(DAC的

    2024年03月24日
    瀏覽(19)
  • 基于FPGA的DDS原理信號(hào)發(fā)生器設(shè)計(jì) quartusII 9.1平臺(tái) Verilog HDL語(yǔ)言編程 可產(chǎn)生正弦波

    基于FPGA的DDS原理信號(hào)發(fā)生器設(shè)計(jì) quartusII 9.1平臺(tái) Verilog HDL語(yǔ)言編程 可產(chǎn)生正弦波

    基于FPGA的DDS原理信號(hào)發(fā)生器設(shè)計(jì) quartusII 9.1平臺(tái) Verilog HDL語(yǔ)言編程 ?可產(chǎn)生正弦波、方波、鋸齒波以及三角波 ? 頻率幅度可調(diào)節(jié) ? 代碼+原理圖 在現(xiàn)代電子技術(shù)領(lǐng)域,針對(duì)各種應(yīng)用的信號(hào)發(fā)生器是一種非常核心的設(shè)備,而基于現(xiàn)場(chǎng)可編程邏輯門(mén)陣列(FPGA)的直接數(shù)字合成(

    2024年04月27日
    瀏覽(30)
  • FPGA實(shí)驗(yàn)五:信號(hào)發(fā)生器設(shè)計(jì)

    目錄 一、實(shí)驗(yàn)?zāi)康?二、設(shè)計(jì)要求 三、實(shí)驗(yàn)代碼 1.代碼原理分析 2.代碼設(shè)計(jì)思路

    2024年02月12日
    瀏覽(28)
  • DDS信號(hào)發(fā)生器(stm32+ad9850)

    DDS信號(hào)發(fā)生器(stm32+ad9850)

    正點(diǎn)原子精英板、ad9850、杜邦線 https://download.csdn.net/download/qq_45974939/87672298

    2024年02月16日
    瀏覽(36)
  • FPGA實(shí)驗(yàn)報(bào)告 Verilog HDL:7人表決器 巴克碼信號(hào)發(fā)生器 FPGA數(shù)字時(shí)鐘

    寫(xiě)在前面:本文提供以下三個(gè)任務(wù)的思路講解和代碼實(shí)現(xiàn), 如需參考引腳配置說(shuō)明,可以點(diǎn)擊下方鏈接跳轉(zhuǎn)查看完整實(shí)驗(yàn)報(bào)告 ;本實(shí)驗(yàn)使用的是Altera公司的cycloneⅢ類型的芯片。 Verilog HDL實(shí)現(xiàn):7人表決器 信號(hào)發(fā)生器 多功能數(shù)字時(shí)鐘 實(shí)驗(yàn)?zāi)繕?biāo):實(shí)現(xiàn)7人投票表決電路,支持人

    2024年02月05日
    瀏覽(26)
  • 畢設(shè)分享|基于51單片機(jī)DDS信號(hào)發(fā)生器設(shè)計(jì)

    畢設(shè)分享|基于51單片機(jī)DDS信號(hào)發(fā)生器設(shè)計(jì)

    在電子通信技術(shù)日益發(fā)展的時(shí)代潮流下,直接式(DFS)和鎖相式(PLL)已經(jīng)不能滿足生活和科研方面對(duì)于頻率技術(shù)的需求。經(jīng)過(guò)科研人員的不斷攻堅(jiān)下,直接數(shù)字頻率合成器(DDS)應(yīng)運(yùn)而生。它現(xiàn)在廣泛運(yùn)用于移動(dòng)通信、電子雷達(dá)、航天等方面。本次設(shè)計(jì)主要通過(guò)FPGA模塊+單片機(jī)最小

    2024年02月03日
    瀏覽(29)
  • 【畢業(yè)設(shè)計(jì)—DDS信號(hào)發(fā)生器】Quartus II 軟件新建工程

    【畢業(yè)設(shè)計(jì)—DDS信號(hào)發(fā)生器】Quartus II 軟件新建工程

    大學(xué)四年的時(shí)間轉(zhuǎn)瞬即逝,2023年我將迎來(lái)我的本科畢業(yè)。為了記錄自己的研究進(jìn)展,我將在這兒分享我的畢業(yè)設(shè)計(jì)進(jìn)度~~博客涉及的知識(shí)點(diǎn),如有不對(duì),歡迎大家及時(shí)糾正,共同進(jìn)步! 我安裝的是Quartus II 13.1 版本。 1.在電腦D磁盤(pán)下新建一個(gè)文件夾【DDS】,然后分別新建4個(gè)子

    2024年02月03日
    瀏覽(18)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包