IT技术之家

首页 > 硬件开发

硬件开发

FPGA学习汇总(六)----数码管显示(1)_辽G.默语_怎么让数码管同时显示不同的数字

发布时间:2022-10-24 16:58:38 硬件开发 0次 标签:FPGA 经验分享
FPGA学习总结,分享学习过程。...

目录

概念

单个数码管显示单个数字

?操作

?代码

?现象

分析

四个数码管定时单个显示数字

分析

代码

四个数码管同时显示

分析

代码

现象

?四个数码管同时显示定时转换

分析

代码


概念

我们要搞懂数码管首先要明白几个概念。

我们先看一个数码管

?

一个数码管是由a、b、c、d、e、f、g、dp八个二极管组成,八个LED一端接在一起,另一端引脚引出来。二极管如果阳极连在一起,就是共阳极数码管,阴极连在一起,就是共阴极数码管。

如上图,是一个共阴极数码管,要使数码管显示不同的数字,只需点亮对应LED即可。如:数码管显示“0”,则a、b、c、d、e、f六个LED亮,g、dp这俩个LED灭,即可显示“0”。

如果是一个数码管我们需要控制八个led来控制显示 如果是四个 理论上需要控制三十二个 太多了 我们这时候就引用了共阴和共阳的概念。

我们来看原理图(这里我这个板子是共阳,共阴同理)

一共只需要十二个引脚即可,四个段选 八个位选 通过D1234 不同的高低电平可以控制哪个数码管亮 通过给abcdefg dp 不同的高低电平 可以控制数码管显示什么

如果没学过51单片机的朋友可能还不理解如何实现控制四位数码管 看原理图 好像一个时刻只能显示一个数 这里运用了人类视觉的偏差 即当不同的数码管切换速度足够快 则可以出现同时显示的偏差 也就实现了四位数码管的显示?

接着我们先看

单个数码管显示单个数字

操作

这个就比较容易实现? 我们按照原理图找到对应引脚(有些可以自己定义)

在下面选择pin planner 配置自己的引脚 (自行配置)

?

?

配置好了之后 全局编译 然后导入板子

选中里面sof文件? 点击start 导入 (前面文章介绍过 这里也只简单介绍一遍)

?代码

module KC14(clk,rst,seg,sel);
input clk;
input rst;
output reg[7:0] seg;
reg[1:0] num;
output reg[3:0] sel;

always@(posedge clk or negedge rst)
		begin
begin
		if(!rst)
        seg<=8'b1111_1111;
        sel<=4'b1111;
end
else
		begin
		seg<=8'b1010_0100;//选位 亮具体哪个led 控制数码管显示数字
		sel<=4'b0111;//段选 控制哪个数码管亮
		end
		end
		
		endmodule

现象

分析:

简单分析一下 大家应该对verilog语言有了基础的认识 主要讲一下段选和位选

段选 因为是共阳 而是D1 D2 D3 D4 为高电平即可 但是我们可以注意到 我给的是0

因为我们原理图接了一个

当给0电平时导通 这样我们通过控制四位二进制 0000到 1111 来控制哪个数码管亮 也就是段选

然后我们在上面也介绍过 abcdefg dp(.) 这八个led 我们通过给0 来控制数码管显示什么数字

上面例子给的是?8'b1010_0100 也就是2 我们想实现不同的数字对应不同的八位二进制数 大家可以自己尝试改变一下。

四个数码管定时单个显示数字

分析

原理与上面类似 就不赘述了? 主要加了一个定时 和 不同数码管的切换 如果上面例子看懂了 这里直接看代码应该就可以看懂 这里实现的是四个数码管 1234 定时1s 每秒切换 1234 分别显示?

代码

module KC5(clk,rst,seg,sel);
input clk;
input rst;
output reg[7:0] seg;
reg[1:0] num;
output reg[3:0] sel;
reg[25:0] cnt;
reg[25:0] clk_1s;


always@(posedge clk or negedge rst)
	begin
		if(!rst)
		begin
cnt=0;
	end
	
	else if(cnt==26'd24_999_999)
cnt<=0;
else 
cnt<=cnt+1;
end
//1s周期控制部分
always@(posedge clk or negedge rst)
begin 
     if(!rst)
    clk_1s<=1;
 else if(cnt==26'd24_999_999)
      clk_1s<=~clk_1s;
else 
  clk_1s<=clk_1s;  
end
		always@(posedge clk_1s or negedge rst)
		begin
		if(!rst)
		begin
		seg<=8'b1111_1111;
		sel<=4'b0000;
		num<=0;
		end
		else
		begin
case(num)
			0:
			begin
			seg<=8'b1111_1001;
			sel<=4'b0111;
			num<=1;
			end
			
			
			1:
			begin
			seg<=8'b1100_0100;
			sel<=4'b1011;
			num<=2;
			end
			
			2:
			begin
			seg<=8'b1101_0000;
			sel<=4'b1101;
			num<=3;
			end
			
			3:
			begin
			seg<=8'b1001_1001;
			sel<=4'b1110;
			num<=0;
			end

			default:num<=0; 
		endcase
end
end
endmodule

现象就是数码管1 显示1 数码管2 显示2 数码管3显示3 数码管4显示4 依次每秒转换

四个数码管同时显示

分析

同一时刻 某个数码管 我们已经了解了 那么如何让四个数码管一起显示呢 这就需要我们在不同的段选中来回快速切换 当速度足够快时 就达到了我们想要的效果 四个数码管同时显示

代码

module KC6(clk,rst,seg,sel);

input clk;
input rst;
output reg [7:0] seg;
output reg [3:0] sel;
reg [1:0] num;
reg[16:0] cnt;
reg[16:0] clk_1s;

always@(posedge clk or negedge rst)
	begin
		if(!rst)
		begin
cnt=0;
	end
	
	else if(cnt==26'd24_999)
cnt<=0;
else 
cnt<=cnt+1;
end

always@(posedge clk or negedge rst)
begin 
     if(!rst)
    clk_1s<=1;
 else if(cnt==26'd24_999)//注意区别上面 这里的cnt比上面的少 也就是转换的快
      clk_1s<=~clk_1s;//所以此时clk_1s不是1s 
else 
  clk_1s<=clk_1s;  
end


always@(posedge clk_1s or negedge rst)
begin
if(!rst)
begin
seg<=8'b1111_1111;
sel<=4'b1111;
end

else
begin

case(num)
0:
begin
seg<=8'b1111_1001;
sel<=4'b0111;
num<=1;
end

1:
begin
seg<=8'b1010_0100;
num<=2;
sel<=4'b1011;
end

2:
begin
seg<=8'b1011_0000;
num<=3;
sel<=4'b1101;
end

3:
begin
seg<=8'b1001_1001;
num<=0;
sel<=4'b1110;
end

default:num<=0; 

endcase

end
end


endmodule

现象

?四个数码管同时显示定时转换

分析

我么已经知道如何同时显示了 那么我们只需要多定义一个时钟 然后把上面的代码包含进来 就可以实现四位数码管同时显示 定时转换

这里我们要实现的是数码管1234 分别显示1234和4321 两者定时转换

代码

module KC7(clk,rst,seg,sel);
output reg [7:0] seg;
output reg [3:0] sel;
input clk;
input rst;
reg num0;
reg [1:0] num1;
reg[26:0] clk1;
reg[26:0] cnt;
reg[26:0] clk_1s;
reg[26:0]clk_2s;

always@(posedge clk or negedge rst)
	begin
		if(!rst)
		begin
cnt=0;
	end
	
	else if(cnt==26'd24_999)
cnt<=0;
else 
cnt<=cnt+1;
end
//1s周期控制部分

always@(posedge clk )
begin 

  if(cnt==16'd24_999)
      clk_1s<=~clk_1s;
else 
  clk_1s<=clk_1s;  
end

always@(posedge clk_1s or negedge rst)
begin
if(!rst) 
begin
clk1<=0;
end

else if(clk1==16'd2499)
begin
clk_2s<=~clk_2s;
clk1<=0;
end

else
begin
 clk_2s=clk_2s;
clk1<=clk1+1;
if(num0==0)
begin
case (num1)
0:
begin
seg<=8'b1111_1001;
sel<=4'b0111;
num1<=1;
end

1:
begin
seg<=8'b1010_0100;
num1<=2;
sel<=4'b1011;
end

2:
begin
seg<=8'b1011_0000;
num1<=3;
sel<=4'b1101;
end

3:
begin
seg<=8'b1001_1001;
num1<=0;
sel<=4'b1110;
end

default:num1<=0; 
endcase

end

else
begin
case (num1)
0:
begin
seg<=8'b1001_1001;
sel<=4'b0111;
num1<=1;
end

1:
begin
seg<=8'b1011_0000;
num1<=2;
sel<=4'b1011;
end

2:
begin
seg<=8'b1010_0100;
num1<=3;
sel<=4'b1101;
end

3:
begin
seg<=8'b1111_1001;
num1<=0;
sel<=4'b1110;
end

default:num1<=0; 
endcase

end

end


end

always@(posedge clk_2s )
begin

num0=!num0;

end
endmodule

经验证 实验显现符合预期