色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STEP FPGA驅(qū)動(dòng)基于74HC595的數(shù)碼管模塊

          STEP FPGA驅(qū)動(dòng)基于74HC595的數(shù)碼管模塊

          作者: 時(shí)間:2023-11-28 來源:電子森林 收藏

          硬件說明

          在前面之前的入門教程中 獨(dú)立顯示 章節(jié)已為大家介紹了獨(dú)立顯示的相關(guān)內(nèi)容,關(guān)于獨(dú)立顯示這里就不在贅述。我們的底板上有6位,根據(jù)驅(qū)動(dòng)方法不同,有以下比較:
          獨(dú)立顯示:控制每個(gè)數(shù)碼管至少需要8個(gè)I/O口控制,6位數(shù)碼管就需要6*8 = 48根信號(hào)線才能分別顯示。獨(dú)立顯示實(shí)現(xiàn)簡(jiǎn)單,但是需要大量的信號(hào)線。
          掃描顯示:將每位數(shù)碼管的同一段選信號(hào)連接在一起,這樣我們就只需要8根段選信號(hào)和6根位選信號(hào),共計(jì)14根信號(hào)。掃描顯示可以有效節(jié)約I/O口資源,實(shí)現(xiàn)起來稍顯復(fù)雜。

          本文引用地址:http://cafeforensic.com/article/202311/453344.htm

          我們小腳丫底板上使用的6位共陰極數(shù)碼管,分析掃描顯示的原理如下:
          當(dāng)某一時(shí)刻,F(xiàn)PGA控制8根公共的段選接口輸出數(shù)字1對(duì)應(yīng)的數(shù)碼管字庫(kù)數(shù)據(jù)8'h06(DP=0、G=0、F=0、E=0、D=0、C=1、B=1、A=0)時(shí),同時(shí)控制6位數(shù)碼管只有第1位使能(DIG1=0、DIG2=1、DIG3=1、DIG4=1、DIG5=1、DIG6=1)這樣我們會(huì)看到第1位數(shù)碼管顯示數(shù)字1,其余5位數(shù)碼管不顯示,如果不明白可以參考入門教程中實(shí)驗(yàn)四: 數(shù)碼管獨(dú)立顯示 章節(jié)
          按照掃描的方式,一共分為6個(gè)時(shí)刻,段選端口分別對(duì)應(yīng)輸出6位數(shù)碼管需要顯示的字庫(kù)數(shù)據(jù),位選端口保持每個(gè)時(shí)刻只有1位數(shù)碼管處于使能狀態(tài),6個(gè)時(shí)刻依次循環(huán),當(dāng)掃描頻率足夠高(例如當(dāng)掃描頻率等于100Hz)時(shí),則在人眼看到的數(shù)碼管顯示就是連續(xù)的,我們看到的就是6個(gè)不同的數(shù)字。
          上面為大家介紹了數(shù)碼管的獨(dú)立顯示和掃描顯示兩種方法,掃描顯示的方式使用了14個(gè)I/O口控制,相對(duì)于簡(jiǎn)單的處理器來講14個(gè)I/O口也是非常多了,這里我們又使用了一款常見的驅(qū)動(dòng)芯片74HC595,下面我們一起了解一下:
          74HC595是較為常用的串行轉(zhuǎn)并行的芯片,內(nèi)部集成了一個(gè)8位移位寄存器、一個(gè)存儲(chǔ)器和8個(gè)三態(tài)緩沖輸出。在最簡(jiǎn)單的情況下我們只需要控制3根引腳輸入得到8根引腳并行輸出信號(hào),而且可以級(jí)聯(lián)使用,我們使用3個(gè)I/O口控制兩個(gè)級(jí)聯(lián)的74HC595芯片,產(chǎn)生16路并行輸出,連接到掃描顯示的6位數(shù)碼管上,可以輕松完成數(shù)碼管驅(qū)動(dòng)任務(wù)。

          不同的IC廠家都可以生產(chǎn)74HC595芯片,功能都是一樣的,然而不同廠家的芯片手冊(cè)對(duì)于管腳的命名會(huì)存在差異,管腳順序相同,大家可以對(duì)應(yīng)識(shí)別 上圖是本設(shè)計(jì)中74HC595芯片的硬件電路連接,參考74HC595數(shù)據(jù)手冊(cè)了解其具體用法,下圖中我們了解到OE#(G#)和MR#(SCLR#)信號(hào)分別為輸出使能(低電平輸出)和復(fù)位管腳(低電平復(fù)位),OE#(G#)我們接GND讓芯片輸出使能,MR#(SCLR#)我們接VCC讓芯片的移位寄存器永遠(yuǎn)不復(fù)位,如此FPGA只需要控制SHCP(SCK)、STCP(RCK)和DS(SER)即可。

          74hc595引腳功能

          74hc595邏輯圖

          74hc595時(shí)序圖

          數(shù)碼管驅(qū)動(dòng)程序框圖

          Verilog代碼

          // --------------------------------------------------------------------
          // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
          // --------------------------------------------------------------------
          // Module:Segment_scan
          //
          // Author: Step
          //
          // Description: Display with Segment tube
          //
          // --------------------------------------------------------------------
          // Code Revision History :
          // --------------------------------------------------------------------
          // Version: |Mod. Date:   |Changes Made:
          // V1.0     |2015/11/11   |Initial ver
          // --------------------------------------------------------------------
          module Segment_scan
          (
          input clk_in, //系統(tǒng)時(shí)鐘
          input rst_n_in, //系統(tǒng)復(fù)位,低有效
          input [3:0] seg_data_1, //SEG1 數(shù)碼管要顯示的數(shù)據(jù)
          input [3:0] seg_data_2, //SEG2 數(shù)碼管要顯示的數(shù)據(jù)
          input [3:0] seg_data_3, //SEG3 數(shù)碼管要顯示的數(shù)據(jù)
          input [3:0] seg_data_4, //SEG4 數(shù)碼管要顯示的數(shù)據(jù)
          input [3:0] seg_data_5, //SEG5 數(shù)碼管要顯示的數(shù)據(jù)
          input [3:0] seg_data_6, //SEG6 數(shù)碼管要顯示的數(shù)據(jù)
          input [5:0] seg_data_en, //各位數(shù)碼管數(shù)據(jù)顯示使能,[MSB~LSB]=[SEG6~SEG1]
          input [5:0] seg_dot_en, //各位數(shù)碼管小數(shù)點(diǎn)顯示使能,[MSB~LSB]=[SEG6~SEG1]
          output reg rclk_out, //74HC595的RCK管腳
          output reg sclk_out, //74HC595的SCK管腳
          output reg sdio_out //74HC595的SER管腳)

          parameter CLK_DIV_PERIOD = 600; //分頻系數(shù) 
          localparam IDLE = 3'd0;
          localparam MAIN = 3'd1;
          localparam WRITE = 3'd2; 
          localparam LOW = 1'b0;
          localparam HIGH = 1'b1; //創(chuàng)建數(shù)碼管的字庫(kù),字庫(kù)數(shù)據(jù)依段碼順序有關(guān)//這里字庫(kù)數(shù)據(jù)[MSB~LSB]={DP,G,F,E,D,C,B,A}
          reg[7:0] seg [15:0]; initial begin
             seg[0] = 8'h3f;   //  0
             seg[1] = 8'h06;   //  1
             seg[2] = 8'h5b;   //  2
             seg[3] = 8'h4f;   //  3
             seg[4] = 8'h66;   //  4
             seg[5] = 8'h6d;   //  5
             seg[6] = 8'h7d;   //  6
             seg[7] = 8'h07;   //  7
             seg[8] = 8'h7f;   //  8
             seg[9] = 8'h6f;   //  9
          seg[10] = 8'h77;   //  A
             seg[11] = 8'h7c;   //  b
             seg[12] = 8'h39;   //  C
             seg[13] = 8'h5e;   //  d
             seg[14] = 8'h79;   //  E
             seg[15] = 8'h71;   //  Fend  //計(jì)數(shù)器對(duì)系統(tǒng)時(shí)鐘信號(hào)進(jìn)行計(jì)數(shù)
             reg[9:0] cnt=0;
             always@(posedge clk_in or negedge rst_n_in) begin
          if(!rst_n_in) begin
          cnt <= 1'b0;
          end else begin
          if(cnt>=(CLK_DIV_PERIOD-1)) cnt <= 1'b0;
          else cnt <= cnt + 1'b1;
          endend //根據(jù)計(jì)數(shù)器計(jì)數(shù)的周期產(chǎn)生分頻的脈沖信號(hào)
          reg clk_div;
          always@(posedge clk_in or negedge rst_n_in) begin
          if(!rst_n_in) begin
          clk_div <= 1'b0;
          end else begin
          if(cnt==(CLK_DIV_PERIOD-1)) clk_div <= 1'b1;
          else clk_div <= 1'b0;
          endend //使用狀態(tài)機(jī)完成數(shù)碼管的掃描和74HC595時(shí)序的實(shí)現(xiàn)
          reg [15:0] data_reg;
          reg [2:0] cnt_main;
          reg [5:0] cnt_write;
          reg [2:0] state = IDLE;
          always@(posedge clk_in or negedge rst_n_in) begin
          if(!rst_n_in) begin //復(fù)位狀態(tài)下,各寄存器置初值
          state <= IDLE;
          cnt_main <= 3'd0;
          cnt_write <= 6'd0;
          sdio_out <= 1'b0;
          sclk_out <= LOW;
          rclk_out <= LOW;
          end else begin
          case(state)
          IDLE:begin //IDLE作為第一個(gè)狀態(tài),相當(dāng)于軟復(fù)位
          state <= MAIN;
          cnt_main <= 3'd0;
          cnt_write <= 6'd0;
          sdio_out <= 1'b0;
          sclk_out <= LOW;
          rclk_out <= LOW;
          end
          MAIN:begin
          if(cnt_main >= 3'd5) cnt_main <= 1'b0;
          else cnt_main <= cnt_main + 1'b1;
          case(cnt_main)
          //對(duì)6位數(shù)碼管逐位掃描
          3'd0: begin
          state <= WRITE;
          //在配置完發(fā)給74HC595的數(shù)據(jù)同時(shí)跳轉(zhuǎn)至WRITE狀態(tài),完成串行時(shí)序
          data_reg <= {seg[seg_data_1]|(seg_dot_en[0]?8'h80:8'h00),seg_data_en[0]?8'hfe:8'hff};
          //data_reg[15:8]為段選,data_reg[7:0]為位選
          //seg[seg_data_1]  是根據(jù)端口的輸入獲取相應(yīng)字庫(kù)數(shù)據(jù)
          //seg_dot_en[0]?8'h80:8'h00  是根據(jù)小數(shù)點(diǎn)顯示使能信號(hào) 控制SEG1數(shù)碼管的小數(shù)點(diǎn)DP段的電平
          //seg_data_en[0]?8'hfe:8'hff  是根據(jù)數(shù)據(jù)顯示使能信號(hào) 控制SEG1數(shù)碼管的位選引腳的電平
          end
          3'd1: begin
          state <= WRITE;
          data_reg <= {seg[seg_data_2]|(seg_dot_en[1]?8'h80:8'h00),seg_data_en[1]?8'hfd:8'hff};
          end
          3'd2: begin
          state <= WRITE;
          data_reg <= {seg[seg_data_3]|(seg_dot_en[2]?8'h80:8'h00),seg_data_en[2]?8'hfb:8'hff};
          end
          3'd3: begin
          state <= WRITE;
          data_reg <= {seg[seg_data_4]|(seg_dot_en[3]?8'h80:8'h00),seg_data_en[3]?8'hf7:8'hff};
          end
          3'd4: begin
          state <= WRITE;
          data_reg <= {seg[seg_data_5]|(seg_dot_en[4]?8'h80:8'h00),seg_data_en[4]?8'hef:8'hff};
          end
          3'd5: begin
          state <= WRITE;
          data_reg <= {seg[seg_data_6]|(seg_dot_en[5]?8'h80:8'h00),seg_data_en[5]?8'hdf:8'hff};
          end
          default: state <= IDLE;
          endcase
          end
          WRITE:begin
          if(clk_div) begin //74HC595的串行時(shí)鐘有速度要求,需要按照分頻后的節(jié)拍
          if(cnt_write >= 6'd33) cnt_write <= 1'b0;
          else cnt_write <= cnt_write + 1'b1;
          case(cnt_write)
          //74HC595是串行轉(zhuǎn)并行的芯片,3路輸入可產(chǎn)生8路輸出,而且可以級(jí)聯(lián)使用
          //74HC595的時(shí)序?qū)崿F(xiàn),參考74HC595的芯片手冊(cè)
          6'd0:  begin sclk_out <= LOW;
          sdio_out <= data_reg[15];
          end //SCK下降沿時(shí)SER更新數(shù)據(jù)
          6'd1:  begin sclk_out <= HIGH;
          end //SCK上升沿時(shí)SER數(shù)據(jù)穩(wěn)定
          6'd2:  begin sclk_out <= LOW;
          sdio_out <= data_reg[14];
          end
          6'd3:  begin sclk_out <= HIGH;
          end
          6'd4:  begin sclk_out <= LOW;
          sdio_out <= data_reg[13];
          end
          6'd5:  begin sclk_out <= HIGH;
          end
          6'd6:  begin sclk_out <= LOW;
          sdio_out <= data_reg[12];
          end
          6'd7:  begin sclk_out <= HIGH;
          end
          6'd8:  begin sclk_out <= LOW;
          sdio_out <= data_reg[11];
          end
          6'd9:  begin sclk_out <= HIGH;
          end
          6'd10: begin sclk_out <= LOW;
          sdio_out <= data_reg[10];
          end
          6'd11: begin sclk_out <= HIGH;
          end
          6'd12: begin sclk_out <= LOW;
          sdio_out <= data_reg[9];
          end
          6'd13: begin sclk_out <= HIGH;
          end
          6'd14: begin sclk_out <= LOW;
          sdio_out <= data_reg[8];
          end
          6'd15: begin sclk_out <= HIGH;
          end
          6'd16: begin sclk_out <= LOW;
          sdio_out <= data_reg[7];
          end
          6'd17: begin sclk_out <= HIGH;
          end
          6'd18: begin sclk_out <= LOW;
          sdio_out <= data_reg[6];
          end
          6'd19: begin sclk_out <= HIGH;
          end
          6'd20: begin sclk_out <= LOW;
          sdio_out <= data_reg[5];
          end
          6'd21: begin sclk_out <= HIGH;
          end
          6'd22: begin sclk_out <= LOW;
          sdio_out <= data_reg[4];
          end
          6'd23: begin sclk_out <= HIGH;
          end
          6'd24: begin sclk_out <= LOW;
          sdio_out <= data_reg[3];
          end
          6'd25: begin sclk_out <= HIGH;
          end
          6'd26: begin sclk_out <= LOW;
          sdio_out <= data_reg[2];
          end
          6'd27: begin sclk_out <= HIGH;
          end
          6'd28: begin sclk_out <= LOW;
          sdio_out <= data_reg[1];
          end
          6'd29: begin sclk_out <= HIGH;
          end
          6'd30: begin sclk_out <= LOW;
          sdio_out <= data_reg[0];
          end
          6'd31: begin sclk_out <= HIGH;
          end
          6'd32: begin rclk_out <= HIGH;
          end //當(dāng)16位數(shù)據(jù)傳送完成后RCK拉高,輸出生效
          6'd33: begin rclk_out <= LOW; s
          tate <= MAIN;
          end
          default: state <= IDLE;
          endcase
          end else begin
          sclk_out <= sclk_out;
          sdio_out <= sdio_out;
          rclk_out <= rclk_out;
          cnt_write <= cnt_write;
          state <= state;
          end
          end
          default: state <= IDLE;
          endcase
          end
          end 
          endmodule

          小結(jié)

          本節(jié)主要為大家講解了數(shù)碼管顯示的相關(guān)原理及軟件設(shè)計(jì),需要大家掌握的同時(shí)自己創(chuàng)建工程,通過整個(gè)設(shè)計(jì)流程,生成FPGA配置文件加載測(cè)試。



          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉