久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 19741|回復(fù): 3
打印 上一主題 下一主題
收起左側(cè)

FPGA應(yīng)用—74HC595驅(qū)動流水燈程序詳解

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:91350 發(fā)表于 2015-11-1 17:39 | 只看該作者 |只看大圖 回帖獎勵 |倒序?yàn)g覽 |閱讀模式

一、設(shè)計(jì)需求

設(shè)計(jì)一個(gè)驅(qū)動74HC595芯片工作的功能模塊,并在CB哥的開發(fā)板上8盞led燈上實(shí)現(xiàn)流水燈的效果。

二、設(shè)計(jì)思路

1、74HC595介紹及分析

圖1所示為74HC595芯片的封裝及引腳分布。74HC595是由8位移位寄存器和8位三態(tài)并行輸出的D型鎖存器組成,如圖2所示。

圖1 74HC595封裝及引腳分布

圖2 74HC595邏輯圖

74HC595具有以下特征:

(1) 移位寄存器接收串行數(shù)據(jù)、提供串行或8位并行數(shù)據(jù)輸出;

(2) 移位寄存器和鎖存器擁有獨(dú)立的時(shí)鐘輸入;

(3) 移位寄存器擁有異步復(fù)位信號

圖3所示為74HC595的功能表,于是可總結(jié)為:

當(dāng)復(fù)位信號RESET為低電平時(shí),

(1) 移位寄存器輸出為低電平(包括并行和串行輸出);

(2) 當(dāng)輸出使能信號為低電平時(shí),若鎖存器時(shí)鐘上升沿到來,則最后輸出為低電平(移位寄存器輸出),否則保持不變;當(dāng)輸出使能信號為高電平時(shí),最后輸出為高阻態(tài)。

當(dāng)復(fù)位信號RESET為高電平時(shí),

(1) 當(dāng)移位時(shí)鐘上升沿到來時(shí),移位寄存器輸出與輸入內(nèi)容一樣,否則保持不變;

(2) 當(dāng)輸出使能信號為低電平時(shí),若鎖存器時(shí)鐘上升沿到來,則最后輸出與輸入內(nèi)容(移位寄存器輸出),否則保持不變;當(dāng)輸出使能信號為高電平時(shí),最后輸出為高阻態(tài)。

圖3 74HC595功能表

圖4所示為74HC595的時(shí)序圖。由時(shí)序圖可以看出,串行輸入數(shù)據(jù)在移位時(shí)鐘的上升沿被讀進(jìn)移位寄存器中;當(dāng)復(fù)位信號有效時(shí),移位寄存器被清零;在輸出使能為低電平且鎖存時(shí)鐘的上升沿時(shí),移位寄存器的值被鎖存輸出;當(dāng)輸出使能為高電平時(shí),輸出高阻態(tài)。而串行輸出接口則是輸出移位寄存器的最高位,且不受輸出使能的控制。

圖4 74HC595時(shí)序圖

本次的led流水燈設(shè)計(jì)不需要高阻態(tài),故將輸出使能始終置為低電平,同時(shí)也不需要復(fù)位信號,將其置為高電平,永不復(fù)位。此外也不需要串行輸出。在不考慮這三個(gè)信號的情況下,重新給出簡化后的74HC595時(shí)序圖,如圖5所示。這里考慮了輸入數(shù)據(jù)對移位時(shí)鐘上升沿的建立時(shí)間和保持時(shí)間,如圖6所示,由于芯片供電電壓為3.3V且當(dāng)前的室溫是在25攝氏度到85攝氏度之間,故最小建立時(shí)間和保持時(shí)間分別為50ns和5ns。而移位時(shí)鐘上升沿對鎖存時(shí)鐘上升沿的最小建立時(shí)間為70ns。

圖5 簡化后的74HC595時(shí)序圖

圖6 建立時(shí)間和保持時(shí)間要求

此外,移位時(shí)鐘的最大頻率可以是10MHz,如圖7所示。但為了滿足時(shí)序要求,移位時(shí)鐘采用5MHz即200ns,輸入數(shù)據(jù)只能在移位時(shí)鐘的下降沿改變,這里建立時(shí)間和保持時(shí)間裕量分別為50ns和95ns。鎖存時(shí)鐘也在移位時(shí)鐘的下降沿產(chǎn)生,于是建立時(shí)間裕量還有30ns。

圖7 移位時(shí)鐘最大頻率與溫度、電壓的關(guān)系

2、設(shè)計(jì)分析

如圖8所示,本設(shè)計(jì)由三個(gè)模塊組合,分別為子模塊led_ctrl、driver_74595和頂層模塊led_water,它們的作用分別為:

led_ctrl模塊 :負(fù)責(zé)產(chǎn)生流水燈顯示的數(shù)據(jù);

driver_74595模塊 :負(fù)責(zé)驅(qū)動74HC595芯片工作并發(fā)送led數(shù)據(jù);

led_water頂層模塊 :例化led_ctrl和driver_74595模塊,完成流水燈設(shè)計(jì)。

圖8 設(shè)計(jì)組織框架

至于led_ctrl模塊設(shè)計(jì)思路可參考上上篇博文“FPGA應(yīng)用(一)——流水燈”,這里主要分析driver_74595模塊的設(shè)計(jì)。該模塊采用狀態(tài)機(jī)的方案來實(shí)現(xiàn),如圖9所示。狀態(tài)機(jī)中有四個(gè)狀態(tài),分別為IDLE、CLK_L、CLK_H和FINISH。在IDLE中主要完成led數(shù)據(jù)的加載和發(fā)送;在CLK_L中產(chǎn)生移位時(shí)鐘的低電平;在CLK_H中產(chǎn)生移位時(shí)鐘的高電平和led數(shù)據(jù)的發(fā)送;在FINISH中產(chǎn)生鎖存時(shí)鐘。

圖9 74HC595驅(qū)動狀態(tài)機(jī)

三、設(shè)計(jì)實(shí)現(xiàn)

led_water頂層模塊:

/**********************************************版權(quán)申明*************************************************
**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:          led_water.v
** 創(chuàng)建者:          CrazyBird
** 創(chuàng)建日期:        2015-7-11
** 版本號:           v1.0
** 功能描述:        該模塊完成74HC595的驅(qū)動并實(shí)現(xiàn)流水燈的功能
**                   
********************************************************************************************************/
// synopsys translate_off
`timescale 1 ns / 1 ps
// synopsys translate_on
module led_water(
    rst_n,
    clk,
    shift_clock,
    lacth_clock,
    led_dout
    );
    //******************************************************************************
    //                                參數(shù)定義               
    //******************************************************************************
    //  修改以下參數(shù)以滿足需求
    parameter   CLK_CYCLE = 20;                                        //   時(shí)鐘周期,單位ns
    parameter   LED_WIDTH = 8;                                         //   led數(shù)據(jù)位寬
    //  修改以上參數(shù)以滿足需求
    
    //******************************************************************************
    //                            輸入/輸出端口定義
    //******************************************************************************
    input                           rst_n;                             //   全局復(fù)位信號
    input                           clk;                               //   全局時(shí)鐘信號,50MHz
    output                          shift_clock;                       //   74HC595的移位時(shí)鐘信號
    output                          lacth_clock;                       //   74HC595的鎖存時(shí)鐘信號
    output                          led_dout;                          //   74HC595的串行數(shù)據(jù)輸入
    
    //******************************************************************************
    //                               變量定義
    //******************************************************************************
    wire        [LED_WIDTH-1:0]     led_data;                          //   led燈數(shù)據(jù)輸出
    wire                            led_flag;                          //   led燈數(shù)據(jù)輸出標(biāo)志
    
    //******************************************************************************
    //                               模塊連接
    //******************************************************************************
    //  例化led_ctrl模塊
    led_ctrl #(
        .CLK_CYCLE(CLK_CYCLE),
        .LED_WIDTH(LED_WIDTH)
    )
    u_led_ctrl(
        .rst_n      (   rst_n       ),
        .clk        (   clk         ),
        .led_data   (   led_data    ),
        .led_flag   (   led_flag    )
    );
    
    //  例化driver_74595模塊
    driver_74595 #(
        .CLK_CYCLE(CLK_CYCLE),
        .LED_WIDTH(LED_WIDTH)
    )
    u_driver_74595(
        .rst_n          (   rst_n       ),
        .clk            (   clk         ),
        .led_data       (   led_data    ),
        .led_flag       (   led_flag    ),
        .shift_clock    (   shift_clock ),
        .latch_clock    (   lacth_clock ),
        .led_dout       (   led_dout    )
    );
    
    //******************************************************************************

endmodule
//*********************************************文件結(jié)束*****************************************************

led_ctrl模塊:

/**********************************************版權(quán)申明*************************************************

**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:          led_ctrl.v
** 創(chuàng)建者:          CrazyBird
** 創(chuàng)建日期:        2015-7-11
** 版本號:           v1.0
** 功能描述:        該模塊主要負(fù)責(zé)產(chǎn)生led燈流水顯示的數(shù)據(jù)
**                   
********************************************************************************************************/
// synopsys translate_off
`timescale 1 ns / 1 ps
// synopsys translate_on
module led_ctrl(
    rst_n,
    clk,
    led_data,
    led_flag
    );
    //******************************************************************************
    //                                參數(shù)定義               
    //******************************************************************************
    //  修改以下參數(shù)以滿足需求
    parameter   CLK_CYCLE = 20;                                        //   時(shí)鐘周期,單位ns
    parameter   T0        = 500_000_000;                               //   0.5s,流水燈流動速率
    // parameter   T0        = 5000;                                      //   測試用
    parameter   LED_WIDTH = 8;                                         //   led數(shù)據(jù)位寬
    parameter   DELAY0    = 25;                                        //   計(jì)數(shù)器位寬
    //  修改以上參數(shù)以滿足需求
    
    //  以下參數(shù)不要修改
    parameter   T0_VAL    = (T0/CLK_CYCLE)-1;                          //   0.5s,流水燈流動速率
    //  以上參數(shù)不要修改
    
    //******************************************************************************
    //                            輸入/輸出端口定義
    //******************************************************************************
    input                           rst_n;                             //   全局復(fù)位信號
    input                           clk;                               //   全局時(shí)鐘信號,50MHz
    output reg  [LED_WIDTH-1:0]     led_data;                          //   led燈數(shù)據(jù)輸出
    output reg                      led_flag;                          //   led燈數(shù)據(jù)輸出標(biāo)志
    
    //******************************************************************************
    //                                 計(jì)數(shù)器
    //******************************************************************************
    reg         [DELAY0-1:0]        cnt;
    wire                            cnt_done;                          //   0.5計(jì)數(shù)完成標(biāo)志位
    
    always @(posedge clk or negedge rst_n)
    begin
        if(rst_n==1'b0)
            cnt <= {(LED_WIDTH){1'b0}};
        else if(cnt_done==1'b1)
            cnt <= {(LED_WIDTH){1'b0}};
        else
            cnt <= cnt + 1'b1;
    end
    assign  cnt_done = (cnt==T0_VAL);
    
    //******************************************************************************
    //                              流水燈數(shù)據(jù)的產(chǎn)生 
    //******************************************************************************
    always @(posedge clk or negedge rst_n)
    begin
        if(rst_n==1'b0)
        begin
            led_data <= {{(LED_WIDTH-1){1'b0}},1'b1};
            led_flag <= 1'b0;
        end
        else if(cnt_done==1'b1)
        begin
            led_data <= {led_data[LED_WIDTH-2:0],led_data[LED_WIDTH-1]};
            led_flag <= 1'b1;
        end
        else
        begin
            led_data <= led_data;
            led_flag <= 1'b0;
        end
    end
    
    //******************************************************************************

endmodule
//*********************************************文件結(jié)束*****************************************************

driver_74595模塊:

/**********************************************版權(quán)申明*************************************************

**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:          driver_74595.v
** 創(chuàng)建者:          CrazyBird
** 創(chuàng)建日期:        2015-7-11
** 版本號:           v1.0
** 功能描述:        該模塊完成對74HC595的驅(qū)動
**                   
********************************************************************************************************/
// synopsys translate_off
`timescale 1 ns / 1 ps
// synopsys translate_on
module driver_74595(
    rst_n,
    clk,
    led_data,
    led_flag,
    shift_clock,
    latch_clock,
    led_dout
    );
    //******************************************************************************
    //                                參數(shù)定義               
    //******************************************************************************
    //  修改以下參數(shù)以滿足需求
    parameter   CLK_CYCLE = 20;                                        //   時(shí)鐘周期,單位ns
    parameter   T0        = 100;                                       //   100ns,移位時(shí)鐘高低電平時(shí)間長度
    parameter   T1        = 200;                                       //   200ns,鎖存時(shí)鐘周期
    parameter   LED_WIDTH = 8;                                         //   led數(shù)據(jù)位寬
    parameter   W0        = 3;                                         //   100ns計(jì)數(shù)器位寬
    parameter   W1        = 4;                                         //   200ns計(jì)數(shù)器位寬
    parameter   W2        = 4;                                         //   計(jì)算移位時(shí)鐘周期數(shù)
    //  修改以上參數(shù)以滿足需求
    
    //  以下參數(shù)不要修改
    parameter   T0_VAL    = (T0/CLK_CYCLE)-1;                          //   100ns,移位時(shí)鐘高低電平時(shí)間長度
    parameter   T1_VAL    = (T1/CLK_CYCLE)-1;                          //   200ns,鎖存時(shí)鐘周期
    parameter   IDLE      = 2'b00,
                CLK_L     = 2'b01,
                CLK_H     = 2'b10,
                FINISH    = 2'b11;
    //  以上參數(shù)不要修改
    
    //******************************************************************************
    //                            輸入/輸出端口定義
    //******************************************************************************
    input                           rst_n;                             //   全局復(fù)位信號
    input                           clk;                               //   全局時(shí)鐘信號,50MHz
    input       [LED_WIDTH-1:0]     led_data;                          //   led燈數(shù)據(jù)輸出
    input                           led_flag;                          //   led燈數(shù)據(jù)輸出標(biāo)志
    output reg                      shift_clock;                       //   74HC595的移位時(shí)鐘信號
    output reg                      latch_clock;                       //   74HC595的鎖存時(shí)鐘信號
    output                          led_dout;                          //   74HC595的串行數(shù)據(jù)輸入
    
    //******************************************************************************
    //                                變量定義
    //******************************************************************************
    wire                            shift_clock_cnt_done;              //   100ns計(jì)數(shù)完成標(biāo)志位
    wire                            latch_clock_cnt_done;              //   200ns計(jì)數(shù)完成標(biāo)志位
    wire                            period_cnt_done;                   //   生成8個(gè)移位時(shí)鐘標(biāo)志位
    
    //******************************************************************************
    //                          狀態(tài)機(jī)實(shí)現(xiàn)74HC595驅(qū)動
    //******************************************************************************
    reg         [1:0]               state;
    reg         [LED_WIDTH-1:0]     led_data_r;                        //   led燈的加載變量
    reg                             shift_clock_cnt_en;                //   100ns計(jì)數(shù)使能
    reg                             latch_clock_cnt_en;                //   200ns計(jì)數(shù)使能
    reg                             period_cnt_en;                     //   移位時(shí)鐘周期計(jì)數(shù)使能
    
    always @(posedge clk or negedge rst_n)
    begin
        if(rst_n==1'b0)
        begin
            state              <= IDLE;
            led_data_r         <= {(LED_WIDTH){1'b0}};
            shift_clock        <= 1'b0;
            latch_clock        <= 1'b0;
            shift_clock_cnt_en <= 1'b0;
            latch_clock_cnt_en <= 1'b0;
            period_cnt_en      <= 1'b0;
        end
        else
        begin
            case(state)
                IDLE :
                begin
                    if(led_flag)
                    begin
                        state              <= CLK_L;
                        led_data_r         <= led_data;                //   數(shù)據(jù)加載
                        shift_clock_cnt_en <= 1'b1;
                    end
                    else
                        state              <= IDLE;
                end
                
                CLK_L :
                begin
                    shift_clock <= 1'b0;
                    if(shift_clock_cnt_done==1'b1)
                        state   <= CLK_H;
                    else
                        state   <= CLK_L;
                end
                
                CLK_H :
                begin
                    shift_clock   <= 1'b1;
                    period_cnt_en <= 1'b1;
                    
                    if(shift_clock_cnt_done==1'b1)
                    begin
                        period_cnt_en <= 1'b0;
                        
                        if(period_cnt_done==1'b1)
                        begin
                            state              <= FINISH;
                            shift_clock_cnt_en <= 1'b0;
                            latch_clock_cnt_en <= 1'b1;
                            shift_clock        <= 1'b0;
                        end
                        else
                        begin
                            state      <= CLK_L;
                            led_data_r <= {led_data_r[LED_WIDTH-2:0],1'b0};
                        end
                    end
                    else
                        state <= CLK_H;
                end
                
                FINISH :
                begin
                    latch_clock <= 1'b1;
                    
                    if(latch_clock_cnt_done==1'b1)
                    begin
                        state              <= IDLE;
                        latch_clock_cnt_en <= 1'b0;
                        latch_clock        <= 1'b0;
                    end
                    else
                        state <= FINISH;
                end
            endcase
        end
    end
    
    //******************************************************************************
    //                              各種計(jì)數(shù)器
    //******************************************************************************
    //  移位時(shí)鐘計(jì)數(shù)器
    reg         [W0-1:0]        shift_clock_cnt;
    
    always @(posedge clk or negedge rst_n)
    begin
        if(rst_n==1'b0)
            shift_clock_cnt <= {(W0){1'b0}};
        else if(shift_clock_cnt_en==1'b1)
        begin
            if(shift_clock_cnt_done==1'b1)
                shift_clock_cnt <= {(W0){1'b0}};
            else
                shift_clock_cnt <= shift_clock_cnt + 1'b1;
        end
        else
            shift_clock_cnt <= {(W0){1'b0}};
    end
    assign  shift_clock_cnt_done = (shift_clock_cnt==T0_VAL);
    
    //  鎖存時(shí)鐘計(jì)數(shù)器
    reg         [W1-1:0]            latch_clock_cnt;
    
    always @(posedge clk or negedge rst_n)
    begin
        if(rst_n==1'b0)
            latch_clock_cnt <= {(W1){1'b0}};
        else if(latch_clock_cnt_en)
        begin
            if(latch_clock_cnt_done==1'b1)
                latch_clock_cnt <= {(W1){1'b0}};
            else
                latch_clock_cnt <= latch_clock_cnt + 1'b1;
        end
        else
            latch_clock_cnt <= {(W1){1'b0}};
    end
    assign  latch_clock_cnt_done = (latch_clock_cnt==T1_VAL);
    
    //  移位時(shí)鐘周期計(jì)數(shù)器
    reg         [W2-1:0]            period_cnt;
    
    always @(posedge clk or negedge rst_n)
    begin
        if(rst_n==1'b0)
            period_cnt <= {(W2){1'b0}};
        else if((period_cnt_en==1'b1)&&(shift_clock_cnt_done==1'b1))
        begin
            if(period_cnt_done==1'b1)
                period_cnt <= {(W2){1'b0}};
            else
                period_cnt <= period_cnt + 1'b1;
        end
        else
            period_cnt <= period_cnt;
    end
    assign  period_cnt_done = (period_cnt==7);
    
    //******************************************************************************
    //                              led數(shù)據(jù)輸出
    //******************************************************************************
    assign  led_dout = led_data_r[LED_WIDTH-1];
    
    //******************************************************************************

endmodule
//*********************************************文件結(jié)束*****************************************************

仿真結(jié)果如下:

很明顯,從仿真結(jié)果來看,本設(shè)計(jì)已實(shí)現(xiàn)了功能。接著,就可以對設(shè)計(jì)進(jìn)行綜合、布局布線、生成bit流文件和下載到板子上。在開發(fā)板上可以看到8盞led燈在做流水運(yùn)動。


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:239150 發(fā)表于 2020-6-3 17:24 | 只看該作者
請教下,全局時(shí)鐘信號如果在10Mhz左右能否正常工作
回復(fù)

使用道具 舉報(bào)

板凳
ID:239150 發(fā)表于 2020-6-3 17:25 | 只看該作者
請教下樓主,74HC595能否在10Mhz左右的全局時(shí)鐘下工作
回復(fù)

使用道具 舉報(bào)

地板
ID:919832 發(fā)表于 2021-7-27 17:25 | 只看該作者
程序可以分享一下嗎?
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 成人一区二区在线 | 欧州一区 | 91精品国产欧美一区二区成人 | 成人在线免费视频观看 | 人妖一区 | 美女亚洲一区 | 久草中文在线 | 久久精品中文 | 成人国产精品久久 | 亚洲一区二区三区免费 | 亚洲九色 | 在线观看成人精品 | 欧美久操网| 免费看91 | 一区二区免费视频 | 亚洲精品乱码久久久久久按摩观 | 国产精品片 | 午夜ww| 玖玖视频 | 亚洲a一区二区 | 中文在线一区二区 | 久草新在线 | 午夜视频在线播放 | 91在线色视频 | 国产伊人精品 | 午夜影院普通用户体验区 | 久久成人免费视频 | 亚洲一区二区av | 日本不卡一区二区三区在线观看 | 久草视频在线播放 | 日日天天| 国产一区二区三区久久久久久久久 | 性国产xxxx乳高跟 | 中文字幕中文字幕 | 国产成人久久精品一区二区三区 | 在线免费观看毛片 | 狠狠色香婷婷久久亚洲精品 | 99爱在线视频 | www.精品国产 | 翔田千里一区二区 | 国产伦精品一区二区三区照片91 |