目录
四位同时显示 16进制计数器
module KC8(seg,dig,clock);
input clock;
output [7:0] seg; //
output [3:0] dig; //
reg [7:0] seg; //
reg [3:0] disp_dat; //
reg [36:0] count; //
assign dig= 4'b0000;
always @ (posedge clock )
begin
count <= count + 1;
//if(count[24]!=0)
// disp_dat <= count[28:25];
// dig<= 4'b0110;//
end
always @ (count[24])
begin
disp_dat = count[28:25];
end
always @ (disp_dat)
begin
case (disp_dat)
4'h0 : seg = 8'hc0; //ʾ"0"
4'h1 : seg = 8'hf9; //ʾ"1"
4'h2 : seg = 8'ha4; //ʾ"2"
4'h3 : seg = 8'hb0; //ʾ"3"
4'h4 : seg = 8'h99; //ʾ"4"
4'h5 : seg = 8'h92; //ʾ"5"
4'h6 : seg = 8'h82; //"6"
4'h7 : seg = 8'hf8; //"7"
4'h8 : seg = 8'h80; //"8"
4'h9 : seg = 8'h90; //"9"
4'ha : seg = 8'h88; //"a"
4'hb : seg = 8'h83; //"b"
4'hc : seg = 8'hc6; //"c"
4'hd : seg = 8'ha1; //"d"
4'he : seg = 8'h86; //"e"
4'hf : seg = 8'h8e; //"f"
endcase
end
endmodule
注:count[24:28]第二十四位到二十八位 这样写起到了延时的效果
单个数码管十进制计数器
module KC11(seg,dig,clock);
input clock;
output reg [7:0] seg; //
output reg [3:0] dig; //
reg [4:0] disp_dat; //
reg [36:0] counter1; //
reg [36:0]Counter16;
reg Scan_Clk;
reg [4:0]st1;
always @ (posedge clock )
begin
counter1 <= counter1 + 1'b1;//每个时钟周期加1
if(counter1>=5000000)//如果满5000000
begin
Scan_Clk<=~Scan_Clk;//取反
counter1<=0;//归零
end
end
always @ (posedge Scan_Clk )//每个Scan_Clk周期
begin
case(st1)
0:begin
dig<=4'b1110;//第四个数码管
disp_dat<=4'h0;//显示0
st1<=1;//改变st1 这样就可以每个Scan_Clk周期显示不同的值
end
1:begin
dig<=4'b1110;
disp_dat<=4'h1;
st1<=2;
end
2:begin
dig<=4'b1110;
disp_dat<=4'h2;
st1<=3;
end
3:begin
dig<=4'b1110;
disp_dat<=4'h3;
st1<=4;
end
4:begin
dig<=4'b1110;
disp_dat<=4'h4;
st1<=5;
end
5:begin
dig<=4'b1110;
disp_dat<=4'h5;
st1<=6;
end
6:begin
dig<=4'b1110;
disp_dat<=4'h6;
st1<=7;
end
7:begin
dig<=4'b1110;
disp_dat<=4'h7;
st1<=8;
end
8:begin
dig<=4'b1110;
disp_dat<=4'h8;
st1<=9;
end
9:begin
dig<=4'b1110;
disp_dat<=4'h9;
st1<=0;
end
endcase
end
always @ (st1) // posedge Scan_Clk
begin
case (disp_dat)
4'h0 : seg = 8'hc0; // ʾ"0"
4'h1 : seg = 8'hf9; //ʾ"1"
4'h2 : seg = 8'ha4; //ʾ"2"
4'h3 : seg = 8'hb0; //ʾ"3"
4'h4 : seg = 8'h99; //ʾ"4"
4'h5 : seg = 8'h92; //ʾ"5"
4'h6 : seg = 8'h82; //ʾ"6"
4'h7 : seg = 8'hf8; //ʾ"7"
4'h8 : seg = 8'h80; //ʾ"8"
4'h9 : seg = 8'h90; //ʾ"9"
endcase
end
endmodule
四位数码管十进制计数器
代码
主模块
module jishuqi10(seg,dig,clock); //模块名与输入输出
input clock; //主时钟,50M
output [7:0] seg; //8段LED
output [3:0] dig; //4位位选线
reg [7:0] seg; //寄存器输出
reg [3:0] dig; //
reg [3:0] disp_dat; //当前位显示的数据
reg [36:0] counter;
reg [36:0] counter1; //分频用计数器
wire [24:0] Counter16;//测试用计数器
reg Scan_Clk;//扫描时钟
reg [1:0] st1;//四状态状态机
reg clock1;
wire OC1,OC2,OC3,OC4;
reg [36:0]cnt1;
always @ (posedge clock )
begin
counter1 <= counter1 + 1'b1;
//Counter16<=counter16+1'b1;
if(counter1>=50000)
begin
Scan_Clk<=~Scan_Clk;
counter1<=0;
end
end
//同上 定时转换四位数码管 实现同时显示
always @ (posedge Scan_Clk)
begin
case(st1)
2'd0:begin
dig<=4'b1110;
disp_dat<=Counter16[3:0];
st1<=1;
end
2'd1:begin
dig<=4'b1101;
disp_dat<=Counter16[7:4];
st1<=2;
end
2'd2:begin
dig<=4'b1011;
disp_dat<=Counter16[11:8];
st1<=3;
end
2'd3:begin
dig<=4'b0111;
disp_dat<=Counter16[15:12];
st1<=0;
end
endcase
end
//把所有可能列出来 不同的disp_dat 对应不同的数
always @ (st1)
begin
case (disp_dat)
4'h0 : seg = 8'hc0; //��ʾ"0"
4'h1 : seg = 8'hf9; //��ʾ"1"
4'h2 : seg = 8'ha4; //��ʾ"2"
4'h3 : seg = 8'hb0; //��ʾ"3"
4'h4 : seg = 8'h99; //��ʾ"4"
4'h5 : seg = 8'h92; //��ʾ"5"
4'h6 : seg = 8'h82; //��ʾ"6"
4'h7 : seg = 8'hf8; //��ʾ"7"
4'h8 : seg = 8'h80; //��ʾ"8"
4'h9 : seg = 8'h90; //��ʾ"9"
4'ha : seg = 8'h88; //��ʾ"a"
4'hb : seg = 8'h83; //��ʾ"b"
4'hc : seg = 8'hc6; //��ʾ"c"
4'hd : seg = 8'ha1; //��ʾ"d"
4'he : seg = 8'h86; //��ʾ"e"
4'hf : seg = 8'h8e; //��ʾ"f"
endcase
end
reg i;//定义计时时钟 控制计数速度
always@(posedge clock)
begin
if(cnt1==5000000)
begin
i<=~i;
cnt1<=0;
end
else cnt1<=cnt1+1;
end
//连接分模块 实现十进制计数
couter10 A1(
.cnt(i),//时钟相连
.counter(Counter16[3:0]),//数码管显示
.OC(OC1)//计数进制
);
couter10 A2(
.cnt(OC1),//我们注意到 这里连接的就是OC1了 因为个位不断进位 我们把十位当时钟就实
//现了我们想要的计数器效果
.counter(Counter16[7:4]),
.OC(OC2)
);
couter10 A3(
.cnt(OC2),
.counter(Counter16[11:8]),
.OC(OC3)
);
couter10 A4(
.cnt(OC3),
.counter(Counter16[15:12]),
.OC(OC4)
);
endmodule
分模块
module couter10(cnt,counter,OC);
input cnt;
output [3:0] counter;
output OC;
reg OC;
reg [3:0] counter;
reg[16:0] cnt1;
reg [16:0] clk_1s;
//满10进1 实现十进制
always @ (posedge cnt )
begin
if(counter<9)
begin
counter<=counter+1;
OC<=0;
end
else
begin
counter<=0;
OC<=1;
end
end
endmodule
分析
代码部分的含义已经通过注释来说明了 因为代码比较长 帮大家整理一下整体的思路
我们首先要实现 十进制的转换 这里就是分模块的内容 我们是实现了十进制 然后实现了进位
接着 我们还是要实现四位同时显示 也就是定义一个间隔相对较短的时钟 分别扫描段选
来实现四个数码管同时显示
接着 我们通过计数 然后来实现不同数字的计数增加 也就是disp_dat<=Counter16[3:0];
通过给disp_dat赋值 通过case 来选择不同的数显示
然后就需要定义一个时钟来实现计数器计数的时间间隔
最后就是连接分模块
我最初学数码管的时候也是昏昏的 我明明看懂了原理却看不懂代码 很苦恼
这是一个慢慢熟悉的过程 需要静下来多看几遍