AC620FPGA学习笔记——BCD数码管

BCD数码管

工程地址:https://github.com/HaHaHaHaHaGe/Planof2019_half/tree/master/Course_Project/FPGA/class03_hc595
实现8个8位数码管,根据分频后的时钟自动计数(16进制)

硬件结构

开发板:AC620
在这里插入图片描述

整体框架

在这里插入图片描述

BCDDisplay模块

在这里插入图片描述
根据输入的data每4位为1组,共8组,对应8个数码管,轮询进行刷新

device_74hc595模块

在这里插入图片描述
根据输入的并行数据输出串行数据,每次输出后会产生锁存脉冲(lock),在输出过程中会产生busy高电平信号,等传输完毕后恢复低电平。

代码部分

device_74hc595

module device_74hc595(
	clk,
	rst,
	data,
	busy,
	lock,
	lock595,
	out595,
	clk595
);

input clk,rst,lock;
input [15:0]data;
output reg lock595,clk595,busy,out595;

reg [4:0]send_cnt;
reg [15:0]data_buffer;

reg [1:0]flag;
localparam SEND_STATE = 2'b00;
localparam LOCK0_STATE = 2'b01;
localparam LOCK1_STATE = 2'b11;
localparam IDLE_STATE = 2'b10;

always@(posedge clk,negedge rst) 
if(!rst)begin
	send_cnt <= 5'b0;
	busy <= 1'b0;
	data_buffer <= 16'b0;
	flag <= IDLE_STATE;
	lock595 <= 1'b0;
	clk595 <= 1'b1;
	out595 <= 1'b0;
end
else 
	case(flag)
		SEND_STATE:
			if(clk595) begin
				if(send_cnt == 5'd16)
					flag <= LOCK0_STATE;
				else begin
					send_cnt <= send_cnt + 5'b1;
					out595 <= data_buffer[5'd15-send_cnt];
					clk595 <= 1'b0;
				end
			end
			else begin
				clk595 <= 1'b1;
			end
		LOCK0_STATE: begin
			lock595 <= 1'b1;
			flag <= LOCK1_STATE;
			end
		LOCK1_STATE: begin
			lock595 <= 1'b0;
			flag <= IDLE_STATE;
			end
		
		IDLE_STATE:
			if(lock)begin
				send_cnt <= 5'b0;
				data_buffer <= data;
				busy <= 1'b1;
				flag <= SEND_STATE;
			end
			else
				busy <= 1'b0;
		default:
			flag <= IDLE_STATE;
	endcase
endmodule

BCDdecoder

module BCDdecoder(
	data,
	out
);
input [3:0]data;
output reg [7:0]out;
always@(*)
case(data)
 4'h0:out = 7'b1000000;             
 4'h1:out = 7'b1111001;             
 4'h2:out = 7'b0100100;             
 4'h3:out = 7'b0110000;             
 4'h4:out = 7'b0011001;             
 4'h5:out = 7'b0010010;             
 4'h6:out = 7'b0000010;             
 4'h7:out = 7'b1111000;             
 4'h8:out = 7'b0000000;             
 4'h9:out = 7'b0010000;             
 4'ha:out = 7'b0001000;             
 4'hb:out = 7'b0000011;             
 4'hc:out = 7'b1000110;             
 4'hd:out = 7'b0100001;             
 4'he:out = 7'b0000110;             
 4'hf:out = 7'b0001110; 
endcase
  
endmodule

frequencydivider

module frequencydivider(
	clk,
	rst,
	fclk
);

input clk,rst;
output reg fclk;

reg [31:0]cnt;

always@(posedge clk,negedge rst)
if(!rst) begin
	cnt <= 0;
	fclk <= 0;
end
else if(cnt == 500) begin
	cnt <= 0;
	fclk <= ~fclk;
end
else
	cnt <= cnt + 1;
	
endmodule

BCDDisplay

module BCDDisplay(
	clk,
	rst,
	data,
	lock595,
	out595,
	clk595
);
wire fclk;
input clk,rst;
input [31:0]data;
output lock595,out595,clk595;
reg flag;
reg [7:0]selecter;
reg [7:0]srcdata;
wire [7:0]dstdata;
reg [31:0]data_buffer;
reg lock;
wire busy;
reg doonce;
reg [7:0]cnt;

localparam Wait_Busy = 1'b0;
localparam Circle_Play = 1'b1;

BCDdecoder BCDdecoder_01(
	.data(srcdata),
	.out(dstdata)
);

frequencydivider frequencydivider_01(
	.clk(clk),
	.rst(rst),
	.fclk(fclk)
);

device_74hc595 device_74hc595_01(
	.clk(fclk),
	.rst(rst),
	.data({dstdata,selecter}),
	.busy(busy),
	.lock(lock),
	.lock595(lock595),
	.out595(out595),
	.clk595(clk595)
);
always@(posedge clk,negedge rst)
if(!rst) begin
	selecter <= 8'b0000_0001;
	data_buffer <= 32'b0;
	flag <= Circle_Play;
	srcdata <= 8'b0;
	lock <= 0;
	cnt <= 8'd4;
	doonce <= 0;
end
else begin
	data_buffer <= data;
	case(flag)
		Circle_Play: begin
			srcdata <= data_buffer >> cnt;
			selecter <= {selecter[6:0],selecter[7]};
			flag <= Wait_Busy;
			doonce <= 0;
			
			if(cnt == 8'd28)
				cnt <= 8'b0;
			else
				cnt <= cnt + 4;
		end
		Wait_Busy:
			if(busy) begin
				lock <= 0;
				doonce <= 1;
			end
			else if(doonce)
				flag <= Circle_Play;
			else
				lock <= 1;
	endcase
end
endmodule

顶层代码

module test_74hc595(
	clk,
	rst,
	key,
	lock595,
	out595,
	clk595
);
wire lock;
input clk;
input wire rst,key;
wire rst2;
reg [31:0]data;

output lock595,out595,clk595;

wire rst3;
wire clk2;

inkey inkey_1(
	.in(key),
	.out(lock),
	.clk(clk)
);

inkey inkey_2(
	.in(rst),
	.out(rst2),
	.clk(clk)
);


BCDDisplay BCDDisplay_1(
	.clk(clk),
	.rst(rst3),
	.data(data),
	.lock595(lock595),
	.out595(out595),
	.clk595(clk595)
);

frequencydivider frequencydivider2(
	.clk(clk),
	.rst(rst3),
	.fclk(clk2)
);


always @(negedge rst3,posedge clk2)
begin
if(!rst3)
	data <= 0;
else
	data <= data + 1;
end

assign rst3 = ~rst2;

endmodule

猜你喜欢

转载自blog.csdn.net/weixin_41738734/article/details/84108767