在线咨询 切换到宽版
eetop公众号 创芯大讲堂 创芯人才网

 找回密码
 注册

手机号码,快捷登录

手机号码,快捷登录

搜帖子
查看: 2042|回复: 0

[原创] FPGA数码管动态扫描附件详细的讲解

[复制链接]
发表于 2018-9-29 10:21:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
数码管动态扫描


一、项目背景

led数码管(LED Segment Displays)是由多个发光二极管封装在一起组成“8”字型的器件,引线已在内部连接完成,只引出它们的各个笔划,公共电极。led数码管常用段数一般为7段,如上图中的abcdefg,有的还会有一个小数点,如图中的h

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png

数码管要正常显示,就要用驱动电路来驱动数码管的各个段码,从而显示出我们要的数字。按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。

下表列出了要显示的数字,以及对应的abcdefg的值。

  

显示

  

数字

  
  

共阳abcdefg

  

2进制

  
  

共阳abcdefg

  

16进制

  
  

共阴abcdefg

  

2进制

  
  

共阴abcdefg

  

16进制

  
  

0

  
  

7’b0000001

  
  

7’h01

  
  

7’b 1111110

  
  

7’h7e

  
  

1

  
  

7’b 1001111

  
  

7’h4f

  
  

7’b 0110000

  
  

7’h30

  
  

2

  
  

7’b 0010010

  
  

7’h12

  
  

7’b 1101101

  
  

7’h6d

  
  

3

  
  

7’b 0000110

  
  

7’h06

  
  

7’b 1111001

  
  

7’h79

  
  

4

  
  

7’b 1001100

  
  

7’h4c

  
  

7’b 0110011

  
  

7’h33

  
  

5

  
  

7’b 0100100

  
  

7’h24

  
  

7’b 1011011

  
  

7’h5b

  
  

6

  
  

7’b 0100000

  
  

7’h20

  
  

7’b 1011111

  
  

7’h3f

  
  

7

  
  

7’b 0001111

  
  

7’h0f

  
  

7’b 1110000

  
  

7’h70

  
  

8

  
  

7’b 0000000

  
  

7’h00

  
  

7’b 1111111

  
  

7’h7f

  
  

9

  
  

7’b 0000100

  
  

7’h04

  
  

7’b 1111011

  
  

7’h7b

  


例如,共阳数码管中,abcdefg的值分别是1001111时,也就是bc字段亮,其他字段不亮,这时就显示了数字“1”。

如果要显示多个数码管,根据数码管的驱动方式的不同,可以分为静态式和动态式两类。

静态驱动也称直流驱动。静态驱动是指每个数码管的每一个段码都由一个单片机的I/O端口进行驱动,或者使用如BCD码二-十进制译码器译码进行驱动。静态驱动的优点是编程简单,显示亮度高,缺点是占用I/O端口多,如驱动5个数码管静态显示则需要5×8=40I/O端口来驱动,要知道一个89S51单片机可用的I/O端口才32个,实际应用时必须增加译码驱动器进行驱动,增加了硬件电路的复杂性。

数码管动态显示接口是应用最为广泛的一种显示方式之一,动态驱动是将所有数码管的8个显示笔划"a,b,c,d,e,f,g,dp"的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制,当要输出字形码时,所有数码管都接收到相同的字形码,但究竟是哪个数码管会显示出字形,取决于单片机对位选通COM端电路的控制,所以我们只要将需要显示的数码管的选通控制打开,该位就显示出字形,没有选通的数码管就不会亮。通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。在轮流显示过程中,每位数码管的点亮时间为12ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。

明德扬开发板上一共有24位的共阳数码管,也就是说一共有8个共阳数码管。数码管的配置电路如下。

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg

图中的SEG_ASEG_B~SEG_DP,是段选信号,这些信号都是8个数码管共用的。

DIG1~DIG8是位选信号,分别对应8个数码管。对应的位选信号为0,就表示将段选信号的值赋给该数码管。例如DIG30,表示将段选信号SEG_A~SEG_DP的值赋给数码管3

SEG_A~SEG_DPDIG1~DIG8,都是连接到电阻,如下图。

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg

由此可见,SEG_A~SEG_DP是由SEG0~SEG7产生的,DIG1~DIG8是由DIG_EN1~DIG_EN8产生的。


SEG0~SEG7DIG_EN1~DIG_EN8直接连到FPGAIO上。

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image007.png


这些信号与FPGA管脚的对应关系如下表。

  

信号线

  
  

信号线

  
  

FPGA管脚

  
  

SEG_E

  
  

SEG0

  
  

Y6

  
  

SEG_DP

  
  

SEG1

  
  

W6

  
  

SEG_G

  
  

SEG2

  
  

Y7

  
  

SEG_F

  
  

SEG3

  
  

W7

  
  

SEG_D

  
  

SEG4

  
  

P3

  
  

SEG_C

  
  

SEG5

  
  

P4

  
  

SEG_B

  
  

SEG6

  
  

R5

  
  

SEG_A

  
  

SEG7

  
  

T3

  
  

DIG1

  
  

DIG_EN1

  
  

T4

  
  

DIG2

  
  

DIG_EN2

  
  

V4

  
  

DIG3

  
  

DIG_EN3

  
  

V3

  
  

DIG4

  
  

DIG_EN4

  
  

Y3

  
  

DIG5

  
  

DIG_EN5

  
  

Y8

  
  

DIG6

  
  

DIG_EN6

  
  

W8

  
  

DIG7

  
  

DIG_EN7

  
  

W10

  
  

DIG8

  
  

DIG_EN8

  
  

Y10

  



也就是说,FPGA通过控制上面中的管脚,就控制了数码管的显示。


二、设计目标

开发板或者模块是有 8 位数码管,本次设计需要使用 8 个数码管,实现数码管显示功能,具体要求如下:

复位后,数码管 0 显示数字 01 秒后,轮到数码管 1 显示数字 11 秒后,轮到数码管 2 显示数字 2;以此类推,每隔 1 秒变化,最后是数码管 7 显示数字 7。然后再次循环。


上板效果图如下图所示。

上板的演示效果,请登陆网址查看:www.mdy-edu.com/xxxx


file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image009.jpgfile:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image011.jpgfile:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image013.jpgfile:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image015.jpg

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image017.jpgfile:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image019.jpgfile:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image021.jpgfile:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image023.jpg

三、模块设计

我们要实现的功能,概括起来就是控制8个数码管,让数码管显示不同的数字。要控制8个数码管,就需要控制位选信号,即FPGA要输出一个8位的位选信号,设为seg_sel,其中seg_sel[0]对应数码管0seg_sel[1]对应数码管1,以此类推,seg_sel[7]对应数码管7

要显示不同的数字,就需要控制段选信号,不需要用到DP,一共有7根线,即FPGA要输出一个7位的段选信号,设为seg_mentseg_ment[6]~segm_ment[0]分别对应数码管的abcdefg(注意对应顺序)。

我们还需要时钟信号和复位信号来进行工程控制。

综上所述,我们这个工程需要4个信号,时钟clk,复位rst_n,输出的位选信号seg_sel和输出的段选信号seg_ment。其中,seg_selseg_ment的对应关系下如下:


  

信号线

  
  

信号线

  
  

FPGA管脚

  
  

内部信号

  
  

SEG_E

  
  

SEG0

  
  

Y6

  
  

seg_ment[2]

  
  

SEG_DP

  
  

SEG1

  
  

W6

  
  

未用到

  
  

SEG_G

  
  

SEG2

  
  

Y7

  
  

seg_ment[0]

  
  

SEG_F

  
  

SEG3

  
  

W7

  
  

seg_ment[1]

  
  

SEG_D

  
  

SEG4

  
  

P3

  
  

seg_ment[3]

  
  

SEG_C

  
  

SEG5

  
  

P4

  
  

seg_ment[4]

  
  

SEG_B

  
  

SEG6

  
  

R5

  
  

seg_ment[5]

  
  

SEG_A

  
  

SEG7

  
  

T3

  
  

seg_ment[6]

  
  

DIG1

  
  

DIG_EN1

  
  

T4

  
  

seg_sel[0]

  
  

DIG2

  
  

DIG_EN2

  
  

V4

  
  

seg_sel[1]

  
  

DIG3

  
  

DIG_EN3

  
  

V3

  
  

seg_sel[2]

  
  

DIG4

  
  

DIG_EN4

  
  

Y3

  
  

seg_sel[3]

  
  

DIG5

  
  

DIG_EN5

  
  

Y8

  
  

seg_sel[4]

  
  

DIG6

  
  

DIG_EN6

  
  

W8

  
  

seg_sel[5]

  
  

DIG7

  
  

DIG_EN7

  
  

W10

  
  

seg_sel[6]

  
  

DIG8

  
  

DIG_EN8

  
  

Y10

  
  

seg_sel[7]

  



我们先分析要实现的功能,数码管0显示数字0,翻译成信号就是seg_sel的值为8’b1111_1110seg_ment的值为7’b000_0001。数码管1显示数字1,也就是说seg_sel的值为8’b1111_1101seg_ment的值为7’b100_1111。以此类推,数码管7显示数字7,就是seg_sel的值为8’b0111_1111seg_ment的值为7’b000_1111

再留意下,以上都是每隔1秒进行变化,并且是8个数码管轮流显示,那么波形示意图如下图所示。


file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image025.png

上图就是seg_selseg_seg信号的变化波形图。在显示第1个时,seg_sel=8’hfeseg_ment=7’h01并持续1秒;在第1个时,seg_sel=8’hfdseg_ment=7’h4f并持续1秒;以此类推,第8个时,seg_sel=8’h7fseg_ment=7’h0f并持续1秒。然后又再次重复。

由波形图可知,我们需要1个计数器用来计算1秒的时间。本工程的工作时钟是50MHz,即周期为20ns,计数器计数到1_000_000_000/20=50_000_000个,我们就能知道1秒时间到了。另外,由于该计数器是不停地计数,永远不停止的,可以认为加1条件一直有效,可写成:assignadd_cnt==1。综上所述,该计数器的代码如下。

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image027.jpg

再次观察波形图,我们发现有第1个,第2个直到第8个,说明这还需要另外一个计数器来表示第几个。该计数器表示第几个,自然是完成1秒就加1,因为加1条件可为end_cnt0。该计数器一共要数8次。所以代码为:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image029.jpg

有了两个计数器,我们来思考输出信号seg_sel的变化。概括起来,在第1次的时候输出值为8’hfe;在第2次的时候输出值为8’hfd;以此类推,在第8次的时候输出值为8’h7f。我们用信号cnt1来代替第几次,也就是:当cnt1==0的时候,输出值为8’hfe;在cnt1==1的时候输出值为8’hfd;以此类推,在cnt1==7的时候输出值为8’h7f。再进一步翻译成代码,就变成如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image030.png

读者有没有发现,上面代码基本上和文字描述是一模一样的,这进一步展现了verilog是“硬件描述语言”。上面的代码是能正确实现seg_sel功能的,从实现角度和资源角度来说,都挺好。但代码进一步概括,可以化简如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image031.png

对上面代码解释一下,第131行是指先将8’b1向左移位,再取反后的值,赋给seg_sel。假设此时cnt1等于0,那么8’b1<<0的结果是8’b0000_0001,取反的值为8’hfe;假设cnt1等于3,那么8’b1<<3的结果为8’b000_1000,取反后的结果为8’b1111_0111,即8’hf7。与第一种写法的结果都是相同的。


我们来思考输出信号seg_ment的变化。概括起来,在第1次的时候输出值为7’h01;在第2次的时候输出值为7’h4f;以此类推,在第8次的时候输出值为7’h0f。我们用信号cnt1来代替第几次,也就是:当cnt1==0的时候,输出值为7’h01;在cnt1==1的时候输出值为7’h4f;以此类推,在cnt1==7的时候输出值为7’h0f。再进一步翻译成代码,就变成如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image032.png

上面的代码正确地实现了seg_ment的功能,对于本工程说已经完美。但我们分析一下,就知道上面代码实现了类似译码的功能,将数字设成数码管显示的值,代码里只对0~7进行译码。很自然的,我先做一个通用的译码模块,将0~9都进行译码,以后就方便调用了。例如改成下面代码。

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image033.png


然后我们只要控制好data就能实现想要在数码管显示的数字,如下面代码。

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image034.png

cnt1=0,则数码管会显示0。当cnt1=1,则数码管会显示1

在代码的最后一行写下endmodule

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image035.png      

至此,主体程序已经完成。接下来是将module补充完整。

module的名称定义为my_seg。并且我们已经知道该模块有4个信号:clkrst_nseg_selseg_ment,代码如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image036.png


其中clkrst_n1位的输入信号,seg_sel8位的输出信号,seg_ment7位的输出信号,根据此,补充输入输出端口定义。代码如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image037.png


接下来定义信号类型。

cnt0是用always产生的信号,因此类型为regcnt0计数的最大值为50_000_000,需要用26根线表示,即位宽是26位。add_cnt0end_cnt0都是用assign方式设计的,因此类型为wire。并且其值是0或者11个线表示即可。因此代码如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image038.png

cnt1是用always产生的信号,因此类型为regcnt1计数的最大值为7,需要用3根线表示,即位宽是3位。add_cnt1end_cnt1都是用assign方式设计的,因此类型为wire。并且其值是0或者11根线表示即可。因此代码如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image039.png

seg_sel是用always方式设计的,因此类型为reg,其一共有8根线,即位宽为8。因此代码如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image040.png

seg_ ment是用always方式设计的,因此类型为reg,其一共有7根线,即位宽为7。因此代码如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image041.png


如果做了译码电路,即用到了data这个信号。那么data是用assign设计的,所以类型为wire,其最大值为9,所以需要4位位宽。代码如下:

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image042.png


至此,整个代码的设计工作已经完成。下一步是新建工程和上板查看现象。

四、综合工程和上板新建工程

1.)点击File File菜单中选择New Project Wizard....

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image044.jpg

2.弹出Introduction界面选择next

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image046.jpg







(2.)工程文件夹,工程名,顶层模块名设置界面

点击next之后进入此界面

按如下路径建立文件夹E/quartus_project/project_seg

点击“选择工程文件夹(what is theworking directory for this project?)”后面的file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image047.png 找到之前建立的立文件夹E/quartus_project/project_seg

将工程名命名栏(what is the nameof this project)中输入“my_seg

在顶层模块命名栏(what is the nameof the top-level design entity for this project?This name is case sensitive andmust exactly match the entity name in the design file)中输入“my_seg

5.命名完毕后点击next

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image049.jpg

(3.)文件添加界面

1.从上一界面进入此界面之后点击file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image047.png浏览文件夹

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image051.jpg

2.找到我们之前写的.v文件 之后选中它并点击打开

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image053.jpg

之后点击add添加此.v文件

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image055.jpg

(4.)器件选择界面

1.Device family这一项之中选择 Cyclone IV E

2.在下部的Available device 选择EP4CE6F17C8这一项

完成后点击next

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image057.jpg

EDA工具界面(采用默认配置即可)

点击next

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image059.jpg










总结界面

直接点击next即可

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image061.jpg

综合

1.点击file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image062.png此键进行编译

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image064.jpg

之后等待编译成功 点击ok

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image065.png

配置管脚

编译成功后配置管脚

点击图中位置(pin planer键)进入管脚配置界面

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image067.jpg

在下图红框区域配置管脚

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image069.jpg

按下图内容进行管脚配置

  

信号线

  
  

信号线

  
  

FPGA管脚

  
  

内部信号

  
  

SEG_E

  
  

SEG0

  
  

Y6

  
  

seg_ment[2]

  
  

SEG_DP

  
  

SEG1

  
  

W6

  
  

未用到

  
  

SEG_G

  
  

SEG2

  
  

Y7

  
  

seg_ment[0]

  
  

SEG_F

  
  

SEG3

  
  

W7

  
  

seg_ment[1]

  
  

SEG_D

  
  

SEG4

  
  

P3

  
  

seg_ment[3]

  
  

SEG_C

  
  

SEG5

  
  

P4

  
  

seg_ment[4]

  
  

SEG_B

  
  

SEG6

  
  

R5

  
  

seg_ment[5]

  
  

SEG_A

  
  

SEG7

  
  

T3

  
  

seg_ment[6]

  
  

DIG1

  
  

DIG_EN1

  
  

T4

  
  

seg_sel[0]

  
  

DIG2

  
  

DIG_EN2

  
  

V4

  
  

seg_sel[1]

  
  

DIG3

  
  

DIG_EN3

  
  

V3

  
  

seg_sel[2]

  
  

DIG4

  
  

DIG_EN4

  
  

Y3

  
  

seg_sel[3]

  
  

DIG5

  
  

DIG_EN5

  
  

Y8

  
  

seg_sel[4]

  
  

DIG6

  
  

DIG_EN6

  
  

W8

  
  

seg_sel[5]

  
  

DIG7

  
  

DIG_EN7

  
  

W10

  
  

seg_sel[6]

  
  

DIG8

  
  

DIG_EN8

  
  

Y10

  
  

seg_sel[7]

  



布局布线

管脚配置完毕后再次点击file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image062.png此键进行编译

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image071.jpg

连接开发板

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image073.jpg

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image075.jpg

上板

右键Program Device 选择Open 进入烧录界面

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image077.jpg







2.点击startfile:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image078.png开始烧录程序

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image080.jpg

Progress这一栏变为绿色显示百分之百successful即代表烧录成功

file:///C:/Users/pan/AppData/Local/Temp/msohtmlclip1/01/clip_image082.jpg






FPGA数码管动态扫描.pdf

1.4 MB, 下载次数: 4 , 下载积分: 资产 -2 信元, 下载支出 2 信元

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


手机版| 小黑屋| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2025-8-28 18:52 , Processed in 0.017951 second(s), 5 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表