课程设计论文点阵LED显示的设计报告.doc
点阵LED显示的设计1课程设计指标(1)实现点阵LED的动态扫描。 (2)在点阵LED显示学生自己的中文名字、班级和学号。(3)两个功能键:1)、启动显示,2)、停止显示。2课程设计的总体方案2.1 方案比较在16×16LED发光二极管点阵上显示汉字的方式有两种:第一种方法是滚屏显示学生班级,姓名,学号,另一种方法是每次显示一个汉字,一秒钟后刷新显示第二个汉字,再一秒钟后刷新显示第三个汉字,依次刷新显示班级和学号数。循环显示以上内容。对于前一种方案,可以依次对多汉字抽取像素信息,并按顺序排队存放于ROM之中,这样便可得到一个待显示数据序列。然后通过寻址的方法来控制该数据序列的释放过程,就可实现在16×16 LED 发光二极管点阵上滚动显示多汉字信息的目的。这种方法虽然看起来比较简单,但是实现起来却有许多困难,由于滚屏显示是将需要显示的内容当成一个整体,即是在行方向上看成许多汉字排成一排,然后通过指针顺序控制汉字的显示,而对于在VHDL语言中指针的使用这方面的内容我们接触不多,没有经验,因此做起来比较困难。而且,如果滚屏显示时间把握得不好,那么显示的效果将会受到很大的影响。而采用刷新显示对时间方面要求比较低,容易控制。而且刷新显示比较符合我们的习惯。2.2 方案选择 通过上述比较,我们决定采用方案二。3设计的详细原理3.1 系统结构及工作原理LED点阵显示控制的传统方式是采用单片机或系统机作为CPU来实现,当系统显示的信息比较多时,由于单片机的输入/输出端口(I/O)有限,采用此方式的成本将大大增加,系统和程序的设计难度也急剧增加;而且,当系统完成后修改、改变显示方式或扩展时,所需改动的地方比较大,甚至有可能需要重新设计;另外,在以显示为主的系统中,单片机的运算和控制等主要功能的利用率很低,单片机的优势得不到发挥,相当于很大得资源浪费。如果采用现场可编程逻辑器件作为CPU来设计控制器,选择合适的器件,利用器件丰富的I/O口、内部逻辑和连线资源,采用自顶而下的模块化设计方法,可以方便地设计整个显示系统。由于PLD器件的外围器件很少,且可以利用PLD的编程端口(可复用)进行在系统编程,使得系统的修改、显示方式的改变和扩展都变的非常简单、方便。本系统采用单个16×16LED点阵逐列左移(或右移)显示汉字或字符,需显示汉字或符号的16×16点阵字模已经存放在字模存储器中。显示控制器由复杂可编程逻辑器件(CPLD)EPM7128SLC84-15来实现,系统组成原理框图如图1所示。系统原理是PLD控制模块首先产生点阵字模地址,并从存储器读出数据存放在16位寄存器中,然后输出到LED点阵的列,同时对点阵列循环扫描以动态显示数据,当需要显示数据字模的列和被选中的列能够协调配合起来,就可以正确显示汉字或符号。 图1点阵显示控制器原理框图3.2 控制器设计及工作原理从框图中可以看出,系统的关键在于控制器的设计。LED点阵显示数据地址的产生、点阵列扫描和需显示数据的配合以及点阵显示方式控制的实现都必须由控制器来实现。对单个16×16LED点阵显示控制器进行设计的顶层逻辑原理图如图2所示。图2 控制器顶层电路原理图原理图中包含5个模块,其中sequ模块产生读信号RDN和10位地址线(AD9.0)中的最低位地址AD0,AD0和其它模块产生的地址配合,通过8位数据线(DATA7.0)从存储器读出列高字节(AD0=1时)和低字节(AD0=0时),由于16×16点阵字模数据为32个字节,每列含两个字节即16位,它由HOUT7.0和LOUT7.0 来构成;模块R由adclk提供一个慢时钟构成16进制计数器,它的输出送给R模块,为变模计数器R提供一个模,通过模的规律变化以控制点阵按照左移或右移等显示方式进行显示;模块decode4_16是一个416译码器,其输出L15.0连接到LED点阵的列,可选中16×16LED点阵的某列,并显示sequ模块输出的点阵高低字节(字模)数据;模块R为点阵显示控制的核心,为了实现点阵汉字从右到左逐列移动显示,它由R模块提供的模,在R内部构成两个变模计数器,其中一个用来产生读字模数据的地址AD4.1,另外一个产生16×16LED点阵列扫描选择地址R3.0,列扫描选择地址由decode4_16译码后输出;模块rdd为字选择计数器,其输出可以控制多块LED显示器的显示及其显示方式。为了实现字符由右到左逐列移动显示,模块R内部设计了两个由R控制的变模加法计数器,其中R3.0为列扫描控制线。3.3 系统扩展以上为显示单个字符系统,若要同时显示多个字符时,可以按照图1加入虚线框内部分,并且模块rdd设计成R的格式,把AD4作为rdd的记数脉冲即可。按照EPM7128SLC8415的资源(64个I/O口,2个全局时钟,1个全局复位和5个可复用专用端口,5000个等效逻辑门,192个内部寄存器),若不外部扩展译码器,可以有效控制约16个字符的显示;而采用外部译码器时,可以控制的字符数将大大增加,但须注意时钟CLK的频率需要提高,以视觉不能看到整个字符的闪烁为基准。4系统软件设计控制核心模块R采用VHDL语言设计,在开发软件MAX+plus 10.2中实现,详细程序见附录A。从程序可以看出,随着R从0000到1111不断变化,即实现了系统时钟对点阵LED的不停扫描。当R="0000"时,即读出第一个字符的第一列并显示在LED的第1列;当R="0001"时,即读出第一个字符的第一、二列并显示在LED的第1、2列由此类推,由于系统扫描时钟为1KHz,扫描速度比较快,因此,当完成一次扫描时,在人眼视觉差的作用下会看到整个的字符好像是静态显示的一样。然后,在通过控制rdd按一定时间在一定的范围顺序自增,每自增1则显示一个汉字,这样就能实现多个汉字的刷新显示了。5设计的仿真和运行结果以上程序在MAX+plus10.2上仿真验证结果如图3所示。 图3 R模块仿真时序图在设计中,应注意模块sequ的记数时钟CLK频率的选择应远远大于模块R的记数时钟adclk的频率,R的记数时钟为地址最低位AD0,字选择计数器的时钟脉冲为16进制模块R的最高位OUT3。这样, R3.0变化的足够快,在点阵LED上可以看到完整的字符,并当R记数到15产生进位返回到0时,字选择模块rdd获得一个记数脉冲并加1(上升沿触发),此后将显示下一个字符。6、结论以上点阵字符显示系统在开发软件MAX+plus10.2上经仿真验证无误。另外,由于器件含有丰富的可编程连线资源,当系统显示方式和显示字符个数变化时,只需要通过开发工具修改控制器的控制逻辑和连接关系,再将修改完成的程序通过下载电缆下载到器件即可,而电路板可以不做任何改动,可见,系统的维护和修改是极其方便和容易的。当然,由于CLPD的驱动能力有限,当点阵LED显示亮度不够时,需要添加LED驱动电路以得到合适的LED显示亮度。7.心得体会两周的EDA课程设计时间虽然很短暂,但我从中获益匪浅.首先对EDA这门课程有了更深刻的了解,因为课程设计本身要求将以前所学的理论知识运用到实际的电路程序设计当中去,在设计的过程中,我无形中便加深了对VHDL语言的了解及运用能力,并且对课本以及以前学过的知识有了一个更好的总结与理解;以前的EDA实验只是针对某一个小的功能设计,而EDA课程设计对我们的总体电路的设计的要求更严格,需要通过翻阅复习以前学过的知识确立了实验总体设计方案,然后逐步细化进行各模块的设计;其次,在程序仿真的过程中总会出现一些问题,需要我们细心解决,所以这两周下来,我对程序故障的排查能力有了很大的提高;再次,通过此次课程设计,我对Altera公司的MAX+plus软件从编译、排错到波形仿真、下载到FPGA器件上仿真都有了一定的掌握。也加强了发现问题,解决问题的能力,同时还学会了和他人的有效合作、高效率的解决问题,这对我们以后的工作和学习的帮助都很有用处。参考文献电子技术实验指导书,李国丽,朱维勇主编,中国科技大学出版社。电子技术基础 模拟部分(第四版),康华光主编,高教出版社。数字电子技术基础(第四版),阎石主编,高教出版社。EDA技术基础,谭会生主编,湖南大学出版社。EDA技术实用教程,李洋主编,机械工业出版社。附录A 程序清单library IEEE; use IEEE.std_logic_1164.all;USE IEEE.STD_LOGIC_UNSIGNED.ALL;entity dot_led is port(clk :in std_logic; -系统时钟(1KHz) key: in std_logic_vector(1 downto 0);-功能键,key="01",启动显示;key="10",停止显示 R:out std_logic_vector(3 downto 0); -点阵LED行输入,当R="0000", 表示第一列有效. L:out std_logic_vector(15 downto 0); -点阵LED列输入 end dot_led; architecture display of dot_led is signal rdd:std_logic_vector(3 downto 0);-控制显示一个汉字或字符的时间 signal ldd:std_logic_vector(3 downto 0);-ldd用来选择扫描的列 signal cnt0: integer range 0 to 2000; signal temp: std_logic_vector(1 downto 0); begin process(clk,key) begin if (key="11") then cnt0<=0;-防止按键抖动 elsif (clk'event and clk='1') then if cnt0>1999 then cnt0<=0;temp<=key; else cnt0<=cnt0+1; end if; end if; end process; process(clk) variable cnt: integer; variable tmp:std_logic_vector(3 downto 0); begin if clk'event and clk='1' then if cnt<500000 then cnt:=cnt+1; else cnt:=0; if tmp="1100" then tmp:="0000" else tmp:=tmp+1; end if; end if; end if; rdd<=tmp; end process; process(clk) variable tmb:std_logic_vector(3 downto 0); begin if clk'event and clk='1' then if tmb="1111" then tmb:="0000" else tmb:=tmb+1; end if; end if; ldd<=tmb; end process; process(rdd,ldd) begin if rdd="0000"and temp="01" then -电 case ldd is when "0000" => R<="0000" L<=X"0000" when "0001" => R<="0001" L<=X"0000" when "0010" => R<="0010" L<=X"1FE0" when "0011" => R<="0011" L<=X"1FE0" when "0100" => R<="0100" L<=X"1B20" when "0101" => R<="0101" L<=X"1B20" when "0110" => R<="0110" L<=X"1B20" when "0111" => R<="0111" L<=X"7FFE" when "1000" => R<="1000" L<=X"7FFE" when "1001" => R<="1001" L<=X"1B26" when "1010" => R<="1010" L<=X"1B26" when "1011" => R<="1011" L<=X"1B26" when "1100" => R<="1100" L<=X"1FE6" when "1101" => R<="1101" L<=X"1FE6" when "1110" => R<="1110" L<=X"000E" when "1111" => R<="1111" L<=X"000E" when others =>null; end case; elsif rdd="0001"and temp="01" then -子 case ldd is when "0000" => R<="0000" L<=X"0000" when "0001" => R<="0001" L<=X"0300" when "0010" => R<="0010" L<=X"6300" when "0011" => R<="0011" L<=X"6300" when "0100" => R<="0100" L<=X"6300" when "0101" => R<="0101" L<=X"6306" when "0110" => R<="0110" L<=X"6306" when "0111" => R<="0111" L<=X"67FE" when "1000" => R<="1000" L<=X"6FFE" when "1001" => R<="1001" L<=X"7B00" when "1010" => R<="1010" L<=X"7B00" when "1011" => R<="1011" L<=X"7300" when "1100" => R<="1100" L<=X"6300" when "1101" => R<="1101" L<=X"0300" when "1110" => R<="1110" L<=X"0300" when "1111" => R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="0010"and temp="01" then -06 case ldd is when"0000" => R<="0000" L<=X"1FFC" when "0001" => R<="0001" L<=X"1004" when "0010" => R<="0010" L<=X"1004" when "0011" => R<="0011" L<=X"1004" when "0100" => R<="0100" L<=X"1004" when "0101" => R<="0101" L<=X"1004" when "0110" => R<="0110" L<=X"1FFC" when "0111" => R<="0111" L<=X"0000" when "1000" => R<="1000" L<=X"1FFC" when "1001" => R<="1001" L<=X"1084" when "1010" => R<="1010" L<=X"1084" when "1011" => R<="1011" L<=X"1084" when "1100" => R<="1100" L<=X"1084" when "1101" => R<="1101" L<=X"1084" when "1110" => R<="1110" L<=X"10FC" when "1111" => R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="0011"and temp="01" then -02 case ldd is when "0000"=> R<="0000" L<=X"1FFC" when "0001"=> R<="0001" L<=X"1004" when "0010"=> R<="0010" L<=X"1004" when "0011"=> R<="0011" L<=X"1004" when "0100"=> R<="0100" L<=X"1004" when "0101"=> R<="0101" L<=X"1004" when "0110"=> R<="0110" L<=X"1FFC" when "0111"=> R<="0111" L<=X"0000" when "1000"=> R<="1000" L<=X"10FC" when "1001"=> R<="1001" L<=X"1084" when "1010"=> R<="1010" L<=X"1084" when "1011"=> R<="1011" L<=X"1084" when "1100"=> R<="1100" L<=X"1084" when "1101"=> R<="1101" L<=X"1084" when "1110"=> R<="1110" L<=X"1F84" when "1111"=> R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="0100"and temp="01" then -班 case ldd is when "0000"=> R<="0000" L<=X"0000" when "0001"=> R<="0001" L<=X"318C" when "0010"=> R<="0010" L<=X"318C" when "0011"=> R<="0011" L<=X"3FFC" when "0100"=> R<="0100" L<=X"318C" when "0101"=> R<="0101" L<=X"310E" when "0110"=> R<="0110" L<=X"0F86" when "0111"=> R<="0111" L<=X"000E" when "1000"=> R<="1000" L<=X"7FFC" when "1001"=> R<="1001" L<=X"7FFE" when "1010"=> R<="1010" L<=X"3186" when "1011"=> R<="1011" L<=X"3186" when "1100"=> R<="1100" L<=X"3FFE" when "1101"=> R<="1101" L<=X"3186" when "1110"=> R<="1110" L<=X"3186" when "1111"=> R<="1111" L<=X"3186" when others =>null; end case; elsif rdd="0101"and temp="01" then -吴 case ldd is when "0000"=> R<="0000" L<=X"0000" when "0001"=> R<="0001" L<=X"0042" when "0010"=> R<="0010" L<=X"0046" when "0011"=> R<="0011" L<=X"7C46" when "0100"=> R<="0100" L<=X"4546" when "0101"=> R<="0101" L<=X"454C" when "0110"=> R<="0110" L<=X"4558" when "0111"=> R<="0111" L<=X"45F0" when "1000"=> R<="1000" L<=X"45E0" when "1001"=> R<="1001" L<=X"4558" when "1010"=> R<="1010" L<=X"454C" when "1011"=> R<="1011" L<=X"4546" when "1100"=> R<="1100" L<=X"7C46" when "1101"=> R<="1101" L<=X"0046" when "1110"=> R<="1110" L<=X"0046" when "1111"=> R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="0110"and temp="01" then -云 case ldd is when "0000"=> R<="0000" L<=X"0000" when "0001"=> R<="0001" L<=X"0600" when "0010"=> R<="0010" L<=X"060C" when "0011"=> R<="0011" L<=X"361C" when "0100"=> R<="0100" L<=X"363C" when "0101"=> R<="0101" L<=X"367C" when "0110"=> R<="0110" L<=X"37EC" when "0111"=> R<="0111" L<=X"37CC" when "1000"=> R<="1000" L<=X"378C" when "1001"=> R<="1001" L<=X"360C" when "1010"=> R<="1010" L<=X"360C" when "1011"=> R<="1011" L<=X"363C" when "1100"=> R<="1100" L<=X"361C" when "1101"=> R<="1101" L<=X"060C" when "1110"=> R<="1110" L<=X"0604" when "1111"=> R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="0111"and temp="01" then -20 case ldd is when "0000"=> R<="0000" L<=X"10FC" when "0001"=> R<="0001" L<=X"1084" when "0010"=> R<="0010" L<=X"1084" when "0011"=> R<="0011" L<=X"1084" when "0100"=> R<="0100" L<=X"1084" when "0101"=> R<="0101" L<=X"1084" when "0110"=> R<="0110" L<=X"1F84" when "0111"=> R<="0111" L<=X"0000" when "1000"=> R<="1000" L<=X"1FFC" when "1001"=> R<="1001" L<=X"1004" when "1010"=> R<="1010" L<=X"1004" when "1011"=> R<="1011" L<=X"1004" when "1100"=> R<="1100" L<=X"1004" when "1101"=> R<="1101" L<=X"1004" when "1110"=> R<="1110" L<=X"1FFC" when "1111"=> R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="1000"and temp="01" then -06 case ldd is when"0000" => R<="0000" L<=X"1FFC" when "0001" => R<="0001" L<=X"1004" when "0010" => R<="0010" L<=X"1004" when "0011" => R<="0011" L<=X"1004" when "0100" => R<="0100" L<=X"1004" when "0101" => R<="0101" L<=X"1004" when "0110" => R<="0110" L<=X"1FFC" when "0111" => R<="0111" L<=X"0000" when "1000" => R<="1000" L<=X"1FFC" when "1001" => R<="1001" L<=X"1084" when "1010" => R<="1010" L<=X"1084" when "1011" => R<="1011" L<=X"1084" when "1100" => R<="1100" L<=X"1084" when "1101" => R<="1101" L<=X"1084" when "1110" => R<="1110" L<=X"10FC" when "1111" => R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="1001"and temp="01" then -57 case ldd is when "0000"=> R<="0000" L<=X"1F84" when "0001"=> R<="0001" L<=X"1084" when "0010"=> R<="0010" L<=X"1084" when "0011"=> R<="0011" L<=X"1084" when "0100"=> R<="0100" L<=X"1084" when "0101"=> R<="0101" L<=X"1084" when "0110"=> R<="0110" L<=X"10FC" when "0111"=> R<="0111" L<=X"0000" when "1000"=> R<="1000" L<=X"1000" when "1001"=> R<="1001" L<=X"1000" when "1010"=> R<="1010" L<=X"1000" when "1011"=> R<="1011" L<=X"1000" when "1100"=> R<="1100" L<=X"1000" when "1101"=> R<="1101" L<=X"1000" when "1110"=> R<="1110" L<=X"1FFC" when "1111"=> R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="1010"and temp="01" then -17 case ldd is when "0000"=> R<="0000" L<=X"0000" when "0001"=> R<="0001" L<=X"0000" when "0010"=> R<="0010" L<=X"0000" when "0011"=> R<="0011" L<=X"0000" when "0100"=> R<="0100" L<=X"0000" when "0101"=> R<="0101" L<=X"0000" when "0110"=> R<="0110" L<=X"1FFC" when "0111"=> R<="0111" L<=X"0000" when "1000"=> R<="1000" L<=X"1000" when "1001"=> R<="1001" L<=X"1000" when "1010"=> R<="1010" L<=X"1000" when "1011"=> R<="1011" L<=X"1000" when "1100"=> R<="1100" L<=X"1000" when "1101"=> R<="1101" L<=X"1000" when "1110"=> R<="1110" L<=X"1FFC" when "1111"=> R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="1011"and temp="01" then -02 case ldd is when "0000"=> R<="0000" L<=X"1FFC" when "0001"=> R<="0001" L<=X"1004" when "0010"=> R<="0010" L<=X"1004" when "0011"=> R<="0011" L<=X"1004" when "0100"=> R<="0100" L<=X"1004" when "0101"=> R<="0101" L<=X"1004" when "0110"=> R<="0110" L<=X"1FFC" when "0111"=> R<="0111" L<=X"0000" when "1000"=> R<="1000" L<=X"10FC" when "1001"=> R<="1001" L<=X"1084" when "1010"=> R<="1010" L<=X"1084" when "1011"=> R<="1011" L<=X"1084" when "1100"=> R<="1100" L<=X"1084" when "1101"=> R<="1101" L<=X"1084" when "1110"=> R<="1110" L<=X"1F84" when "1111"=> R<="1111" L<=X"0000" when others =>null; end case; elsif rdd="1100"and temp="01" then