矩陣鍵盤鍵入系統(tǒng)設(shè)計(jì)
實(shí)驗(yàn)任務(wù)
實(shí)驗(yàn)?zāi)康?/h4>
在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分我們已經(jīng)掌握了FPGA驅(qū)動(dòng)獨(dú)立顯示數(shù)碼管的原理及方法,掌握了有限狀態(tài)機(jī)的設(shè)計(jì)實(shí)現(xiàn)思想,本實(shí)驗(yàn)主要學(xué)習(xí)矩陣鍵盤的原理及驅(qū)動(dòng)設(shè)計(jì)。
本文引用地址:http://butianyuan.cn/article/202312/453589.htm設(shè)計(jì)框圖
根據(jù)前面的實(shí)驗(yàn)解析我們可以得知,該設(shè)計(jì)可以拆分成三個(gè)功能模塊實(shí)現(xiàn),
頂層模塊Type_system通過實(shí)例化三個(gè)子模塊并將對(duì)應(yīng)的信號(hào)連接,最終實(shí)現(xiàn)矩陣鍵盤鍵入系統(tǒng)的總體設(shè)計(jì)。
實(shí)驗(yàn)原理
鍵盤類型
嵌入式設(shè)計(jì)中常見的鍵盤有兩種類型,獨(dú)立鍵盤與矩陣鍵盤,
矩陣鍵盤連接
這里我們以STEP BaseBoard V3.0底板上的4×4矩陣鍵盤為例,其電路圖如下:
上圖為4×4矩陣按鍵的硬件電路圖,可以看到4根行線(ROW1、ROW2、ROW3、ROW4)和4根列線(COL1、COL2、COL3、COL4),同時(shí)列線通過上拉電阻連接到VCC電壓(3.3V),對(duì)于矩陣按鍵來講:
當(dāng)某時(shí)刻,F(xiàn)PGA控制4根行線分別為ROW1=0、ROW2=1、ROW3=1、ROW4=1時(shí),
通過上面的描述:在這一時(shí)刻只有K1、K2、K3、K4按鍵被按下,才會(huì)導(dǎo)致4根列線輸出COL1=0、COL2=0、COL3=0、COL4=0,否則COL1=1、COL2=1、COL3=1、COL4=1,反之當(dāng)FPGA檢測(cè)到列線(COL1、COL2、COL3、COL4)中有低電平信號(hào)時(shí),對(duì)應(yīng)的K1、K2、K3、K4按鍵應(yīng)該是被按下了。 按照掃描的方式,一共分為4個(gè)時(shí)刻,分別對(duì)應(yīng)4根行線中的一根拉低,4個(gè)時(shí)刻依次循環(huán),這樣就完成了矩陣按鍵的全部掃描檢測(cè),我們?cè)诔绦蛑幸赃@4個(gè)時(shí)刻對(duì)應(yīng)狀態(tài)機(jī)的4個(gè)狀態(tài)。
矩陣鍵盤驅(qū)動(dòng)設(shè)計(jì)
通過上節(jié)的描述,大家對(duì)于矩陣鍵盤工作的原理應(yīng)該都沒有問題了,那么我們?cè)趺淳幊虒?shí)現(xiàn)矩陣鍵盤驅(qū)動(dòng)設(shè)計(jì)呢?我們將矩陣鍵盤的掃描周期分為4個(gè)時(shí)刻,對(duì)應(yīng)4個(gè)狀態(tài),使得狀態(tài)機(jī)在4個(gè)狀態(tài)上循環(huán)跳轉(zhuǎn),最終通過掃描的方式獲取矩陣鍵盤的操作狀態(tài)。
狀態(tài)機(jī)程序?qū)崿F(xiàn)如下:
reg [1:0] c_state;
//狀態(tài)機(jī)根據(jù)clk_200hz信號(hào)在4個(gè)狀態(tài)間循環(huán),每個(gè)狀態(tài)對(duì)矩陣按鍵的行接口單行有效
always@(posedge clk_200hz or negedge rst_n) begin
if(!rst_n) begin
c_state <= STATE0;
row <= 4'b1110;
end else begin
case(c_state)
//狀態(tài)c_state跳轉(zhuǎn)及對(duì)應(yīng)狀態(tài)下矩陣按鍵的row輸出
STATE0: begin c_state <= STATE1; row <= 4'b1101; end
STATE1: begin c_state <= STATE2; row <= 4'b1011; end
STATE2: begin c_state <= STATE3; row <= 4'b0111; end
STATE3: begin c_state <= STATE0; row <= 4'b1110; end
default:begin c_state <= STATE0; row <= 4'b1110; end
endcase
endend
至于狀態(tài)機(jī)循環(huán)的周期,根據(jù)我們基礎(chǔ)教程里可知,按鍵抖動(dòng)的不穩(wěn)定時(shí)間在10ms以內(nèi),所以對(duì)同一個(gè)按鍵采樣的周期大于10ms,這里同樣取20ms時(shí)間。20ms時(shí)間對(duì)應(yīng)4個(gè)狀態(tài),每5分鐘進(jìn)行一次狀態(tài)轉(zhuǎn)換。所以我們?cè)跔顟B(tài)機(jī)之前先增加分頻模塊,得到200Hz的分頻時(shí)鐘,然后狀態(tài)機(jī)按照200Hz分頻時(shí)鐘的節(jié)拍做狀態(tài)跳轉(zhuǎn)和鍵盤采樣。
狀態(tài)機(jī)程序?qū)崿F(xiàn)如下:
parameter CNT_200HZ = 60000;//計(jì)數(shù)器計(jì)數(shù)分頻實(shí)現(xiàn)5ms周期信號(hào)
clk_200hzreg [15:0] cnt;
reg clk_200hz;
always@(posedge clk or negedge rst_n) begin //復(fù)位時(shí)計(jì)數(shù)器cnt清零,clk_200hz信號(hào)起始電平為低電平
if(!rst_n) begin
cnt <= 16'd0;
clk_200hz <= 1'b0;
end else begin
if(cnt >= ((CNT_200HZ>>1) - 1)) begin //數(shù)字邏輯中右移1位相當(dāng)于除2
cnt <= 16'd0;
clk_200hz <= ~clk_200hz; //clk_200hz信號(hào)取反
end else begin
cnt <= cnt + 1'b1;
clk_200hz <= clk_200hz;
end
endend
通過以上的程序我們實(shí)現(xiàn)了狀態(tài)機(jī)的4個(gè)狀態(tài)循環(huán)跳轉(zhuǎn),每個(gè)狀態(tài)都有對(duì)應(yīng)的邏輯輸出,接下來我們需要將矩陣鍵盤的輸出采集回來,并以此判斷鍵盤的操作狀態(tài)。采樣也是需要按照狀態(tài)的,4個(gè)狀態(tài)的采樣數(shù)據(jù)合并后得到一個(gè)16位數(shù),代表16個(gè)按鍵的操作狀態(tài),是不是非常簡(jiǎn)單呢?比如下面的程序,是不是就搞定了?
鍵盤采樣功能程序?qū)崿F(xiàn)如下:
//因?yàn)槊總€(gè)狀態(tài)中單行有效,通過對(duì)列接口的電平狀態(tài)采樣得到對(duì)應(yīng)4個(gè)按鍵的狀態(tài),依次循環(huán)
always@(negedge clk_200hz or negedge rst_n_in) begin
if(!rst_n_in) begin
key_out <= 16'hffff;
end else begin
case(c_state)
STATE0:key_out[3:0] <= col; //采集當(dāng)前狀態(tài)的列數(shù)據(jù)賦值給對(duì)應(yīng)的寄存器位
STATE1:key_out[7:4] <= col;
STATE2:key_out[11:8] <= col;
STATE3:key_out[15:12] <= col;
default:key_out <= 16'hffff;
endcase
endend
結(jié)束了嗎? 沒有,還差一點(diǎn),繼續(xù)往下看
對(duì)于大多數(shù)需要循環(huán)掃描的硬件來說,程序?qū)懙竭@里應(yīng)該就完成了,但是大家想想我們之前基礎(chǔ)數(shù)字電路實(shí)驗(yàn)關(guān)于按鍵消抖部分的內(nèi)容,因?yàn)槲覀兪窃趯?duì)按鍵采樣,按鍵是會(huì)抖動(dòng)的,所以我們還要想辦法對(duì)采集回來的數(shù)據(jù)做一些判定,怎么判定呢? 這就得回到矩陣鍵盤工作原理上來了。
上圖是市面上常見按鍵抖動(dòng)的模型,有三個(gè)參數(shù),按下抖動(dòng)10ms以內(nèi),松開抖動(dòng)10ms以內(nèi),按鍵周期數(shù)百ms;前面說過鍵盤的采樣周期為20ms,可以得到以下結(jié)論:
鍵盤采樣判定功能程序?qū)崿F(xiàn)如下:
STATE0: begin
key[3:0] <= col; //矩陣鍵盤采樣
key_r[3:0] <= key[3:0]; //鍵盤數(shù)據(jù)鎖存
key_out[3:0] <= key_r[3:0]|key[3:0]; //連續(xù)兩次采樣判定
end
將此程序?qū)崿F(xiàn)方法更新到上一部分程序中,最后keyout就是采樣消抖后的直接輸出。當(dāng)按鍵被按下時(shí)keyout對(duì)應(yīng)位輸出低電平,松開按鍵時(shí)keyout對(duì)應(yīng)位恢復(fù)高電平輸出。 由以上程序我們完成了矩陣鍵盤的驅(qū)動(dòng),但是keyout這種類型的輸出有時(shí)在后級(jí)時(shí)序電路設(shè)計(jì)中不好直接使用,例如對(duì)于當(dāng)前矩陣鍵盤鍵入系統(tǒng)設(shè)計(jì)來講,我們需要按鍵按動(dòng)一次(與按下保持的時(shí)間長(zhǎng)短無(wú)關(guān))就輸入對(duì)應(yīng)的鍵值,按鍵松開后鍵值也不能消失,我們就需要一個(gè)寄存器變量來儲(chǔ)存按過的按鍵鍵值,考慮到可能存在多個(gè)按鍵在極短時(shí)間內(nèi)被先后按下,這樣一來我們最好將按鍵按動(dòng)這種長(zhǎng)時(shí)間事件轉(zhuǎn)化成一個(gè)瞬間的脈沖,方法就是對(duì)key_out信號(hào)中的每一位進(jìn)行下降沿(或上升沿)檢測(cè),方法如下:
下降沿檢測(cè)程序?qū)崿F(xiàn)如下:
reg [15:0] key_out_r;//Register low_sw_r, lock low_sw to next clk
always @ ( posedge clk or negedge rst_n )
if (!rst_n) key_out_r <= 16'hffff;
else key_out_r <= key_out; //將前一刻的值延遲鎖存
//wire [15:0] key_pulse;
//Detect the negedge of low_sw, generate pulse
assign key_pulse= key_out_r & ( ~key_out); //通過前后兩個(gè)時(shí)刻的值判斷
經(jīng)過上面程序的處理,我們就得到了16位脈沖信號(hào),平時(shí)為低電平,當(dāng)按鍵被按下時(shí)刻keypulse產(chǎn)生一個(gè)高脈沖,脈沖的寬度為模塊系統(tǒng)時(shí)鐘clkin的一個(gè)周期。
系統(tǒng)總體實(shí)現(xiàn)
在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分我們已經(jīng)掌握了FPGA驅(qū)動(dòng)獨(dú)立顯示數(shù)碼管的原理及方法, 模塊通過一個(gè)4位的輸入傳遞要顯示的數(shù)值,通過9位的輸出控制數(shù)碼管顯示該數(shù)值,這里我們不再重復(fù)。 矩陣鍵盤驅(qū)動(dòng)模塊輸出的是脈沖信號(hào),后面數(shù)碼管驅(qū)動(dòng)模塊輸入的是用4位位寬表示的數(shù)據(jù),所以中兩個(gè)實(shí)例之間就需要一個(gè)編碼的功能塊,主要功能是根據(jù)矩陣鍵盤的脈沖輸出(keypulse)判定鍵盤的操作,通過編碼對(duì)應(yīng)提供按鍵的鍵值數(shù)據(jù)(segdata),最后通過連線將鍵值數(shù)據(jù)連接到數(shù)碼管模塊的輸入端口。
鍵值顯示轉(zhuǎn)碼程序?qū)崿F(xiàn)
//key_pulse transfer to seg_data
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
seg_data <= 8'h00;
end else begin
case(key_pulse) //key_pulse脈寬等于clk_in的周期
16'h0001: seg_data <= 8'h01; //編碼
16'h0002: seg_data <= 8'h02;
16'h0004: seg_data <= 8'h03;
16'h0008: seg_data <= 8'h04;
16'h0010: seg_data <= 8'h05;
16'h0020: seg_data <= 8'h06;
16'h0040: seg_data <= 8'h07;
16'h0080: seg_data <= 8'h08;
16'h0100: seg_data <= 8'h09;
16'h0200: seg_data <= 8'h10;
16'h0400: seg_data <= 8'h11;
16'h0800: seg_data <= 8'h12;
16'h1000: seg_data <= 8'h13;
16'h2000: seg_data <= 8'h14;
16'h4000: seg_data <= 8'h15;
16'h8000: seg_data <= 8'h16;
default: seg_data <= seg_data; //無(wú)按鍵按下時(shí)保持
endcase
end
end
綜合后的設(shè)計(jì)框圖如下:
實(shí)驗(yàn)步驟
實(shí)驗(yàn)現(xiàn)象
按動(dòng)矩陣鍵盤上的按鍵,核心板獨(dú)立顯示數(shù)碼管會(huì)更新顯示對(duì)應(yīng)鍵值。例如上電默認(rèn)顯示00,按動(dòng)K8按鍵,數(shù)碼管顯示08,再按動(dòng)K16按鍵,數(shù)碼管顯示16。
在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分我們已經(jīng)掌握了FPGA驅(qū)動(dòng)獨(dú)立顯示數(shù)碼管的原理及方法,掌握了有限狀態(tài)機(jī)的設(shè)計(jì)實(shí)現(xiàn)思想,本實(shí)驗(yàn)主要學(xué)習(xí)矩陣鍵盤的原理及驅(qū)動(dòng)設(shè)計(jì)。
本文引用地址:http://butianyuan.cn/article/202312/453589.htm根據(jù)前面的實(shí)驗(yàn)解析我們可以得知,該設(shè)計(jì)可以拆分成三個(gè)功能模塊實(shí)現(xiàn),
頂層模塊Type_system通過實(shí)例化三個(gè)子模塊并將對(duì)應(yīng)的信號(hào)連接,最終實(shí)現(xiàn)矩陣鍵盤鍵入系統(tǒng)的總體設(shè)計(jì)。
嵌入式設(shè)計(jì)中常見的鍵盤有兩種類型,獨(dú)立鍵盤與矩陣鍵盤,
這里我們以STEP BaseBoard V3.0底板上的4×4矩陣鍵盤為例,其電路圖如下:
上圖為4×4矩陣按鍵的硬件電路圖,可以看到4根行線(ROW1、ROW2、ROW3、ROW4)和4根列線(COL1、COL2、COL3、COL4),同時(shí)列線通過上拉電阻連接到VCC電壓(3.3V),對(duì)于矩陣按鍵來講:
當(dāng)某時(shí)刻,F(xiàn)PGA控制4根行線分別為ROW1=0、ROW2=1、ROW3=1、ROW4=1時(shí),
通過上面的描述:在這一時(shí)刻只有K1、K2、K3、K4按鍵被按下,才會(huì)導(dǎo)致4根列線輸出COL1=0、COL2=0、COL3=0、COL4=0,否則COL1=1、COL2=1、COL3=1、COL4=1,反之當(dāng)FPGA檢測(cè)到列線(COL1、COL2、COL3、COL4)中有低電平信號(hào)時(shí),對(duì)應(yīng)的K1、K2、K3、K4按鍵應(yīng)該是被按下了。 按照掃描的方式,一共分為4個(gè)時(shí)刻,分別對(duì)應(yīng)4根行線中的一根拉低,4個(gè)時(shí)刻依次循環(huán),這樣就完成了矩陣按鍵的全部掃描檢測(cè),我們?cè)诔绦蛑幸赃@4個(gè)時(shí)刻對(duì)應(yīng)狀態(tài)機(jī)的4個(gè)狀態(tài)。
通過上節(jié)的描述,大家對(duì)于矩陣鍵盤工作的原理應(yīng)該都沒有問題了,那么我們?cè)趺淳幊虒?shí)現(xiàn)矩陣鍵盤驅(qū)動(dòng)設(shè)計(jì)呢?我們將矩陣鍵盤的掃描周期分為4個(gè)時(shí)刻,對(duì)應(yīng)4個(gè)狀態(tài),使得狀態(tài)機(jī)在4個(gè)狀態(tài)上循環(huán)跳轉(zhuǎn),最終通過掃描的方式獲取矩陣鍵盤的操作狀態(tài)。
狀態(tài)機(jī)程序?qū)崿F(xiàn)如下:
reg [1:0] c_state; //狀態(tài)機(jī)根據(jù)clk_200hz信號(hào)在4個(gè)狀態(tài)間循環(huán),每個(gè)狀態(tài)對(duì)矩陣按鍵的行接口單行有效 always@(posedge clk_200hz or negedge rst_n) begin if(!rst_n) begin c_state <= STATE0; row <= 4'b1110; end else begin case(c_state) //狀態(tài)c_state跳轉(zhuǎn)及對(duì)應(yīng)狀態(tài)下矩陣按鍵的row輸出 STATE0: begin c_state <= STATE1; row <= 4'b1101; end STATE1: begin c_state <= STATE2; row <= 4'b1011; end STATE2: begin c_state <= STATE3; row <= 4'b0111; end STATE3: begin c_state <= STATE0; row <= 4'b1110; end default:begin c_state <= STATE0; row <= 4'b1110; end endcase endend
至于狀態(tài)機(jī)循環(huán)的周期,根據(jù)我們基礎(chǔ)教程里可知,按鍵抖動(dòng)的不穩(wěn)定時(shí)間在10ms以內(nèi),所以對(duì)同一個(gè)按鍵采樣的周期大于10ms,這里同樣取20ms時(shí)間。20ms時(shí)間對(duì)應(yīng)4個(gè)狀態(tài),每5分鐘進(jìn)行一次狀態(tài)轉(zhuǎn)換。所以我們?cè)跔顟B(tài)機(jī)之前先增加分頻模塊,得到200Hz的分頻時(shí)鐘,然后狀態(tài)機(jī)按照200Hz分頻時(shí)鐘的節(jié)拍做狀態(tài)跳轉(zhuǎn)和鍵盤采樣。
狀態(tài)機(jī)程序?qū)崿F(xiàn)如下:
parameter CNT_200HZ = 60000;//計(jì)數(shù)器計(jì)數(shù)分頻實(shí)現(xiàn)5ms周期信號(hào) clk_200hzreg [15:0] cnt; reg clk_200hz; always@(posedge clk or negedge rst_n) begin //復(fù)位時(shí)計(jì)數(shù)器cnt清零,clk_200hz信號(hào)起始電平為低電平 if(!rst_n) begin cnt <= 16'd0; clk_200hz <= 1'b0; end else begin if(cnt >= ((CNT_200HZ>>1) - 1)) begin //數(shù)字邏輯中右移1位相當(dāng)于除2 cnt <= 16'd0; clk_200hz <= ~clk_200hz; //clk_200hz信號(hào)取反 end else begin cnt <= cnt + 1'b1; clk_200hz <= clk_200hz; end endend
通過以上的程序我們實(shí)現(xiàn)了狀態(tài)機(jī)的4個(gè)狀態(tài)循環(huán)跳轉(zhuǎn),每個(gè)狀態(tài)都有對(duì)應(yīng)的邏輯輸出,接下來我們需要將矩陣鍵盤的輸出采集回來,并以此判斷鍵盤的操作狀態(tài)。采樣也是需要按照狀態(tài)的,4個(gè)狀態(tài)的采樣數(shù)據(jù)合并后得到一個(gè)16位數(shù),代表16個(gè)按鍵的操作狀態(tài),是不是非常簡(jiǎn)單呢?比如下面的程序,是不是就搞定了?
鍵盤采樣功能程序?qū)崿F(xiàn)如下:
//因?yàn)槊總€(gè)狀態(tài)中單行有效,通過對(duì)列接口的電平狀態(tài)采樣得到對(duì)應(yīng)4個(gè)按鍵的狀態(tài),依次循環(huán) always@(negedge clk_200hz or negedge rst_n_in) begin if(!rst_n_in) begin key_out <= 16'hffff; end else begin case(c_state) STATE0:key_out[3:0] <= col; //采集當(dāng)前狀態(tài)的列數(shù)據(jù)賦值給對(duì)應(yīng)的寄存器位 STATE1:key_out[7:4] <= col; STATE2:key_out[11:8] <= col; STATE3:key_out[15:12] <= col; default:key_out <= 16'hffff; endcase endend
結(jié)束了嗎? 沒有,還差一點(diǎn),繼續(xù)往下看
對(duì)于大多數(shù)需要循環(huán)掃描的硬件來說,程序?qū)懙竭@里應(yīng)該就完成了,但是大家想想我們之前基礎(chǔ)數(shù)字電路實(shí)驗(yàn)關(guān)于按鍵消抖部分的內(nèi)容,因?yàn)槲覀兪窃趯?duì)按鍵采樣,按鍵是會(huì)抖動(dòng)的,所以我們還要想辦法對(duì)采集回來的數(shù)據(jù)做一些判定,怎么判定呢? 這就得回到矩陣鍵盤工作原理上來了。
上圖是市面上常見按鍵抖動(dòng)的模型,有三個(gè)參數(shù),按下抖動(dòng)10ms以內(nèi),松開抖動(dòng)10ms以內(nèi),按鍵周期數(shù)百ms;前面說過鍵盤的采樣周期為20ms,可以得到以下結(jié)論:
鍵盤采樣判定功能程序?qū)崿F(xiàn)如下:
STATE0: begin key[3:0] <= col; //矩陣鍵盤采樣 key_r[3:0] <= key[3:0]; //鍵盤數(shù)據(jù)鎖存 key_out[3:0] <= key_r[3:0]|key[3:0]; //連續(xù)兩次采樣判定 end
將此程序?qū)崿F(xiàn)方法更新到上一部分程序中,最后keyout就是采樣消抖后的直接輸出。當(dāng)按鍵被按下時(shí)keyout對(duì)應(yīng)位輸出低電平,松開按鍵時(shí)keyout對(duì)應(yīng)位恢復(fù)高電平輸出。 由以上程序我們完成了矩陣鍵盤的驅(qū)動(dòng),但是keyout這種類型的輸出有時(shí)在后級(jí)時(shí)序電路設(shè)計(jì)中不好直接使用,例如對(duì)于當(dāng)前矩陣鍵盤鍵入系統(tǒng)設(shè)計(jì)來講,我們需要按鍵按動(dòng)一次(與按下保持的時(shí)間長(zhǎng)短無(wú)關(guān))就輸入對(duì)應(yīng)的鍵值,按鍵松開后鍵值也不能消失,我們就需要一個(gè)寄存器變量來儲(chǔ)存按過的按鍵鍵值,考慮到可能存在多個(gè)按鍵在極短時(shí)間內(nèi)被先后按下,這樣一來我們最好將按鍵按動(dòng)這種長(zhǎng)時(shí)間事件轉(zhuǎn)化成一個(gè)瞬間的脈沖,方法就是對(duì)key_out信號(hào)中的每一位進(jìn)行下降沿(或上升沿)檢測(cè),方法如下:
下降沿檢測(cè)程序?qū)崿F(xiàn)如下:
reg [15:0] key_out_r;//Register low_sw_r, lock low_sw to next clk always @ ( posedge clk or negedge rst_n ) if (!rst_n) key_out_r <= 16'hffff; else key_out_r <= key_out; //將前一刻的值延遲鎖存 //wire [15:0] key_pulse; //Detect the negedge of low_sw, generate pulse assign key_pulse= key_out_r & ( ~key_out); //通過前后兩個(gè)時(shí)刻的值判斷
經(jīng)過上面程序的處理,我們就得到了16位脈沖信號(hào),平時(shí)為低電平,當(dāng)按鍵被按下時(shí)刻keypulse產(chǎn)生一個(gè)高脈沖,脈沖的寬度為模塊系統(tǒng)時(shí)鐘clkin的一個(gè)周期。
在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分我們已經(jīng)掌握了FPGA驅(qū)動(dòng)獨(dú)立顯示數(shù)碼管的原理及方法, 模塊通過一個(gè)4位的輸入傳遞要顯示的數(shù)值,通過9位的輸出控制數(shù)碼管顯示該數(shù)值,這里我們不再重復(fù)。 矩陣鍵盤驅(qū)動(dòng)模塊輸出的是脈沖信號(hào),后面數(shù)碼管驅(qū)動(dòng)模塊輸入的是用4位位寬表示的數(shù)據(jù),所以中兩個(gè)實(shí)例之間就需要一個(gè)編碼的功能塊,主要功能是根據(jù)矩陣鍵盤的脈沖輸出(keypulse)判定鍵盤的操作,通過編碼對(duì)應(yīng)提供按鍵的鍵值數(shù)據(jù)(segdata),最后通過連線將鍵值數(shù)據(jù)連接到數(shù)碼管模塊的輸入端口。
鍵值顯示轉(zhuǎn)碼程序?qū)崿F(xiàn)
//key_pulse transfer to seg_data always@(posedge clk or negedge rst_n) begin if(!rst_n) begin seg_data <= 8'h00; end else begin case(key_pulse) //key_pulse脈寬等于clk_in的周期 16'h0001: seg_data <= 8'h01; //編碼 16'h0002: seg_data <= 8'h02; 16'h0004: seg_data <= 8'h03; 16'h0008: seg_data <= 8'h04; 16'h0010: seg_data <= 8'h05; 16'h0020: seg_data <= 8'h06; 16'h0040: seg_data <= 8'h07; 16'h0080: seg_data <= 8'h08; 16'h0100: seg_data <= 8'h09; 16'h0200: seg_data <= 8'h10; 16'h0400: seg_data <= 8'h11; 16'h0800: seg_data <= 8'h12; 16'h1000: seg_data <= 8'h13; 16'h2000: seg_data <= 8'h14; 16'h4000: seg_data <= 8'h15; 16'h8000: seg_data <= 8'h16; default: seg_data <= seg_data; //無(wú)按鍵按下時(shí)保持 endcase end end
綜合后的設(shè)計(jì)框圖如下:
按動(dòng)矩陣鍵盤上的按鍵,核心板獨(dú)立顯示數(shù)碼管會(huì)更新顯示對(duì)應(yīng)鍵值。例如上電默認(rèn)顯示00,按動(dòng)K8按鍵,數(shù)碼管顯示08,再按動(dòng)K16按鍵,數(shù)碼管顯示16。
評(píng)論