基於FPGA的密碼鎖開發——(2)定製化數碼管顯示模塊驅動

這一篇記錄定製化數碼管顯示模塊的驅動開發
數碼管的原理再常見不過了,只不過數碼管也分共陰極和共陽極的,這兩種的寫法是相反的

爲這個課題採購的數碼管來源於淘寶Telsky旗艦店哈哈,我也算是他家老生意了
在這裏插入圖片描述
在這裏插入圖片描述
無非就是讓這個模塊改成參數化傳遞的罷了,和以前寫過的沒啥大的區別

`define SIM
module	Seg_disp_sim
#(
	parameter					MODE = 1//共陽
)
(
	input						System_Clk	,//系統時鐘
	input						Rst_n		,//系統復位
	input	[3:0]				data_0		,//第0位數據
	input	[3:0]				data_1		,//第1位數據
	input	[3:0]				data_2		,//第2位數據		
	output	reg	[6:0]			Dig			,//段選
	output	reg					Dp			,//小數點
	output	reg	[2:0]			Sel			 //位選
//others
);
//Parameters and Defines
`ifndef SIM
	localparam					Sample_end = 49999;//掃描週期1ms
`else
	localparam					Sample_end = 49;
`endif
//Regs
	reg	[3:0]					data_0_r;			//第0位數據寄存器
	reg	[3:0]					data_1_r;           //第1位數據寄存器
	reg	[3:0]					data_2_r;           //第2位數據寄存器
	reg	[3:0]					data_reg;			//實時顯示數據寄存器
	reg	[2:0]					bit_cnt;			//掃描位數計數器
	reg							bit_flag;			//掃描週期計滿標誌
	reg	[15:0]					sample_cnt;			//掃描週期計數器
//Main Code
	//data_0-5_reg
	always	@(posedge System_Clk or negedge	Rst_n)begin
		if(Rst_n == 1'b0)begin
			data_0_r <= 'd0;
			data_1_r <= 'd0;
			data_2_r <= 'd0;
		end
		else if(bit_cnt==3'd0 && sample_cnt==16'd0)begin//在一開始採樣一次待顯示數據並鎖存
			data_0_r <= data_0;//sample at bit0
			data_1_r <= data_1;
			data_2_r <= data_2;
		end
	end
	//bit_flag 掃描週期計數器計滿,計滿標誌發生一個脈衝
	always	@(posedge System_Clk or negedge Rst_n)begin
		if(Rst_n==1'b0)
			bit_flag <= 1'b0;
		else if(sample_cnt==Sample_end)
			bit_flag <= 1'b1;
		else
			bit_flag <= 1'b0;
	end
	//bit_cnt	//掃描位數計數器累加邏輯
	always	@(posedge System_Clk or negedge Rst_n)begin
		if(Rst_n==1'b0)
			bit_cnt <= 'd0;
		else if(bit_cnt == 3'd2 && bit_flag==1'b1)
			bit_cnt <= 'd0;
		else if(bit_flag==1'b1)
			bit_cnt <= bit_cnt + 1'b1;
	end
	//data_reg	//根據掃描位數選擇對應數據
	always	@(*)begin
			case(bit_cnt)
				3'd0:data_reg = data_0_r;
				3'd1:data_reg = data_1_r;
				3'd2:data_reg = data_2_r;
            default:data_reg = 4'h0;
			endcase
	end
	//sample_cnt	掃描計數器邏輯
	always	@(posedge System_Clk or negedge Rst_n)begin
		if(Rst_n==1'b0)
			sample_cnt <= 'd0;
		else if(sample_cnt==Sample_end)
			sample_cnt <= 'd0;
		else
			sample_cnt <= sample_cnt + 1'b1;
	end
	//Dig	//根據數碼管顯示錶
	always	@(*)begin
		case(data_reg)
			4'h0:Dig = MODE?~7'b1111110:7'b1111110;
			4'h1:Dig = MODE?~7'b0000110:7'b0000110;
			4'h2:Dig = MODE?~7'b1101101:7'b1101101;
			4'h3:Dig = MODE?~7'b1111001:7'b1111001;
			4'h4:Dig = MODE?~7'b0110011:7'b0110011;
			4'h5:Dig = MODE?~7'b1011011:7'b1011011;
			4'h6:Dig = MODE?~7'b1011111:7'b1011111;
			4'h7:Dig = MODE?~7'b1110000:7'b1110000;
			4'h8:Dig = MODE?~7'b1111111:7'b1111111;
			4'h9:Dig = MODE?~7'b1111011:7'b1111011;
			/*
			4'ha:Dig = MODE?~7'b0000001:7'b0000001;
			4'hb:Dig = MODE?~7'b0000000:7'b0000000;
			4'hc:Dig = MODE?~7'b0000000:7'b0000000;
			4'hd:Dig = MODE?~7'b0000000:7'b0000000;
			4'he:Dig = MODE?~7'b0000000:7'b0000000;
			4'hf:Dig = MODE?~7'b0000000:7'b0000000;
			*/
			default:Dig = MODE?7'b1111111:7'b0000000;
		endcase
	end
	//sel 位選信號邏輯
	always	@(*)begin
		case(bit_cnt)
			3'd0:Sel = MODE?~3'b110:3'b110;//點亮右面第一個
			3'd1:Sel = MODE?~3'b101:3'b101;
			3'd2:Sel = MODE?~3'b011:3'b011;
			default:Sel = MODE?3'b000:3'b111;
		endcase
	end
endmodule

其中通過這種寫法可以以較低的代碼量實現需求

			4'h0:Dig = MODE?~7'b1111110:7'b1111110;
			4'h1:Dig = MODE?~7'b0000110:7'b0000110;
			4'h2:Dig = MODE?~7'b1101101:7'b1101101;
			4'h3:Dig = MODE?~7'b1111001:7'b1111001;
			4'h4:Dig = MODE?~7'b0110011:7'b0110011;
			4'h5:Dig = MODE?~7'b1011011:7'b1011011;
			4'h6:Dig = MODE?~7'b1011111:7'b1011111;
			4'h7:Dig = MODE?~7'b1110000:7'b1110000;
			4'h8:Dig = MODE?~7'b1111111:7'b1111111;
			4'h9:Dig = MODE?~7'b1111011:7'b1111011;

代碼能少寫點就少些點了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章