赞
踩
1. 学习动态扫描显示数码管的使用。
2. 学习数据选择器及其信号分配方法。
3. 巩固 Verilog HDL 层次化设计电路的方法。
多位数码管的显示电 路如果每一位都单独连接 到驱动(控制)器上,需要 非常多的引脚和布线通道, 实际使用中,为了降低成本、 方便 PCB 布局布线,常使用 动态显示数码管。 右图是 1 种 4 位共阴型 数码管的引脚图。
A,B,C,D,E,F,G,DP 是段选 (行)引脚,
SEG1,SEG2,SEG3,SEG4 是 位选(列)引脚。 对于共阴型数码管,段 信号是高电平有效,位选信 号是低电平有效。整个数码管共用同一组段信号(引脚)。实验室所用的数字电路实验箱上, 数码管的位选信号经过一个 NPN 型三极管放大驱动能力之后连接到数码管的位选引脚,信 号被三极管反相,因此,进行 FPGA 程序设计时位选信号应设计成高电平有效。数码管的 驱动信号时序图可参考下图。 段信号 Data1 Data2 Data3 Data4 Data1 … SEG1 SEG2 SEG3 SEG4 4 位动态扫描显示数码管驱动信号时序图
4 位动态扫描显示数码管的位选信号可看作是 4 相时钟,占空比 25%,位选信号为高电 平时将需要显示的数据送到数码管译码器上译码,再将译码输出送到数码管的段信号。 从上述时序图可以看出,在 SEG1 为高电平时,SEG1 位数码管被选中驱动,Data1 被 送到 7 段译码器中译码,此时数码管的 SEG1 位显示 Data1 的数值,其它几位数码管不亮; 在下一个时钟相位,SEG2 为高电平,SEG2 显示 Data2 的数据…在第四个时钟相位 SEG4
显示 Data4 之后,一个显示周期结束,电路将开始下一个显示周期。由于人眼的视觉暂留,
西南交通大学 电子技术实验室
当 SEG 位选信号切换得足够快(100Hz 以上),在人眼看来,数码管的所有位都同时点亮。 使用可编程芯片(FPGA/CPLD)控制多位动态扫描数码管显示时,一般需要使用计数 器、译码器等模块电路,电路原理可参考下图“4 位动态扫描数码管显示驱动电路框图”。
Data1,Data2,Data3,Data4 为 BCD 码数据,对应数码管上显示的千、百、十、个位显示的数 值。“位信号驱动电路”和“7 段数码管”是可编程芯片之外的单独电路元件,其余部分都 需要编程实现,为了获得频率 1000Hz 左右的扫描时钟,还需要设计一个前置分频器,将
50MHz 的系统时钟分频。
注意,因为位信号驱动电路和数码管的切换速度都不高,一般最高只能几 kHz,所以 扫描时钟频率并非越高越好,否则数码管的亮度可能会降低,甚至显示错误。
扫描时钟 Data4 Data3 Data2 Data1 4选1数据选择器 7段译码器
7段数码管 2-4线译码器 位信号驱动电路 模4计数器 约1000Hz
实验要求: 用 Verilog HDL 设计一个 3 位数码管动态扫描显示电路,在实验箱的数码管上固定显示 显示自己学号的后 3 位数(学号后 3 位全 0 则显示 321)。采用层次化设计方法,只能调用 1
个 7 段译码器。
1. 在基本实验内容的基础上,增加一个功能切换控制开关,切换功能后,数码管显示 的数字可以自动循环移位。
2. 其它显示功能。
1. 简要写出电路设计思路。
2. 完成实验程序代码编写。
3. 用 ModelSim 对实验电路进行功能仿真,并将仿真结果截图。除了观察输出引脚上 的电平,还应该观察中间信号——数据选择器的输出 Y,确保所有信号都是正确的 再进行下一步实验。
4. 列出引脚锁定分配表(信号名->主板器件名->引脚号),实验箱上的数码管段信号 命名为小写字母,位信号命名是 SEG0~SEG7。
1. 列出关键程序代码。
2. 附 Quartus 生成的 RTL 图(菜单 Tools -> Netlist Viewers –>RTL)。
3. 附仿真测试波形。
4. 列出实验过程出现的问题及解决措施。
5. 附源程序(截图)
1. 连接外部信号:连接包括时钟信号clk、复位信号rstn,以及从模块输出的七段数码管的段选信seg、选择信号sel、显示输出值tub和控制信号con。
2. 操作控制:根据需要,通过更改控制信号con的值来选择不同的数字进行显示。具体的操作如下:
(1)初始状态下,con为0。
(2)通过递增con的值,由高位到低位切换要显示的数字。每次递增con时,选择信号sel 和显示值tub会根据con的值更新。具体操作是:
①当con为0时,选择信号sel为3'b100(对应第一个数码管),显示值tub为4'd9。
②当con为1时,选择信号sel为3'b010(对应第二个数码管),显示值tub为4'd0。
③当con为2时,选择信号sel为3'b001(对应第三个数码管),显示值tub为4'd2。
④当con` 超过2时,控制信号con会被重置为0,并标志位flag会设置为1(flag的作用是复位的时候con从0开始而不是1开始),以开始下一个循环。
3. 七段数码管显示:模块会根据sel和tub的值选择要在数码管上显示的数字。具体的显示值已经在代码中定义,通过case语句进行匹配,将seg设置为相应的七段数码管段选信号,以显示正确的数字。
4. 复位功能:在系统初始化或复位时,确保复位信号rstn为低电平。这会将所有输出信号复位为零,以确保初始化状态。
5. 时钟信号生成:模块内部的计数器cnt会生成1kHz的时钟信号clk1k用于控制数码管的刷新。
- module qwq(
- input clk,
- input rstn,
- output reg [6:0] seg, // 数码管
- output reg [7:0] sel, // 选择位数
- output reg [3:0] tub, // 输出的数
- output reg [1:0] con // 控制赋值哪位
- );
- reg [31:0] cnt; // 16位寄存器,用于计数
- reg clk1k; // 时钟信号,1kHz的时钟
- reg flag;
- reg [3:0] k1 = 4'd9;
- reg [3:0] k2 = 4'd0;
- reg [3:0] k3 = 4'd2;
- always @ (posedge clk or negedge rstn) // 时钟上沿或下沿
- begin
- if (!rstn) // 如果复位信号为低电平
- begin
- cnt <= 0; // 计数器复位为0
- clk1k <= 0; // 1kHz时钟信号复位为低电平
- end
- else if (cnt >= 24999999) // 如果计数达到24999(1kHz频率下1秒的计数值)
- begin
- clk1k <= !clk1k; // 切换1kHz时钟信号的状态
- cnt <= 0; // 计数器复位为0
- end
- else
- cnt <= cnt + 1; // 计数器递增
- end
- always @ (posedge clk1k or negedge rstn)
- begin
- if (!rstn) // 如果复位信号为低电平
- begin
- tub <= 0; // 七段数码管显示值复位为0
- con <= 0; // 控制信号复位为0
- sel <= 0; // 选择信号复位为0
- seg <= 0; // 段选信号复位为0
- flag <= 0;
- end
- else
- begin
- if (con < 2 && flag == 1)
- con = con + 1'd1; // 控制信号递增
- else
- begin
-
- con = 0; // 控制信号复位为0
- flag = 1'd1;
- end
- case(con) // 根据控制信号值进行不同的操作
- 2'b00:begin sel = 8'b0000_0100;tub = k1;end
- 2'b01:begin sel = 8'b0000_0010;tub = k2;end
- 2'b10:begin sel = 8'b0000_0001;tub = k3;end
- endcase
- //调用数码管
-
- case(tub) // 根据七段数码管显示值进行不同的操作
- 4'd0: seg = 7'b1111110;
- 4'd1: seg = 7'b0110000;
- 4'd2: seg = 7'b1101101;
- 4'd3: seg = 7'b1111001;
- 4'd4: seg = 7'b0110011;
- 4'd5: seg = 7'b1011011;
- 4'd6: seg = 7'b1011111;
- 4'd7: seg = 7'b1110000;
- 4'd8: seg = 7'b1111111;
- 4'd9: seg = 7'b1111011;
- default: seg = 7'b0000001; // 将大于9的数显示为-负号
- endcase
- end
- end
- endmodule

- `timescale 1ns/1ns // 定义时间单位,1ns为仿真时间单位,10ns为仿真时间精度
- module emm();
- reg clk; // 时钟信号
- reg rstn; // 同步复位信号
- wire [6:0] seg; // 7位数码管的段选信号
- wire [7:0] sel; // 3位数码管的选择信号
- wire [3:0] tub; // 4位七段数码管显示的值
- wire [1:0] con; // 控制信号
- wire [11:0] number;
- initial
- begin
- clk = 1'b0; // 初始化时钟为低电平
- rstn = 1'b0; // 初始化同步复位信号为低电平
- #100 // 延时100个时间单位(1ns),持续100ns
- rstn = 1'b1; // 同步复位信号变为高电平
- // #10000 // 延时100000个时间单位(1ns),持续100ns
- // rstn = 1'b0; // 同步复位信号重新变为低电平
- // #10000 // 延时100000个时间单位(1ns),持续100ns
- // rstn = 1'b1; // 同步复位信号重新变为低电平
- end
-
- always #(1) clk = ~clk; // 时钟信号每1ns翻转一次,周期为2ns,频率为50MHz
- qwq dfun(
- .clk(clk),
- .rstn(rstn),
- .seg(seg),
- .sel(sel),
- .tub(tub),
- .con(con),
- .number(number)
- );
- endmodule

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。