EDITORIAL words
In the project design , we usually need some display device to display the information we need , you can select the display device is a wide range of Ling Lang everywhere, digital control is undoubtedly the most common and easiest one display device. In this section, the dream-wing brothers and we will study together the principles and display of digital driving mode to prepare for our future development projects.
Project requirements
Design of a digital driving circuit, so that the LED can be displayed simultaneously in any six-digit (Sleeper wing boards brothers use digital integrated digital piece of six).
Principle Analysis
As a digital peripherals, we first need to understand how it works and its corresponding circuit connection relationship, the seven segments following schematic structure:
As the name suggests, seven-segment LED is lit using a seven-segment to segment makes up some common digital and letters, this is very easy to see the way we display in digital circuits. Together with the bottom right of the decimal point, in fact, a display unit 8 comprises a signal line. Depending on the circuit design, active high signal lines may also be low. We FPGA control blinking of these segments, you can achieve the appropriate display.
A plurality of digital control module for the display, each of the pins connected to the FPGA will consume a lot of resources on FPGA pin. So we also introduced a similar scanning matrix keyboard. Any time we use only eight signal lights a LED, but the LED 8 is lighted alternately pace with the clock, as long as the clock is fast enough, we observed if several LED light up simultaneously the same. Sleeper wing board schematic brothers used is as follows:
As illustrated, our development board using six common anode LED, six were used as a PNP transistor input switch six groups of digital power supply, that is, we often say that the bit select signal, PNP transistor is low flat conductive, so we bit select signal is active low. Here, in order to save resources of FPGA IO, we selected from the six bit signal to the decoder thirty-eight 74HC138D, the thirty-eight decoder truth table as follows:
Thus, we can conclude that, when {SEL2, SEL1, SEL0} = 3'b000 time, Y0 goes low, and as Y0 is connected to the first digital control, so the first LED lights up. When {SEL2, SEL1, SEL0} = 3'b001, corresponding to the second digital tube lighting, and so on. SEG_0 correspond to SEG_7 diode and ag "decimal point", i.e., what we call the segment select signal. Because it is common anode LED, the diode can be lit as long as a low level, depending on the lighting diodes can exhibit different character. If we want to light up the first LED, and displays the character "A", then we need only select the first LED {SEL2, SEL1, SEL0} = 3'b000, and SEG = 8'b1000_1000.
If you want the digital tube "all lit up", and simultaneously display the same character, that we can only achieve this by comparing the selected bit fast switching signal. However, the switching frequency is too high, the digital display will appear unstable state, and technology related to this device, we can choose to experience 1KHZ frequency switching. So this time, we need to use frequency module, a crystal clock 50MHZ division into 1KHZ we need.
Single digital display
Single digital display system architecture
Single digital display is the largest number in hexadecimal F (15), binary number 15 corresponds 4'b1111, so our input should be four.
Module Module A single digital display presentation
Module name |
Functional Description |
SEG7 |
Output control line |
Single digital display interface module described
Port Name |
Port Description |
clk |
System clock input |
Rst_n |
System reset |
Data[3:0] |
data input |
cells [2: 0] |
Chip select signal output |
out [7: 0] |
Select signal output section |
Code explanation
SEG7 module Code
/**************************************************** * Engineer: Dream Brother Wing * QQ : 761664056
Of The function Module1 * : control of a single digital display any digital *****************************************************/ 00 module SEG7 ( CLK 01 , // system clock Rst_n 02 , // system reset The Data 03 , // input data Seg 04 , // LED segment selector 05 sel // digital bit option 06 ); 07 // system input 08 INPUT CLK ; // the system clock 09 INPUT RST_N ; // reset 10 INPUT [ . 3 : 0 ] Data ; // input data 11 // system output 12 output reg [7:0] seg;//数码管段选 13 output reg [2:0] sel;//数码管位选 14 15 always @ (posedge clk or negedge rst_n) 16 begin 17 if (!rst_n)//复位的时候选择第一个数码管 18 begin 19 sel <= 0; 20 end 21 else 22 begin//选择第一个数码管 23 sel <= 0; 24 end 25 end 26 27 always @ (*)//用组合逻辑进行输出段选信号 28 begin 29 if (!rst_n)//复位的时候数码管熄灭 30 begin 31 seg = 8'b1111_1111; 32 end 33 else 34 begin 35 case(data) 36 0 : seg = 8'b1100_0000;//显示“0” 37 1 : seg = 8'b1111_1001;//显示“1” 38 2 : seg = 8'b1010_0100;//显示“2” 39 3 : seg = 8'b1011_0000;//显示“3” 40 4 : seg = 8'b1001_1001;//显示“4” 41 5 : seg = 8'b1001_0010;//显示“5” 42 6 : seg = 8'b1000_0010;//显示“6” 43 7 : seg = 8'b1111_1000;//显示“7” 44 8 : seg = 8'b1000_0000;//显示“8” 45 9 : seg = 8'b1001_0000;//显示“9” 46 10 : seg = 8'b1000_1000;//显示“A” 47 11 : seg = 8'b1000_0011;//显示“B” 48 12 : seg = 8'b1100_0110;//显示“C” 49 13 : seg = 8'b1010_0001;//显示“D” 50 14 : seg = 8'b1000_0110;//显示“E” 51 15 : seg = 8'b1000_1110;//显示“F” 52 default : seg = 8'b1111_1111;//全灭 53 endcase 54 end 55 end 56 57 endmodule |
仿真代码
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function:测试SEG7模块,并显示“A” *****************************************************/ 00 `timescale 1ns/1ps //定义时间单位和精度 01 02 module SEG7_tb; 03 //系统输入 04 reg clk;//系统时钟 05 reg rst_n;//系统复位 06 reg [3:0] data;//输入数据 07 //系统输出 08 wire [7:0] seg;//数码管段选 09 wire [2:0] sel;//数码管位选 10 11 initial begin 12 clk = 1; 13 rst_n = 0; 14 data = 10;//data = 4'hA; 这两种方式都可以 15 # 200.1 //复位200ns 16 rst_n = 1; 17 end 18 19 always # 10 clk = ~clk;//50M的时钟 20 21 SEG7 SEG7 ( 22 .clk(clk), //系统时钟 23 .rst_n(rst_n),//系统复位 24 .data(data), //输入数据 25 .seg(seg),//数码管段选 26 .sel(sel)//数码管位选 27 ); 28 29 endmodule |
在本模块中,梦翼师兄只是测试了显示”A”,有兴趣的话,可以把0~9、A~F,全部测试一下。
单个数码管显示的仿真分析
在复位期间,seg信号全部为“1”,数码管熄灭。当复位信号拉高以后,seg信号变成了“10001000”,正好是“A”的段选,而sel(位选)一直就是0(选择第一个数码管),证明我们的设计是正确的。
六个数码管显示
六个数码显示的系统架构
应用六个数码管去显示任意数字,每个数码管显示的数字需要用4位二进制数去表示,那么六个数码管一共需要24位二进制数
数码管各模块功能介绍
模块名 |
功能描述 |
SEG7 |
输出数码管控制位选和段选信号 |
freq |
时钟分频模块,输出1KHz时钟 |
top |
顶层模块,负责模块级联 |
端口和内部连线描述
顶层端口
端口名 |
端口说明 |
clk |
系统时钟输入 |
Rst_n |
系统复位 |
Data[23:0] |
数据输入 |
sel[2:0] |
片选信号输出 |
seg[7:0] |
段选信号输出 |
模块内部连线
连线名 |
连线说明 |
Clk_1K |
数码管的切换时钟 |
代码解释
freq模块代码
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function: 产生慢时钟 *****************************************************/ 00 module freq ( 01 clk, //系统时钟 02 rst_n, //系统复位 03 clk_1K//切换时钟 04 ); 05 //系统输入 06 input clk;//系统时钟 07 input rst_n;//系统复位 08 //系统输出 09 output reg clk_1K;//切换时钟 10 //定义中间寄存器 11 reg [19:0] count;//定义一个计数的寄存器 12 13 always @ (posedge clk or negedge rst_n) 14 begin 15 if (!rst_n) 16 begin 17 clk_1K <= 1; 18 count <= 0; 19 end 20 else 21 begin 22 if (count < 24999)// 50000分频,得出1K的时钟 23 count <= count + 1; 24 else 25 begin 26 count <= 0; 27 clk_1K <= ~clk_1K; 28 end 29 end 30 end 31 32 endmodule |
SEG7模块代码
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function: 产生段选信号和位选信号 *****************************************************/ 000 module SEG7 ( 001 clk, //模块时钟 002 rst_n,//系统复位 003 data, //输入数据 004 seg,//数码管段选 005 sel//数码管位选 006 ); 007 //系统输入 008 input clk;//模块时钟 009 input rst_n;//系统复位 010 input [23:0] data;//输入数据 011 //系统输出 012 output reg [7:0] seg;//数码管段选 013 output reg [2:0] sel;//数码管位选 014 //定义中间寄存器 015 reg [3:0] data_temp;//数码管显示的数值 016 reg [2:0] state;//状态寄存器 017 018 always @ (posedge clk or negedge rst_n) 019 begin 020 if (!rst_n)//复位的时候选择第一个数码管 021 begin 022 sel <= 0; 023 data_temp <= 0; 024 state <= 0; 025 end 026 else 027 begin 028 case (state) 029 0 : begin//将最高位的数显示在第一个数码管上 030 sel <= 0; 031 data_temp <= data[23:20]; 032 state <= 1; 033 end 034 035 1 : begin//将第2位的数显示在第二个数码管上 036 sel <= 1; 037 data_temp <= data[19:16]; 038 state <= 2; 039 end 040 041 2 : begin//将第3位的数显示在第三个数码管上 042 sel <= 2; 043 data_temp <= data[15:12]; 044 state <= 3; 045 end 046 047 3 : begin//将第4位的数显示在第四个数码管上 048 sel <= 3; 049 data_temp <= data[11:8]; 050 state <= 4; 051 end 052 053 4 : begin//将最5位的数显示在第五个数码管上 054 sel <= 4; 055 data_temp <= data[7:4]; 056 state <= 5; 057 end 058 059 5 : begin//将最低位的数显示在第六个数码管上 060 sel <= 5; 061 data_temp <= data[3:0]; 062 state <= 0; 063 end 064 065 default : state <= 0; 066 endcase 067 end 068 end 069 070 always @ (*)//根据data_temp的中的值,用组合逻辑进行输出段选信号 071 begin 072 if (!rst_n)//复位的时候数码管熄灭 073 begin 074 seg = 8'b1111_1111; 075 end 076 else 077 begin 078 case(data_temp) 079 0 : seg = 8'b1100_0000;//显示“0” 080 1 : seg = 8'b1111_1001;//显示“1” 081 2 : seg = 8'b1010_0100;//显示“2” 082 3 : seg = 8'b1011_0000;//显示“3” 083 4 : seg = 8'b1001_1001;//显示“4” 084 5 : seg = 8'b1001_0010;//显示“5” 085 6 : seg = 8'b1000_0010;//显示“6” 086 7 : seg = 8'b1111_1000;//显示“7” 087 8 : seg = 8'b1000_0000;//显示“8” 088 9 : seg = 8'b1001_0000;//显示“9” 089 10 : seg = 8'b1000_1000;//显示“A” 090 11 : seg = 8'b1000_0011;//显示“B” 091 12 : seg = 8'b1100_0110;//显示“C” 092 13 : seg = 8'b1010_0001;//显示“D” 093 14 : seg = 8'b1000_0110;//显示“E” 094 15 : seg = 8'b1000_1110;//显示“F” 095 default : seg = 8'b1000_1110;//显示“F” 096 endcase 097 end 098 end 099 100 endmodule |
top模块代码
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function: 顶层模块 *****************************************************/ 00 module top ( 01 clk, //系统时钟 02 rst_n, //系统复位 03 data, //输入数据 04 seg, //数码管段选 05 sel//数码管位选 06 ); 07 //系统输入 08 input clk;//系统时钟 09 input rst_n;//系统复位 10 input [23:0] data;//输入数据 11 //系统输出 12 output [7:0] seg;//数码管段选 13 output [2:0] sel;//数码管位选 14 //定义中间连线 15 wire clk_1K;//定义切换时钟 16 //调用pll(锁相环) 17 freq freq( 18 .clk( clk ),//外部时钟 19 .rst_n(rst_n),//系统复位 20 .clk_1K( clk_1K ) //切换时钟 21 ); 22 //实例化SEG7 23 SEG7 SEG7 ( 24 .clk(clk_1K), //切换时钟 25 .rst_n(rst_n),//系统复位 26 .data(data), //输入数据 27 .seg(seg),//数码管段选 28 .sel(sel)//数码管位选 29 ); 30 31 endmodule |
编写完可综合代码之后查看RTL视图如下:
由RTL视图可知代码综合以后得到的电路和我们设计的系统框图一致,说明顶层连接关系正确,接下来编写测试代码如下:
/**************************************************** * Engineer : 梦翼师兄 * QQ : 761664056 * The module function: 测试数码管模块 *****************************************************/ 00 `timescale 1ns/1ps //定义时间单位和精度 01 02 module top_tb; 03 //系统输入 04 reg clk;//系统时钟 05 reg rst_n;//系统复位 06 reg [23:0] data;//输入数据 07 //系统输出 08 wire [7:0] seg;//数码管段选 09 wire [2:0] sel;//数码管位选 10 11 initial begin 12 clk = 1; 13 rst_n = 0; 14 data = 24'h123456; 15 # 200.1 //复位200.1ns 16 rst_n = 1; 17 end 18 19 always # 10 clk = ~clk;//50M的时钟 20 21 top top( 22 .clk(clk), //系统时钟 23 .rst_n(rst_n),//系统复位 24 .data(data), //输入数据 25 .seg(seg),//数码管段选 26 .sel(sel)//数码管位选 27 ); 28 29 endmodule |
仿真分析
在对应的数码管上,给出对应数值的段选信号,经过比对,我们的设计都是正确的。