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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 19765|回復: 3
收起左側

FPGA應用—74HC595驅動流水燈程序詳解

[復制鏈接]
ID:91350 發表于 2015-11-1 17:39 | 顯示全部樓層 |閱讀模式

一、設計需求

設計一個驅動74HC595芯片工作的功能模塊,并在CB哥的開發板上8盞led燈上實現流水燈的效果。

二、設計思路

1、74HC595介紹及分析

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

5245812404501.jpg

圖1 74HC595封裝及引腳分布

5245984152650.jpg

圖2 74HC595邏輯圖

74HC595具有以下特征:

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

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

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

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

當復位信號RESET為低電平時,

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

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

當復位信號RESET為高電平時,

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

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

5246163406534.jpg

圖3 74HC595功能表

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

5246233132944.jpg

圖4 74HC595時序圖

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

5246399746457.jpg

圖5 簡化后的74HC595時序圖

5250196962745.jpg

圖6 建立時間和保持時間要求

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

5250274346602.jpg

圖7 移位時鐘最大頻率與溫度、電壓的關系

2、設計分析

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

led_ctrl模塊 :負責產生流水燈顯示的數據;

driver_74595模塊 :負責驅動74HC595芯片工作并發送led數據;

led_water頂層模塊 :例化led_ctrl和driver_74595模塊,完成流水燈設計。

5250313491818.jpg

圖8 設計組織框架

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

5250362947955.jpg

圖9 74HC595驅動狀態機

三、設計實現

led_water頂層模塊:

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

led_ctrl模塊:

/**********************************************版權申明*************************************************

**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:          led_ctrl.v
** 創建者:          CrazyBird
** 創建日期:        2015-7-11
** 版本號:           v1.0
** 功能描述:        該模塊主要負責產生led燈流水顯示的數據
**                   
********************************************************************************************************/
// synopsys translate_off
`timescale 1 ns / 1 ps
// synopsys translate_on
module led_ctrl(
    rst_n,
    clk,
    led_data,
    led_flag
    );
    //******************************************************************************
    //                                參數定義               
    //******************************************************************************
    //  修改以下參數以滿足需求
    parameter   CLK_CYCLE = 20;                                        //   時鐘周期,單位ns
    parameter   T0        = 500_000_000;                               //   0.5s,流水燈流動速率
    // parameter   T0        = 5000;                                      //   測試用
    parameter   LED_WIDTH = 8;                                         //   led數據位寬
    parameter   DELAY0    = 25;                                        //   計數器位寬
    //  修改以上參數以滿足需求
    
    //  以下參數不要修改
    parameter   T0_VAL    = (T0/CLK_CYCLE)-1;                          //   0.5s,流水燈流動速率
    //  以上參數不要修改
    
    //******************************************************************************
    //                            輸入/輸出端口定義
    //******************************************************************************
    input                           rst_n;                             //   全局復位信號
    input                           clk;                               //   全局時鐘信號,50MHz
    output reg  [LED_WIDTH-1:0]     led_data;                          //   led燈數據輸出
    output reg                      led_flag;                          //   led燈數據輸出標志
    
    //******************************************************************************
    //                                 計數器
    //******************************************************************************
    reg         [DELAY0-1:0]        cnt;
    wire                            cnt_done;                          //   0.5計數完成標志位
    
    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);
    
    //******************************************************************************
    //                              流水燈數據的產生 
    //******************************************************************************
    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
//*********************************************文件結束*****************************************************

driver_74595模塊:

/**********************************************版權申明*************************************************

**
**--------------------------------------------文件信息--------------------------------------------------
** 文件名:          driver_74595.v
** 創建者:          CrazyBird
** 創建日期:        2015-7-11
** 版本號:           v1.0
** 功能描述:        該模塊完成對74HC595的驅動
**                   
********************************************************************************************************/
// 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
    );
    //******************************************************************************
    //                                參數定義               
    //******************************************************************************
    //  修改以下參數以滿足需求
    parameter   CLK_CYCLE = 20;                                        //   時鐘周期,單位ns
    parameter   T0        = 100;                                       //   100ns,移位時鐘高低電平時間長度
    parameter   T1        = 200;                                       //   200ns,鎖存時鐘周期
    parameter   LED_WIDTH = 8;                                         //   led數據位寬
    parameter   W0        = 3;                                         //   100ns計數器位寬
    parameter   W1        = 4;                                         //   200ns計數器位寬
    parameter   W2        = 4;                                         //   計算移位時鐘周期數
    //  修改以上參數以滿足需求
    
    //  以下參數不要修改
    parameter   T0_VAL    = (T0/CLK_CYCLE)-1;                          //   100ns,移位時鐘高低電平時間長度
    parameter   T1_VAL    = (T1/CLK_CYCLE)-1;                          //   200ns,鎖存時鐘周期
    parameter   IDLE      = 2'b00,
                CLK_L     = 2'b01,
                CLK_H     = 2'b10,
                FINISH    = 2'b11;
    //  以上參數不要修改
    
    //******************************************************************************
    //                            輸入/輸出端口定義
    //******************************************************************************
    input                           rst_n;                             //   全局復位信號
    input                           clk;                               //   全局時鐘信號,50MHz
    input       [LED_WIDTH-1:0]     led_data;                          //   led燈數據輸出
    input                           led_flag;                          //   led燈數據輸出標志
    output reg                      shift_clock;                       //   74HC595的移位時鐘信號
    output reg                      latch_clock;                       //   74HC595的鎖存時鐘信號
    output                          led_dout;                          //   74HC595的串行數據輸入
    
    //******************************************************************************
    //                                變量定義
    //******************************************************************************
    wire                            shift_clock_cnt_done;              //   100ns計數完成標志位
    wire                            latch_clock_cnt_done;              //   200ns計數完成標志位
    wire                            period_cnt_done;                   //   生成8個移位時鐘標志位
    
    //******************************************************************************
    //                          狀態機實現74HC595驅動
    //******************************************************************************
    reg         [1:0]               state;
    reg         [LED_WIDTH-1:0]     led_data_r;                        //   led燈的加載變量
    reg                             shift_clock_cnt_en;                //   100ns計數使能
    reg                             latch_clock_cnt_en;                //   200ns計數使能
    reg                             period_cnt_en;                     //   移位時鐘周期計數使能
    
    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;                //   數據加載
                        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
    
    //******************************************************************************
    //                              各種計數器
    //******************************************************************************
    //  移位時鐘計數器
    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);
    
    //  鎖存時鐘計數器
    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);
    
    //  移位時鐘周期計數器
    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數據輸出
    //******************************************************************************
    assign  led_dout = led_data_r[LED_WIDTH-1];
    
    //******************************************************************************

endmodule
//*********************************************文件結束*****************************************************

仿真結果如下:

5250422386320.png

很明顯,從仿真結果來看,本設計已實現了功能。接著,就可以對設計進行綜合、布局布線、生成bit流文件和下載到板子上。在開發板上可以看到8盞led燈在做流水運動。


回復

使用道具 舉報

ID:239150 發表于 2020-6-3 17:24 | 顯示全部樓層
請教下,全局時鐘信號如果在10Mhz左右能否正常工作
回復

使用道具 舉報

ID:239150 發表于 2020-6-3 17:25 | 顯示全部樓層
請教下樓主,74HC595能否在10Mhz左右的全局時鐘下工作
回復

使用道具 舉報

ID:919832 發表于 2021-7-27 17:25 | 顯示全部樓層
程序可以分享一下嗎?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产伦精品一区二区三区高清 | 欧美日韩中文在线 | 久久成人在线视频 | 国产色婷婷精品综合在线播放 | 国产成人综合久久 | 国产永久免费 | 国产目拍亚洲精品99久久精品 | 国产综合区 | 亚洲欧美一区二区在线观看 | 久久亚洲一区 | 产真a观专区 | 人人做人人澡人人爽欧美 | 亚洲一区在线观看视频 | 视频一区二区在线观看 | 综合精品久久久 | 99久久久99久久国产片鸭王 | 日本午夜精品一区二区三区 | 欧美日韩精品一区二区三区蜜桃 | 国产精品自拍一区 | 久久亚洲天堂 | 99在线资源| 99热热热| 亚洲精品一区国语对白 | 日本久久精品视频 | 狠狠色香婷婷久久亚洲精品 | 日本 欧美 三级 高清 视频 | 中文字幕在线播放不卡 | 九九热在线视频免费观看 | 黄色大片免费播放 | 久久综合狠狠综合久久综合88 | 亚洲高清一区二区三区 | 欧美一区二区三区在线视频 | 欧美日韩在线观看一区 | 亚洲一区二区三区免费在线观看 | 亚洲第一区国产精品 | 日韩精品一区二区三区中文字幕 | 国产日韩欧美 | 精品久久久久久久久久久久久久久久久 | 国产日韩精品视频 | 国产精品久久av | 一区二区三区四区免费观看 |