[FPGA教程] Basys 3 现场可编程门阵列上的七段LED显示

这个 现场可编程门阵列教程 将指导您如何控制Basys 3上的4位七段显示器 现场可编程门阵列 板。显示控制器将在 Verilog 用于在显示屏的4位7段LED显示屏上显示数字 Basys 3 现场可编程门阵列。还将提供七段式LED显示控制器的完整Verilog代码。

Basys 3 现场可编程门阵列 有一个共阳极4位数字 7段LED显示屏 如下图所示。

现场可编程门阵列教程-Basys 3 现场可编程门阵列上的七段LED显示控制器

七段中的七个阳极单个LED中的s连接到一个公共阳极节点,而其阴极则分开,如下图所示。 DP段将照亮该点,因此我们现在省略DP段,因为它不影响点的数值。 七段显示.
现场可编程门阵列教程-Basys 3 现场可编程门阵列上的七段LED显示控制器
为了照亮A-G等LED区段,这些区段的阳极需要位于''逻辑电平和负极应位于'逻辑层次。因此,共阳极节点应高至 activate a single 七段式LED显示屏。阴极的逻辑电平可以从低(发光)到高(未发光)变化,以在单个7段LED显示器上显示不同的十进制值,如下所示。 
现场可编程门阵列教程-Basys 3 现场可编程门阵列上的七段LED显示控制器
如上图所示,我们可以在屏幕上显示从零到九的数字 七段式LED显示屏 通过打开和关闭单个七段LED显示屏的七个段。例如,要显示数字“1“在LED上,分段A,F,G,E和D未点亮或它们的阴极应高,而BC分段被点亮或它们的阴极应低。类似地,我们可以获得以下解码器表在七段式LED显示屏上显示十个数字:
[FPGA教程] Basys 3 现场可编程门阵列上的七段LED显示控制器

该表显示了在单个电极上显示相应数字所需的阴极图形 7段LED显示屏 Basys 3的 现场可编程门阵列 板。

目前,我们知道如何在显示屏上的单个七段LED显示屏上显示数字 Basys 3 现场可编程门阵列板。但是,Basys 3上的四个七段LED的阴极不是分开的,而是连接在一起,如下图所示。

现场可编程门阵列教程-Basys 3 现场可编程门阵列上的七段LED显示控制器
因此,要在4位七段LED显示器上显示4个不同的数字,我们必须通过在不同时间激活四个七段LED来分别控制四个七段LED的阴极(CA-CG)。例如,当我们通过将A1驱动为高电平来激活LED 1,而其他三个LED(LED 2,LED 3,LED 4)被停用(未驱动A2,A3和A4)时,阴极图案(CA-CG)将变为用于在LED 1上显示数字。类似地,LED 2-LED 4可以在不同的时间使用相同的方式显示。如上图所示,我们可以通过使用4个PNP晶体管AN0-AN3来控制激活四个7段LED。当晶体管导通或基极端子(W4,U4,V4或U2)为低时,相应的阳极被驱动为高电平,以激活或启用相应的七段式LED。 

点亮后停用LED时,它会变暗。为避免人眼察觉到的显示不连续性,四个七段LED应当以大约1KHz至60Hz的频率连续刷新,或者应每1ms至16ms的频率刷新一次。 


在这个 现场可编程门阵列教程,七段LED显示控制器设计用于在Basys 3的四位数7段LED显示屏上显示数字 现场可编程门阵列 板。下图是Basys 3上七段LED显示控制器的时序图 现场可编程门阵列:

现场可编程门阵列教程-Basys 3 现场可编程门阵列上的七段LED显示控制器
以下是在Basys 3的4位7段LED显示屏上显示“ 1234”的示例时序图 现场可编程门阵列 刷新率为60Hz或周期为16ms的电路板:
现场可编程门阵列教程-Basys 3 现场可编程门阵列上的七段LED显示控制器

现在,我们知道如何在Basys 3的四位数七段LED显示屏上控制和显示数字 现场可编程门阵列。接下来,让我们设计 7段LED显示控制器.

Basys 3 现场可编程门阵列 具有100MHz的时钟源,我们需要1ms-16ms的刷新周期或1KHz-60Hz的刷新率。我将选择10.5ms的刷新周期(数字周期= 2.6ms),以便我们可以使用20位计数器创建刷新周期,而计数器的前2个MSB位用于创建LED激活信号(数字周期为2.6ms),如上面的时序图所示。

下面是一个例子 Verilog 用于创建刷新信号和LED激活信号的代码:

reg [19:0] refresh_counter; 
// the first 18-bit 对于 creating 2.6ms digit period
// the other 2-bit 对于 creating 4 LED-activating signals
wire [1:0] LED_activating_counter; 
// count        0    ->  1  ->  2  ->  3
// activates    LED1    LED2   LED3   LED4
// and repeat
always @(posedge clock_100Mhz or posedge reset)
begin 
 if(reset==1)
  refresh_counter <= 0;
 else
  refresh_counter <= refresh_counter + 1;
end 
assign LED_activating_counter = refresh_counter[19:18];
之后,我们需要生成阳极信号 (W4,V4,U4,U2) 基于LED激活计数器的四位数7段LED显示器。 LED激活计数器将重复从零计数到三个,以连续激活和更新四个七段LED。

下面是一个例子 Verilog 用于在Basys 3上创建阳极信号并更新四个7段LED的值的代码 现场可编程门阵列:

    // anode activating signals 对于 4 LEDs
    // decoder to generate anode signals 
    always @(*)
    begin
        case(LED_activating_counter)
        2'b00: begin
            Anode_Activate = 4'b0111; 
            // activate LED1 and Deactivate LED2, LED3, LED4
            LED_BCD = displayed_number[15:11];
            // the first hex-digit 的 16-bit number
             end
        2'b01: begin
            Anode_Activate = 4'b1011; 
            // activate LED2 and Deactivate LED1, LED3, LED4
            LED_BCD = displayed_number[10:8];
            // the second hex-digit 的 16-bit number
                end
        2'b10: begin
            Anode_Activate = 4'b1101; 
            // activate LED3 and Deactivate LED2, LED1, LED4
            LED_BCD = displayed_number[7:4];
             // the third hex-digit 的 16-bit number
              end
        2'b11: begin
            Anode_Activate = 4'b1110; 
            // activate LED4 and Deactivate LED2, LED3, LED1
             LED_BCD = displayed_number[3:0];
             // the fourth hex-digit 的 16-bit number 
               end   
        default:begin
             Anode_Activate = 4'b0111; 
            // activate LED1 and Deactivate LED2, LED3, LED4
            LED_BCD = displayed_number[15:11];
            // the first hex-digit 的 16-bit number
            end
        endcase
    end

最后但并非最不重要的例子 Verilog代码 for BCD至7段解码器 根据上面的解码器表:

reg[6:0] LED_out;
// Cathode patterns 的 7段LED显示屏 
always @(*)
begin
 case(LED_BCD)
 4'b0000: LED_out = 7'b0000001; // "0"  
 4'b0001: LED_out = 7'b1001111; // "1" 
 4'b0010: LED_out = 7'b0010010; // "2" 
 4'b0011: LED_out = 7'b0000110; // "3" 
 4'b0100: LED_out = 7'b1001100; // "4" 
 4'b0101: LED_out = 7'b0100100; // "5" 
 4'b0110: LED_out = 7'b0100000; // "6" 
 4'b0111: LED_out = 7'b0001111; // "7" 
 4'b1000: LED_out = 7'b0000000; // "8"  
 4'b1001: LED_out = 7'b0000100; // "9" 
 default: LED_out = 7'b0000001; // "0"
 endcase
end
设计 7段LED显示控制器 基本完成。让我们使用控制器在Basys 3的四位数七段LED显示屏上显示一个16位计数 现场可编程门阵列 板,计数周期为1秒。

充分 Verilog代码 of the 七段式LED显示控制器 在Basys 3上显示计数数字 现场可编程门阵列

// hzgifts.cn: 现场可编程门阵列项目, Verilog projects, VHDL projects
// 现场可编程门阵列教程: 七段式LED显示控制器 on Basys  3 现场可编程门阵列
module Seven_segment_LED_Display_Controller(
    input clock_100Mhz, // 100 Mhz clock source on Basys 3 现场可编程门阵列
    input reset, // reset
    output reg [3:0] Anode_Activate, // anode signals 的 7段LED显示屏
    output reg [6:0] LED_out// cathode patterns 的 7段LED显示屏
    );
    reg [26:0] one_second_counter; // counter 对于 generating 1 second clock enable
    wire one_second_enable;// one second enable 对于 counting numbers
    reg [15:0] displayed_number; // counting number to be displayed
    reg [3:0] LED_BCD;
    reg [19:0] refresh_counter; // 20-bit 对于 creating 10。5ms refresh period or 380Hz refresh rate
             // the first 2 MSB bits 对于 creating 4 LED-activating signals with 2.6ms digit period
    wire [1:0] LED_activating_counter; 
                 // count     0    ->  1  ->  2  ->  3
              // activates    LED1    LED2   LED3   LED4
             // and repeat
    always @(posedge clock_100Mhz or posedge reset)
    begin
        if(reset==1)
            one_second_counter <= 0;
        else begin
            if(one_second_counter>=99999999) 
                 one_second_counter <= 0;
            else
                one_second_counter <= one_second_counter + 1;
        end
    end 
    assign one_second_enable = (one_second_counter==99999999)?1:0;
    always @(posedge clock_100Mhz or posedge reset)
    begin
        if(reset==1)
            displayed_number <= 0;
        else if(one_second_enable==1)
            displayed_number <= displayed_number + 1;
    end
    always @(posedge clock_100Mhz or posedge reset)
    begin 
        if(reset==1)
            refresh_counter <= 0;
        else
            refresh_counter <= refresh_counter + 1;
    end 
    assign LED_activating_counter = refresh_counter[19:18];
    // anode activating signals 对于 4 LEDs, digit period of 2.6ms
    // decoder to generate anode signals 
    always @(*)
    begin
        case(LED_activating_counter)
        2'b00: begin
            Anode_Activate = 4'b0111; 
            // activate LED1 and Deactivate LED2, LED3, LED4
            LED_BCD = displayed_number/1000;
            // the first digit 的 16-bit number
              end
        2'b01: begin
            Anode_Activate = 4'b1011; 
            // activate LED2 and Deactivate LED1, LED3, LED4
            LED_BCD = (displayed_number % 1000)/100;
            // the second digit 的 16-bit number
              end
        2'b10: begin
            Anode_Activate = 4'b1101; 
            // activate LED3 and Deactivate LED2, LED1, LED4
            LED_BCD = ((displayed_number % 1000)%100)/10;
            // the third digit 的 16-bit number
                end
        2'b11: begin
            Anode_Activate = 4'b1110; 
            // activate LED4 and Deactivate LED2, LED3, LED1
            LED_BCD = ((displayed_number % 1000)%100)%10;
            // the fourth digit 的 16-bit number    
               end
        endcase
    end
    // Cathode patterns 的 7段LED显示屏 
    always @(*)
    begin
        case(LED_BCD)
        4'b0000: LED_out = 7'b0000001; // "0"     
        4'b0001: LED_out = 7'b1001111; // "1" 
        4'b0010: LED_out = 7'b0010010; // "2" 
        4'b0011: LED_out = 7'b0000110; // "3" 
        4'b0100: LED_out = 7'b1001100; // "4" 
        4'b0101: LED_out = 7'b0100100; // "5" 
        4'b0110: LED_out = 7'b0100000; // "6" 
        4'b0111: LED_out = 7'b0001111; // "7" 
        4'b1000: LED_out = 7'b0000000; // "8"     
        4'b1001: LED_out = 7'b0000100; // "9" 
        default: LED_out = 7'b0000001; // "0"
        endcase
    end
 endmodule
Basys 3上四位数七段LED显示屏的引脚约束文件 现场可编程门阵列:
# Clock signal
set_property PACKAGE_PIN W5 [get_ports clock_100Mhz]       
 set_property IOSTANDARD LVCMOS33 [get_ports clock_100Mhz]
set_property PACKAGE_PIN R2 [get_ports reset]     
 set_property IOSTANDARD LVCMOS33 [get_ports reset]
#seven-segment LED display
set_property PACKAGE_PIN W7 [get_ports {LED_out[6]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[6]}]
set_property PACKAGE_PIN W6 [get_ports {LED_out[5]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[5]}]
set_property PACKAGE_PIN U8 [get_ports {LED_out[4]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[4]}]
set_property PACKAGE_PIN V8 [get_ports {LED_out[3]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[3]}]
set_property PACKAGE_PIN U5 [get_ports {LED_out[2]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[2]}]
set_property PACKAGE_PIN V5 [get_ports {LED_out[1]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[1]}]
set_property PACKAGE_PIN U7 [get_ports {LED_out[0]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {LED_out[0]}]
set_property PACKAGE_PIN U2 [get_ports {Anode_Activate[0]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[0]}]
set_property PACKAGE_PIN U4 [get_ports {Anode_Activate[1]}]                    
   set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[1]}]
set_property PACKAGE_PIN V4 [get_ports {Anode_Activate[2]}]               
   set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[2]}]
set_property PACKAGE_PIN W4 [get_ports {Anode_Activate[3]}]          
   set_property IOSTANDARD LVCMOS33 [get_ports {Anode_Activate[3]}]
现在,在Vivado中创建一个新项目,选择设备的部件号 XC7A35T-用于Artix-7 现场可编程门阵列的1CPG236C Basys 3 现场可编程门阵列板。然后,添加源文件和约束文件,并生成 bitstream. 编程FPGA 使用位流并查看其在Basys 3 现场可编程门阵列板上的工作方式。

的演示视频 七段式LED显示控制器 在Basys 3 现场可编程门阵列板上:

这里 是Basys 3 现场可编程门阵列上七段显示器的完整VHDL代码。
推荐的 现场可编程门阵列项目 for students:
1. 什么是FPGA? 现场可编程门阵列如何工作?
2. 什么是FPGA编程?
3. 如何将文本文件或图像加载到FPGA中
4. 使用Verilog在FPGA上进行图像处理
5. 现场可编程门阵列上的车牌识别
6. 使用Verilog的FPGA上的闹钟
7. 使用VHDL的FPGA上的数字时钟
8. 现场可编程门阵列上的交通灯控制器
9. Verilog中基于FPGA的停车场系统
10。 现场可编程门阵列上Verilog单片机的实现
11。 现场可编程门阵列 Xilinx上的VHDL矩阵乘法
12 现场可编程门阵列上微控制器的VHDL代码
13 现场可编程门阵列上FIR滤波器的VHDL代码
14。 使用Verilog的FPGA上的单周期MIPS处理器
15 使用Verilog在FPGA上进行RISC处理器设计
16。 使用VHDL的FPGA上的PWM发生器
17。 使用Verilog在FPGA上的井字游戏
18岁 Verilog中FPGA上的流水线MIPS处理器
19 面向初学者的价格实惠的Xilinx 现场可编程门阵列板
20 面向初学者的经济实惠的Altera 现场可编程门阵列板
21 Basys 3 现场可编程门阵列 OV7670摄像机
现场可编程门阵列 Verilog VHDL课程

24条评论:

  1. 你好
    我没有'不能理解19位= 190Hz?

    回复删除
    回覆
    1. 19位刷新计数器最多可以计数2 ^ 19-1 =524287。时钟输入为100Mhz。因此您可以获得的刷新率= 100,000,000 / 524,287 = 190 Hz。

      删除
    2. Ahaaa,但是如果我对一秒钟计数器执行同样的操作,结果将不是1秒!
      100MHz / 2 ^ 27 = 0.75 ---> 1/0.75 = 1.33 sec
      可以计算吗?而您无法获得纯粹的1秒?但是,如果我要精确到毫秒或纳秒的时钟怎么办?
      谢谢

      删除
    3. 如果使用27位计数器,则最多可计数134,217,727。因此,当计数器达到100,000,000时,您需要将计数器重置为0。然后,您将获得1秒时钟。

      删除
    4. 因此,当变量计数达到524287 + 1?时,将受益于该变量的溢出,从而产生了190Hz刷新率。

      删除
    5. Basys 3 现场可编程门阵列的时钟源为100MHz,我们需要1ms-16ms的刷新周期或1KHz-60Hz的刷新率。我将选择10.5ms的刷新周期(数字周期= 2.6ms),以便我们可以使用20位计数器创建刷新周期,而计数器的前2个MSB位用于创建LED激活信号(数字周期为2.6ms),如上面的时序图所示。

      删除
    6. 20位用于生成10.5毫秒,如果我想生成8.5毫秒,刷新计数器位应为多少?
      如何确定刷新计数器位?

      删除
    7. 20bits刷新计数器用于生成10.5ms,如果我想生成8.5ms,刷新计数器位应如何设置?

      如何选择刷新计数器位?

      删除
    8. 20bits刷新计数器用于生成10.5ms,如果我想生成8.5ms,刷新计数器位应如何设置?

      如何选择刷新计数器位?

      删除
    9. 20bits刷新计数器用于生成10.5ms,如果我想生成8.5ms,刷新计数器位应如何设置?

      如何选择刷新计数器位?

      删除
    10. 20bits刷新计数器用于生成10.5ms,如果我想生成8.5ms,刷新计数器位应如何设置?

      如何选择刷新计数器位?

      删除
  2. 回覆
    1. 使用8位计数器制作一个mod 100计数器,当计数器达到100(01100100)时,通过将输出的Q(6),Q(5)和Q(2)位输入与门3的输入端并将其清零,将其清零。该输出清除计数器..

      删除
  3. 先生
    请提供有关LCD(digilent pmodclp)与basys 3 fpga接口的教程。

    回复删除
  4. 回覆
    1. 例如:您有一个4位数字:1234,该代码将删除该数字"4" 对于 displaying.

      删除
  5. 您好,我在哪里可以获得完整的电路图?

    回复删除
  6. 嗨,我有16位输出,我想将值显示为4七段十六进制。有任何想法来解决这个问题

    回复删除
    回覆
    1. 提供的代码用于在4位7段LED显示屏上显示16位数字。正是您所需要的。

      删除
  7. 20位刷新计数器用于生成10.5ms,如果我想生成8.5ms,刷新计数器位应为多少?

    如何选择刷新计数器位?

    回复删除
  8. 为什么在刷新周期中使用20位刷新计数器,而不是更低的刷新计数器?另外,为什么要查看它的2个MSB。唐'不明白为什么只看那两个而不是其他。谢谢。

    回复删除
  9. 嗨,非常感谢您。
    我尝试自己最长的时间来实施它,并认为自己能理解。但是我的解决方案没有 '不能正常工作,当我复制您的代码时,我会遇到Pin Planning错误。我有BASYS 3 现场可编程门阵列板。我可能做错了什么?\

    [DRC NSTD-1]未指定的I / O标准:12个逻辑端口中的12个使用I / O标准(IOSTANDARD)值'DEFAULT',而不是为用户分配特定值。这可能会导致I / O争用或与电路板电源或连接性不兼容,从而影响性能,信号完整性,或者在极端情况下会损坏设备或与其连接的组件。若要更正此冲突,请指定所有I / O标准。除非所有逻辑端口都定义了用户指定的I / O标准值,否则此设计将无法生成位流。要允许使用未指定的I / O标准值创建位流(不建议),请使用以下命令:set_property SEVERITY {警告} [get_drc_checks NSTD-1]。注意:使用Vivado Runs基础结构(例如launch_runs Tcl命令)时,请将此命令添加到.tcl文件中,并将该文件作为执行运行的write_bitstream步骤的预钩添加。问题端口:i_Binary_Num [3:0],i_Clk,o_Segment_A,o_Segment_B,o_Segment_C,o_Segment_D,o_Segment_E,o_Segment_F和o_Segment_G。

    回复删除
  10. 嗨,非常感谢您。
    我尝试自己最长的时间来实施它,并认为自己能理解。但是我的解决方案没有 '不能正常工作,当我复制您的代码时,我会遇到Pin Planning错误。我有BASYS 3 现场可编程门阵列板。我可能做错了什么?\

    [DRC NSTD-1]未指定的I / O标准:12个逻辑端口中的12个使用I / O标准(IOSTANDARD)值'DEFAULT',而不是为用户分配特定值。这可能会导致I / O争用或与电路板电源或连接性不兼容,从而影响性能,信号完整性,或者在极端情况下会损坏设备或与其连接的组件。若要更正此冲突,请指定所有I / O标准。除非所有逻辑端口都定义了用户指定的I / O标准值,否则此设计将无法生成位流。要允许使用未指定的I / O标准值创建位流(不建议),请使用以下命令:set_property SEVERITY {警告} [get_drc_checks NSTD-1]。注意:使用Vivado Runs基础结构(例如launch_runs Tcl命令)时,请将此命令添加到.tcl文件中,并将该文件作为执行运行的write_bitstream步骤的预钩添加。问题端口:i_Binary_Num [3:0],i_Clk,o_Segment_A,o_Segment_B,o_Segment_C,o_Segment_D,o_Segment_E,o_Segment_F和o_Segment_G。

    回复删除

热门FPGA项目