TA的每日心情 | 郁闷 2017-12-4 18:33 |
---|
签到天数: 94 天 连续签到: 1 天 [LV.6]常住居民II
|
上一篇教程介绍了单个数码管的驱动,本教程则介绍如何驱动4位数码管,同时显示0-9999计数。
等学会这个之后,不管多少位,你都可以迎刃而解。
先介绍一下4位数码管管脚说明:
每个数码管的公共极为SEG*,其余引脚公用。
本实验采用的是共阴极4位数码管。
因此当需要点亮第一个数码管的a段,则需要将数码管的SEG1置0,a引脚置1,当然这之间需要加限流电阻。
同理,当需要点亮第二个数码管的a段,则切换数码管的SEG2置0即可。
假设需要用该数码管显示1234,则需要将数码管公共极SEG*轮流置0,同时在当SEGx为0是,段码a_to_g_dp显示相应的数据。比如SEG1=0,其余SEGx均为1时,则段码a_to_g_dp引脚则为1的译码值。这个过程成为动态扫描。
这里有个故事,之前有个群里同学说这个动态扫描的形成是因为数码管有余光,没有完全熄灭,导致人眼看上去像多位同时显示。义正言辞,差点把我说蒙了。。。
动态扫描的主要程序如下:
always@(posedge clk,posedge rst)begin if(rst) sel <= 4'b1111; else begin case(count[10:9]) 2'b00:begin sel <= 4'b1110; data <= bcd[3:0]; end 2'b01:begin sel <= 4'b1101; data <= bcd[7:4]; end 2'b10:begin sel <= 4'b1011; data <= bcd[11:8]; end 2'b11:begin sel <= 4'b0111; data <= bcd[15:12]; end default:begin sel <= 4'b1111; data <= 4'bxxxx; end endcase end end上述代码并不包含bcd-7seg译码过程。
接下来,进行计数器设计。
主要有两种,一、先用二进制进行计数,计数至9999时赋零,再通过二进制到BCD码转换,最后进行译码显示。二、直接利用BCD码进行计数,再译码显示。
第一种方法在计数范围小的情况下可以采用。但是一旦计数范围达到几千几万,则建议采取第二种方法。
以十位数为例,主要代码如下:
//ten always@(posedge clk,posedge rst)begin if(rst) bcd_reg[7:4] <= 0; else begin if(clk_1s && bcd_reg[3:0] == 4'd9)begin if(bcd_reg[7:4] == 4'd9) bcd_reg[7:4] <= 0; else bcd_reg[7:4] <= bcd_reg[7:4] + 1'b1; end end end需要注意的是,当前位数据的计数判断需要同时满足计数时钟和之前所有位数据均为9。
接线有点凌乱,还望见谅! |
|