【学习笔记】数电实验——发光二极管走马灯电路的设计与实现
2020-5-16
使用软件为quartusII 9.1,芯片为EPM1270T144C5
一、实验任务要求
设计并实现一个控制16个发光二极管亮灭的电路,仿真验证其功能。实现功能如下:
(1)单点移动模式:从左到右依次循环点亮16个发光二极管,每个发光二极管的点亮时间为0.5s;
(2)幕布式:从中间两个发光二极管开始点亮,向两边每次增加点亮2个发光二极管,直至点亮16个发光二极管;然后再从两边开始每次灭掉2个发光二极管,直至所有发光二极管灭掉,依次往复,每个状态持续时间为0.5s;
(3)两个模式可用按键进行切换。
二、VHDL代码
分频器:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--div50
ENTITY div50 isport(clk1: IN STD_LOGIC;clkout: OUT STD_LOGIC);
END div50;ARCHITECTURE div50_arch of div50 is
signal count: integer range 0 to 49;
beginprocess(clk1)beginif(clk1'event and clk1 = '1') thenif(count = 49) thencount <= 0;elsecount <= count + 1;end if;if count <= 24 thenclkout <= '0';elseclkout <= '1';end if;end if;end process;
END div50_arch;
防抖电路:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--anti-shake
ENTITY anti_shake_key isport(clk2: IN STD_LOGIC;reset: IN STD_LOGIC;resetn: OUT STD_LOGIC);
END anti_shake_key;ARCHITECTURE key_arch of anti_shake_key is
signal resetmp1,resetmp2:
STD_LOGIC;
beginprocess(clk2)beginif(clk2'event and clk2 = '0') thenresetmp2 <= resetmp1;resetmp1 <= reset;end if;end process;
resetn <= clk2 AND resetmp1 AND (NOT resetmp2);
END key_arch;
控制器:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--colorlamp
ENTITY colorlamp isport(clk3: IN STD_LOGIC;key_in: IN STD_LOGIC;reset: IN STD_LOGIC;led: OUT STD_LOGIC_VECTOR(15 downto 0));
END colorlamp;ARCHITECTURE colorlamp_arch of colorlamp is
type all_state is(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15);
signal cnt: STD_LOGIC :='0';
signal state:all_state;
beginprocess(key_in,reset) --01count--to change modesbeginif(key_in'event and key_in = '1') thencnt <= cnt XOR '1';end if;if(reset = '1')thencnt <= '0'; --resetend if;end process;process(clk3,reset)beginif(clk3'event and clk3 = '1')thenif(cnt = '0') thencase state iswhen s0=>state<=s1;led <= "1000000000000000";when s1=>state<=s2;led <= "0100000000000000";when s2=>state<=s3;led <= "0010000000000000";when s3=>state<=s4;led <= "0001000000000000";when s4=>state<=s5;led <= "0000100000000000";when s5=>state<=s6;led <= "0000010000000000";when s6=>state<=s7;led <= "0000001000000000";when s7=>state<=s8;led <= "0000000100000000";when s8=>state<=s9;led <= "0000000010000000";when s9=>state<=s10;led <= "0000000001000000";when s10=>state<=s11;led <= "0000000000100000";when s11=>state<=s12;led <= "0000000000010000";when s12=>state<=s13;led <= "0000000000001000";when s13=>state<=s14;led <= "0000000000000100";when s14=>state<=s15;led <= "0000000000000010";when others => state<=s0;led <= "0000000000000001";end case;end if;if(cnt = '1')thencase state iswhen s0=>state<=s1;led <= "0000000110000000";when s1=>state<=s2;led <= "0000001111000000";when s2=>state<=s3;led <= "0000011111100000";when s3=>state<=s4;led <= "0000111111110000";when s4=>state<=s5;led <= "0001111111111000";when s5=>state<=s6;led <= "0011111111111100";when s6=>state<=s7;led <= "0111111111111110";when s7=>state<=s8;led <= "1111111111111111";when s8=>state<=s9;led <= "0111111111111110";when s9=>state<=s10;led <= "0011111111111100";when s10=>state<=s11;led <= "0001111111111000";when s11=>state<=s12;led <= "0000111111110000";when s12=>state<=s13;led <= "0000011111100000";when s13=>state<=s14;led <= "0000001111000000";when s14=>state<=s15;led <= "0000000110000000";when s15=>state<=s0;led <= "0000000000000000";end case;end if;end if;if(reset = '1')thenstate <= s0; --resetend if;end process;
END colorlamp_arch;
连接电路:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
--connection
ENTITY lamp_player isport(ain:IN STD_LOGIC;reset:IN STD_LOGIC;key:IN STD_LOGIC;bout:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));
END lamp_player;ARCHITECTURE player_arch of lamp_player is
COMPONENT div50port(clk1:IN STD_LOGIC;clkout:OUT STD_LOGIC);
END COMPONENT;COMPONENT anti_shake_keyport(clk2:IN STD_LOGIC;reset:IN STD_LOGIC;resetn:OUT STD_LOGIC);
END COMPONENT;COMPONENT colorlampport(clk3:IN STD_LOGIC;key_in:IN STD_LOGIC;reset:IN STD_LOGIC;led:OUT STD_LOGIC_VECTOR(15 downto 0));
END COMPONENT;SIGNAL c0,c1:STD_LOGIC;
beginu1:div50 PORT MAP(clk1=>ain,clkout=>c0);u2:anti_shake_key PORT MAP(clk2=>ain,reset=>key,resetn=>c1);u3:colorlamp PORT MAP(clk3=>c0,key_in=>c1,reset=>reset,led(15 downto 0)=>bout(15 downto 0));
END;
三、仿真波形及分析:
(1)分频器
由图可见该部分为分频系数为50的分频器,输入信号的频率为100Hz,则分频后的信号的频率为2Hz周期为0.5s。
(2)防抖电路
输出信号resetn = clk and resetmp1 and(not resetmp2),该电路部分采用时钟信号下降沿触发,以reset信号第一次发生“抖动”为例:在第一个时钟(clk2)信号下降沿,resetmp2得到resetmp1的值为低电平“0”,resetmp1得到此时reset的值为高电平“1”,且由于边沿触发,两个信号直至第二个时钟信号下降沿到达前一直保持该值(稳定)。在第二个时钟下降沿时,resetmp2得到resetmp1的值为高电平“1”,resetmp1为时钟下降沿时刻的reset值,保持高电平“1”输出,直至第三个时钟信号下降沿到来,reset信号为低电平,resetmp1变为低电平,resetmp2在第四个时钟下降沿被赋予此刻resetmp1的值变为低电平。resetmp2由resetmp1开始变化前的值赋予,因此总是比resetmp1要“延迟”一个时钟信号,且resetmp1和resetmp2在高电平有效时间内稳定,则resetn经过resetmp1和resetmp2的处理相较于reset初始信号变得更稳定,消除了可能发生的抖动。由于在第一个被检测到的reset信号进来时,resetmp1立刻变为高电平,resetmp2慢一个时钟信号变为高电平,正好“错峰”,在resetn = clk and resetmp1 and(not resetmp2)的逻辑下得到一个稳定的按键信号。
图形可见当输入信号reset在发生“抖动”时,信号resetn稳定输出,实现了按键消抖。
(3)控制器
整体图形:
在按键之前,发光二极管从左(led15)到右(led0)依次闪烁,循环点亮,实现单点移动要求;按键产生一个脉冲信号,切换模式,从中间两个发光二极管开始点亮,向两边每次点亮两个发光二极管直至全部点亮,再从两边开始每次熄灭两个二极管,实现幕布式点亮和熄灭,如下图所示:
再次按按键,则又变回单点移动模式:
reset信号高电平有效,实现信号复位,当reset信号为1时进行复位操作,变回单点移动模式,如下图所示:
(4)完整电路仿真波形
整体图形:
在按下按键之前按照单点移动模式运行,发光二极管自左(bout15)向右(bout0)循环依次点亮,第一次按下按键后产生脉冲信号,转换模式,变为幕布式亮灭灯,第二次按下按键重新切换为单点移动模式,第三次按下按钮变为幕布式亮灭灯,注意到在这之后有一个reset高电平信号,电路复位,变为初始状态,发光二极管重新变为单点移动模式,且从最左端(bout15)开始向右“移动”。
放大仿真波形,可见输入信号ain的频率为100Hz,分频器对其进行分频,得到频率为2Hz周期为0.5s的周期信号,如下图,一个发光二极管的发光时间为0.5s,满足设计要求:
四、故障分析
在设计控制器的时候cnt对按键产生的脉冲信号进行模值为2的计数,以更方便地实现灯亮模式的转换,但是最初用的是电平触发,导致仿真波形发生多次翻转,而后改进为边沿(上升沿)触发解决问题。
五、总结和结论
本次实验进一步提升了VHDL的编程能力和图形的仿真分析能力,学会了一个较为完整的电路设计,同时实践了机械按键的消抖,对按键消抖有了更深刻的认识。
============
更新:发现自己的防抖处理好像把问题复杂化了,还有一种防抖的方式是设定一个计数器,若按键按下的持续时间未达到设定值,则认为按键无效(持续时间太短,认为是按键抖动或者其他原因造成的误差),只有在按下的持续时间超过一定值才认为是有效地按下按钮。
process(clk_1ms)//该部分与上面的报告无关,只是补充一个防抖的写法
//时间可自己设置
variable num: integer range 0 to 100 := 0;
begin
if(clk_1ms'event and clk_1ms = '1')thenif(btn = '1')thenif(num = 99)thennum := 99;elsenum := num + 1;end if;if(num > 30)thenbtn_out <= '1';//设置防抖后的有效输出elsebtn_out <= '0';end if;elsenum := 0;btn <= '0';end if;
end if;
end process;
【学习笔记】数电实验——发光二极管走马灯电路的设计与实现相关推荐
- 数电实验4:彩灯控制器设计
数电实验4:彩灯控制器设计 一.实验目的 二.实验内容 三.预习要求 四.实验报告要求 五.Verilog代码.RTL视图及仿真波形 1.Verilog代码 2.RTL视图 3.仿真波形 西南交大数电 ...
- 数电实验6:可控分频器设计
数电实验6:可控分频器设计 一.实验目的 二.基本实验内容 三.提高性实验内容(选做) 四.预习实验 五.实验报告要求 六.内容讲解(基础实验内容) 七.testbench及仿真结果 1.testbe ...
- 74LS160 笔记 数电实验
74LS160 The LS160A / 161A / 162A / 163A are high-speed 4-bit synchronous counters. 74LS160是4位同步计数器. ...
- 数电实验九:计数器的设计
转载自https://wu-kan.cn/_posts/2018-07-04-计数器的设计/ 数字电子技术实验报告 实验题目:计数器的设计 预习报告 内容一 使用JK触发器设计一个16进制异步减法计数 ...
- 数电实验六:利用MSI设计组合逻辑电路
转载自https://wu-kan.cn/_posts/2018-08-27-利用MSI设计组合逻辑电路/ 数字电子技术实验报告 实验题目:利用MSI设计组合逻辑电路 预习报告 内容一:74LS138 ...
- 数电实验:用74LS160/74LS161设计6进制,96进制,140进制计数器
制作140进制计数器: 将芯片1的EP.ET.LD.RD置高电平. 将芯片2的EP.ET通过芯片1的进位输出口C接入,LD接高电平,异步置零,因此终止位置为0100,所以先将Q2接在与非的一个脚上,然 ...
- 数电实验(一)利用与非门设计四舍五入判别电路
数电实验(一)利用与非门设计四舍五入判别电路 要求: 1.输入为8421BCD码,接四个逻辑电平开关,同时接数码管. 2.输出和LED相连. 一.写出逻辑函数: F(A,B,C,D)=∑m(5,6,7 ...
- 数电实验(三)利用3线-8线译码器74LS138和与非门设计一个表决电路
数电实验(三)利用3线-8线译码器74LS138和与非门设计一个表决电路 要求: 设计一个表决电路, 当控制端M=0时,输入端A.B.C一致同意时,输出F为1,否则输出为0:当控制端M=1时,输入端A ...
- 模电学习笔记_双极型晶体管及其放大电路(4)
前置:模电学习笔记_双极型晶体管及其放大电路(3) 一.基本知识点 2.5 晶体管单管放大电路的三种基本组态 2.5.1 共集放大电路(射极输出器.射极跟随器) 1.主要特点:高输入阻抗,低输出阻抗, ...
最新文章
- seaborn使用axes_dict函数获取displot函数生成的图像所有标题信息、使用set_title函数自定义设置多面板直方图标题(Multi-panel histogram‘s title)
- 梁云 北大 计算机,北京大学信息技术高等研究院
- 左神算法:将单链表的每K个节点之间逆序(Java版)
- 聊聊高并发(二十四)解析java.util.concurrent各个组件(六) 深入理解AQS(四)
- mongodb 字段出现次数_MongoDB数据库
- 项目管理系统Redmine安装
- Leecode刷题热题HOT100(22)——括号生成
- .NET中的Lambda表达式与匿名方法
- CSS 标签权重判断的方式
- 复数Complex类
- lol服务器稳定性补偿,lol游戏稳定性补偿皮肤领取
- php mysql 插入图片_mysql中怎样插入图片
- 老板喜欢提拔什么样的员工
- iOS苹果内购详细步骤
- 获取数据库表格的字段名、类型、长度、注释等属性
- PHP自学笔记(基础语法篇)
- 怎么看oracle定时作业,Oracle 定时作业Job详解
- 数字双向码的matlab仿真,matlab2016 ccs
- Dl4j使用Spark分布式训练指定CPU后端训练
- 计算机故障吧,摊上事了!我给客户修电脑说主板硬盘坏了,客户:你也太坑了吧!...