北邮数电实验下LED点阵风扇的设计与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字电路与逻辑设计实验
实验报告
实验名称:led点阵风扇的设计与实现学院:电子工程学院
专业:电子科学与技术
班级:
班内序号:
学号:
姓名:
北京邮电大学
2015年11月9日
目录
一、任务要求 (3)
1.基本要求: (3)
2.提高要求: (3)
二、系统设计 (3)
1. 设计思路 (3)
2. 总体框图 (4)
3. 分块设计 (7)
三、仿真波形及波形分析 (8)
四、源程序(包括注释) (12)
五、功能说明及资源利用情况 (23)
1. 功能说明 (23)
2. 资源利用情况 (24)
六、故障及问题分析 (25)
七、总结和结论 (27)
1.总结 (27)
2.结论 (27)
一、任务要求
1.基本要求:
(1)用8*8点阵模拟风扇转动,并采用双色点阵显示。
(2)风扇转动方式如图1所示,包括四个点阵显示状态并按顺序循环显示。
风扇转动速度根据环境温度分为4档,其中1档的四个显示状态之间的切换时间为2秒,2档为1秒,3档为0.5秒,4档为静止不动。
(3)环境温度通过2个BTN按键设置,一个用来增加,一个用来减少,温度可设置范围为10℃~40℃,温度精度为1℃,并用两个数码管进行温度显示。
风扇根据不同的温度自动采用不同的转动速度,其中20℃~24℃对应1档,25℃~29℃对应2档,30℃~40℃对应3档,10℃~19℃对应4档,用一个数码管显示档位。
(4)定时模式:在风扇不同转动速度下,可以通过按键切换进入定时模式。
定时时间可设置范围为20~59秒,采用两个数码管进行倒计时,当倒计时结束后,风扇状态保持静止不动。
(5)设置开关键。
风扇开机初始状态为20℃、1档,并有不小于5秒的开机音乐。
关机状态为点阵全灭。
图1
2.提高要求:
(1)设计LED风扇的其他工作模式。
(2)利用实验板上的温度传感器代替按键直接获取温度数据,实现对LED 风扇四档转速的自动控制。
(3)用数码管实时显示温度传感器的温度数据,精度为0.1℃。
(4)自拟其他功能。
二、系统设计
1.设计思路
在LED点阵风扇的设计与实现中,首先进行了分频器的设计:由于所使用电路板的时钟频率为50MHz,而需要使用的点阵、数码管扫描频率为1kHz,扇叶切换频率分别为2Hz、1Hz和0.5Hz,故首先将时钟频率进行四次分频。
然后是按键控制温度调节部分的实现,由于题中要求温度在10-40之间的两位数,所以在vhdl的程序设计中将这两位数拆成两个四位的BCD码,并用temerature_h和temperature_l来分别表示,每当需要温度增减时,通过控制这两个信号来实现温度的变化。
接着是倒计时部分:同样是使用两个四位BCD 码来表示,并且创建了一个标准信号来记录倒计时是否结束,以此来完成倒计时结束后风扇的停止转动。
以温度的输入来实现档位的选择,首先判断记录倒计时的信号值,若倒计时结束,则选择4档;否则,判断高位的温度值,当其为1、3、4时均有分别对应的档位,当起为2时再用对应的CASE 语句来判断档位。
点阵显示部分:根据档位的判断来选择合适的时钟控制风扇扇叶的旋转速度,用1kHz 的时钟来对点阵的行进行扫描,低频时钟用来切换风扇扇叶的四个图形。
数码管显示:6个数码管稳定显示需要至少300Hz 频率的时钟,故用1kHz 时钟来扫描数码管,温度的高低位数字、时间的高低位数字以及档位,都通过一个译码器来输出对应数码管显示数字的7位向量,使得当时钟扫描到某一个数码管时,可以正确地显示要表达的数字。
音乐播放:使用蜂鸣器播放音乐同样也需要两个时钟来完成对应功能,一个时钟来完成节拍的表达,另一个时钟来输出乐音的音调,如C 、D 、E 、F 等,使得当节拍的时钟到来时能够输出对应简谱中的音调。
2. 总体框图
(1) 系统顶层框图
(2) 系统对外接口图
(3) 逻辑划分框图
disp1
,disp0 led 点阵显示 时钟clk 开关clr 温度调节定时转换row ,colg ,colr seg cat
(4)流程图
(5) MDS图
3.分块设计
p1:将50MHz的时钟clk分500000次频变为为1kHz的时钟clk_1kHz,来完成对点阵行row以及6个数码管cat的扫描。
若clr=‘0’即关机状态,则输出时钟及计数变量均置零;否则当时钟上升沿到来时,计数变量开始计数,时钟也开始输出。
p2:将1kHz的clk_1kHz分500次频,输出频率为2Hz的clk_2Hz,来完成风扇3档转速的输出。
同样为使关机状态点阵全灭,需先判断clr的值。
p3:将clk_2Hz二分频,输出频率为1Hz的clk_1Hz,来完成风扇2档转速的输出。
p4:将clk_1Hz二分频,输出频率为0.5Hz的clk_half1Hz来完成风扇1档转速的输出。
p5:为防止由于按键抖动带来的按键一次增加或减少温度过多,使用2Hz 的时钟来判断按键是否正在使用以实现按键的防抖。
同样,首先使用IF语句要判断clr的值,如果为0,则温度变为20℃;否则当2Hz的时钟上升沿到来时,若同时表达温度上升的输入信号temp_up为1,则接着判断其高位是否为0100。
若高位为0100则,温度输出值保持40℃不变,不再累加;否则温度的个位增加1,当个位满足1010时,置零且十位增加1。
同理,当表达温度下降的输入信号temp_down为1时也如此判断,区别在于判断其最小值是否为10,并且相减时判断低位为1111时,则十位减一,个位置为0101。
这样的判断语句的设置,能够实现关机时数码管全灭,由按键来控制温度的增减,并且温度范围为10~40℃的实验要求。
p6:档位判断模块,当表达倒计时结束的信号count_end为1时,档位输出为0,其他的档位输入由一个嵌套的CASE语句来完成。
温度的十位数字为0001、0011、0100即1、3、4时,档位输出分别为00、11、11即4、3、3档,十位为其他数字即2时,再判断个位数字以此来实现输出1档和2档。
此模块可以实现由温度到档位的判断选择。
p7:倒计时模块,直接置入一个倒计时数字30,start变化时开始倒计时,
未完成实验20~59s可调节要求。
当clr为0时即关机状态下,count_end置零,time_h和time_l为1111,不显示;若clr为1即开机状态下,start 为1,则开始倒计时,倒计时算法与降低温度类似,但需区分出1s->0s时,使count_end为1,标志倒计时结束,到达0s时需保持时间不变。
如果start 为0,为开启倒计时状态,则将时间置为30。
p8:译码器,由于数码管现实的档位、倒计时时间的高低位以及温度的高低位,均为4位BCD码,故需要将它们转换为能够在数码管上显示的对应数字,使用5个CASE语句来进行选择输出。
p9:数码管扫描,首先判断开关机状态,若为开机则判断start是否为1,start为0时只显示档位和温度;start为1时,全部显示。
然后将1kHz时钟6分频,每个时钟上升沿代表了扫描到一个cat,若显示,则将其置为0其余为1,输出对应从译码器得到的7位编码。
p10:使用CASE语句根据档位来选择输出时钟,dang为00时,输出时钟为0,扇叶静止;dang为01时,表示1档,输出时钟为clk_half1Hz;dang 为10时,表示2档,输出时钟为clk_1Hz;dang为11时,表示3档,输出时钟为clk_2Hz。
p11:点阵显示模块,在开机状态下,使用1kHz时钟循环扫描点阵行,每扫描到某一行,点亮对应列的led灯,以此来实现在点阵上稳定显示某一图案。
于此同时,用档位决定的低频时钟来扫描4幅图案,每一图案对应着自己的行列编码,以此来用低频时钟控制扇叶扫描的速率。
p12:节拍分频器,为得到24Hz的节拍频率,对时钟进行分频系数为2083332的分频,使得得到的节拍每记24个数约为1s。
p13:依据输入的tone分频系数来对clk进行分频,以实现beep对不同音调的输出。
p14:以tape的时钟为输入时钟,输出对应节拍上音乐的分频系数。
p15:对beep输出音调的时钟频率,以实现音乐的输出。
三、仿真波形及波形分析
p1:由于分频系数为50000过高,无法进行仿真。
p2:由于分频系数为500过高,无法进行仿真。
p3:2Hz->1Hz,clr置零时无时钟输出,其他时刻对时钟进行二分频。
图 2
p4:1Hz->0.5Hz,与p3功能相同。
图3
p5:温度调节模块,temp_up为1时,temperature_l在时钟上升沿到来时增加;temp_down为1时,temperature_l在时钟上升沿到来时减少;clr为0时,温度重新置为20。
图 4
p6:档位选择模块,当count_end为1时,dang输出为0即4档;当温度输入为10~40℃以外的数值时,由于总体程序中已有限制,故未考虑该情况,输出档位均为1,其余情况下dang 输出为1、2、3分别代表1档、2档、3档,仿真情况符合实验要求。
图 5
p7:开机时若start为1,则开始倒计时;若start为0则时间重新置为30,start 为1,则继续开始倒计时,符合实验要求。
图 6
p8:4位BCD码与7位显示码之间对应正确。
图7
p9:由于seg不存在真实数值,无法仿真,故仅仿真数码管cat的显示。
当start 为1时扫描5个数码管,当start为0时扫描3个数码管,符合设计思路。
图8
p10:档位选择器,输出时钟无确切数值,故无法仿真。
p11:点阵扫描与图案切换时钟频率相差过大,故无法进行仿真。
p12:节拍分频器,分频系数过大,故无法仿真。
p13:音调分频,分频系数过大,故无法仿真。
p14:输出信号为整形数值,故无法仿真。
p15:tone_clk无有效时钟数值,故无法进行仿真。
四、源程序(包括注释)
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY fan IS
PORT(
clk,clr:IN STD_lOGIC;--clr==>SW0
temp_up,temp_down:IN STD_LOGIC;--temp_up==>BTN1;temp_down==>BTN0;
start:IN STD_LOGIC;--start==>SW7
seg:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);--控制数字显示
cat:OUT STD_LOGIC_VECTOR(5 DOWNTO 0);--共阴极数码管
row:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
colr:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
colg:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
beep:OUT STD_LOGIC);
END fan;
ARCHITECTURE display OF fan IS
----------------------------------------------------------------------------分频1
SIGNAL clk_1kHz:STD_LOGIC;
SIGNAL clk_out1:STD_LOGIC;
----------------------------------------------------------------------------分频2
SIGNAL clk_2Hz:STD_LOGIC;
SIGNAL clk_out2:STD_LOGIC;
----------------------------------------------------------------------------分频3
SIGNAL clk_1Hz:STD_LOGIC;
SIGNAL clk_out3:STD_LOGIC;
----------------------------------------------------------------------------分频4
SIGNAL clk_half1Hz:STD_LOGIC;
SIGNAL clk_out4:STD_LOGIC;
----------------------------------------------------------------------------温度输入调节
SIGNAL temperature_h:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL temperature_l:STD_LOGIC_VECTOR(3 DOWNTO 0);
----------------------------------------------------------------------------档位选择
SIGNAL count_end:STD_LOGIC;
SIGNAL dang:STD_LOGIC_VECTOR(1 DOWNTO 0);
----------------------------------------------------------------------------倒计时
SIGNAL time_h:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL time_l:STD_LOGIC_VECTOR(3 DOWNTO 0);
----------------------------------------------------------------------------数码管显示
SIGNAL dang_seg:STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL time_h_seg:STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL time_l_seg:STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL temperature_h_seg:STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL temperature_l_seg:STD_LOGIC_VECTOR(6 DOWNTO 0);
----------------------------------------------------------------------------风扇转速时钟输出
SIGNAL clk_out:STD_LOGIC;
----------------------------------------------------------------------------点阵显示
SIGNAL row_temp,colr_temp,colg_temp:STD_LOGIC_VECTOR(7 DOWNTO 0);
----------------------------------------------------------------------------节拍分频
SIGNAL tape_clk:STD_LOGIC;
----------------------------------------------------------------------------音调分频
SIGNAL tone_tmp:INTEGER RANGE 0 TO 64000;
SIGNAL tone_clk:STD_LOGIC;
BEGIN
----------------------------------------------------------------------------分频1:将50MHz时钟频率分为1KHz
p1:PROCESS(clk,clr)
V ARIABLE tmp1:INTEGER RANGE 0 TO 24999;
BEGIN
IF clr='0' THEN tmp1:=0;clk_1kHz<= '0';
ELSIF clk'EVENT AND clk='1' THEN
IF tmp1=24999 THEN tmp1:=0;clk_out1<=NOT clk_out1;
ELSE tmp1:=tmp1+1;
END IF;
clk_1kHz<=clk_out1;
END IF;
END PROCESS p1;
----------------------------------------------------------------------------分频2:利用1kHz时钟分得2Hz时钟
p2:PROCESS(clk_1kHz,clr)
V ARIABLE tmp2:INTEGER RANGE 0 TO 249;
BEGIN
IF clr='0' THEN tmp2:=0;clk_2Hz<='0';
ELSIF clk_1kHZ'EVENT AND clk_1kHz='1' THEN
IF tmp2=249 THEN tmp2:=0;clk_out2<=NOT clk_out2;
ELSE tmp2:=tmp2+1;
END IF;
clk_2Hz<=clk_out2;
END IF;
END PROCESS p2;
----------------------------------------------------------------------------分频3:利用2Hz时钟分得1Hz时钟
p3:PROCESS(clk_2Hz,clr)
BEGIN
IF clr='0' THEN clk_out3<='0';
ELSIF clk_2Hz'EVENT AND clk_2Hz='1' THEN
clk_out3<=NOT clk_out3;
END IF;
clk_1Hz<=clk_out3;
END PROCESS p3;
----------------------------------------------------------------------------分频4:利用1Hz时钟分得0.5Hz时钟
p4:PROCESS(clk_1Hz,clr)
BEGIN
IF clr='0' THEN clk_out4<='0';
ELSIF clk_1Hz'EVENT AND clk_1Hz='1' THEN
clk_out4<=NOT clk_out4;
END IF;
clk_half1Hz<=clk_out4;
END PROCESS p4;
----------------------------------------------------------------------------温度输入调节
p5:PROCESS(clk_2Hz,clr)
V ARIABLE temperature_h_temp,temperature_l_temp: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF clr='0' THEN temperature_h_temp:="0010";temperature_l_temp:="0000";
ELSIF(clk_2Hz'EVENT AND clk_2Hz='1')THEN
IF temp_up='1' THEN
IF temperature_h_temp="0100" THEN temperature_h_temp:="0100";temperature_l_temp:="0000";
ELSE temperature_l_temp:=temperature_l_temp+"0001";
IF temperature_l_temp="1010" THEN
temperature_l_temp:="0000";
temperature_h_temp:=temperature_h_temp+"0001";
END IF;
END IF;
END IF;
IF temp_down='1' THEN
IF(temperature_h_temp="0001" AND temperature_l_temp="0000")THEN temperature_h_temp:="0001";temperature_l_temp:="0000";
ELSE temperature_l_temp:=temperature_l_temp-"0001";
IF temperature_l_temp="1111" THEN
temperature_l_temp:="1001";
temperature_h_temp:=temperature_h_temp-"0001";
END IF;
END IF;
END IF;
END IF;
temperature_h<=temperature_h_temp;
temperature_l<=temperature_l_temp;
END PROCESS p5;
----------------------------------------------------------------------------档位选择
p6:PROCESS(clk_2Hz,count_end)
BEGIN
IF count_end='1' THEN dang<="00";
ELSE
CASE temperature_h IS
WHEN "0001"=>dang<="00";--1-0
WHEN "0011"=>dang<="11";--3-3
WHEN "0100"=>dang<="11";--4-3
WHEN OTHERS=> --2
CASE temperature_l IS
WHEN "0000"=>dang<="01";--0-1
WHEN "0001"=>dang<="01";--1-1
WHEN "0010"=>dang<="01";--2-1
WHEN "0011"=>dang<="01";--3-1
WHEN "0100"=>dang<="01";--4-1
WHEN OTHERS=>dang<="10";--5,6,7,8,9-2
END CASE;
END CASE;
END IF;
END PROCESS p6;
----------------------------------------------------------------------------倒计时
p7:PROCESS(clk_1Hz,start,clr)
V ARIABLE time_h_temp,time_l_temp:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF clr='0' THEN count_end<='0';time_h_temp:="1111";time_l_temp:="1111";
ELSE
IF clk_1Hz'EVENT AND clk_1Hz='1' THEN
IF start='1' THEN
IF(time_h_temp="0000" AND time_l_temp="0001")THEN time_h_temp:="0000";time_l_temp:="0000";count_end<='1';
ELSE
IF(time_h_temp="0000" AND time_l_temp="0000")THEN time_h_temp:="0000";time_l_temp:="0000";
ELSE
IF time_l_temp="0000" THEN time_l_temp:="1001";time_h_temp:=time_h_temp-"0001";
ELSE time_l_temp:=time_l_temp-"0001";
END IF;
END IF;
END IF;
ELSE time_h_temp:="0011";time_l_temp:="0000";count_end<='0';
END IF;
END IF;
END IF;
time_l<=time_l_temp;
time_h<=time_h_temp;
END PROCESS p7;
----------------------------------------------------------------------------译码器
p8:PROCESS(dang,time_h,time_l,temperature_h,temperature_l)
BEGIN
CASE dang IS
WHEN "00"=>dang_seg<="0110011";--num4
WHEN "01"=>dang_seg<="0110000";--num1
WHEN "10"=>dang_seg<="1101101";--num2
WHEN "11"=>dang_seg<="1111001";--num3
WHEN OTHERS=>dang_seg<="0000000";
END CASE;
CASE time_h IS
WHEN "0000"=>time_h_seg<="1111110";--0
WHEN "0001"=>time_h_seg<="0110000";--1
WHEN "0010"=>time_h_seg<="1101101";--2
WHEN "0011"=>time_h_seg<="1111001";--3
WHEN "0100"=>time_h_seg<="0110011";--4
WHEN "0101"=>time_h_seg<="1011011";--5
WHEN "0110"=>time_h_seg<="1011111";--6
WHEN "0111"=>time_h_seg<="1110000";--7
WHEN "1000"=>time_h_seg<="1111111";--8
WHEN "1001"=>time_h_seg<="1111011";--9
WHEN OTHERS=>time_h_seg<="0000000";
END CASE;
CASE time_l IS
WHEN "0000"=>time_l_seg<="1111110";--0
WHEN "0001"=>time_l_seg<="0110000";--1
WHEN "0010"=>time_l_seg<="1101101";--2
WHEN "0011"=>time_l_seg<="1111001";--3
WHEN "0100"=>time_l_seg<="0110011";--4
WHEN "0101"=>time_l_seg<="1011011";--5
WHEN "0110"=>time_l_seg<="1011111";--6
WHEN "0111"=>time_l_seg<="1110000";--7
WHEN "1000"=>time_l_seg<="1111111";--8
WHEN "1001"=>time_l_seg<="1111011";--9
WHEN OTHERS=>time_l_seg<="0000000";
END CASE;
CASE temperature_h IS
WHEN "0000"=>temperature_h_seg<="1111110";--0 WHEN "0001"=>temperature_h_seg<="0110000";--1 WHEN "0010"=>temperature_h_seg<="1101101";--2 WHEN "0011"=>temperature_h_seg<="1111001";--3 WHEN "0100"=>temperature_h_seg<="0110011";--4 WHEN "0101"=>temperature_h_seg<="1011011";--5 WHEN "0110"=>temperature_h_seg<="1011111";--6 WHEN "0111"=>temperature_h_seg<="1110000";--7 WHEN "1000"=>temperature_h_seg<="1111111";--8 WHEN "1001"=>temperature_h_seg<="1111011";--9 WHEN OTHERS=>temperature_h_seg<="0000000"; END CASE;
CASE temperature_l IS
WHEN "0000"=>temperature_l_seg<="1111110";--0 WHEN "0001"=>temperature_l_seg<="0110000";--1 WHEN "0010"=>temperature_l_seg<="1101101";--2 WHEN "0011"=>temperature_l_seg<="1111001";--3 WHEN "0100"=>temperature_l_seg<="0110011";--4
WHEN "0101"=>temperature_l_seg<="1011011";--5
WHEN "0110"=>temperature_l_seg<="1011111";--6
WHEN "0111"=>temperature_l_seg<="1110000";--7
WHEN "1000"=>temperature_l_seg<="1111111";--8
WHEN "1001"=>temperature_l_seg<="1111011";--9
WHEN OTHERS=>temperature_l_seg<="0000000";
END CASE;
END PROCESS p8;
----------------------------------------------------------------------------数码管扫描
p9:PROCESS(clk_1kHz,clr,start)
V ARIABLE all_cat:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
IF clr='0' THEN cat<="111111";seg<="0000000";
ELSE
IF clk_1kHz'EVENT AND clk_1kHz='1' THEN
IF all_cat="101" THEN all_cat:="000";
ELSE all_cat:=all_cat+1;
END IF;
END IF;
IF clk_1kHz'EVENT AND clk_1kHz='1' THEN
IF start='1' THEN
CASE all_cat IS
WHEN "000"=>cat<="011111";seg<=time_h_seg;--ten digit
WHEN "001"=>cat<="101111";seg<=time_l_seg;--single digit
WHEN "010"=>cat<="111011";seg<=dang_seg;
WHEN "011"=>cat<="111101";seg<=temperature_h_seg;--ten digit
WHEN "100"=>cat<="111110";seg<=temperature_l_seg;--single digit
WHEN OTHERS=>cat<="111111";seg<="0000000";
END CASE;
ELSE
CASE all_cat IS
WHEN "010"=>cat<="111011";seg<=dang_seg;
WHEN "011"=>cat<="111101";seg<=temperature_h_seg;--ten digit
WHEN "100"=>cat<="111110";seg<=temperature_l_seg;--single digit
WHEN OTHERS=>cat<="111111";seg<="0000000";
END CASE;
END IF;
END IF;
END IF;
END PROCESS p9;
----------------------------------------------------------------------------风扇转速时钟输出
P10:PROCESS(dang)
BEGIN
CASE dang IS
WHEN "00"=>clk_out<='0';--dang 4
WHEN "01"=>clk_out<=clk_half1Hz;--dang 1
WHEN "10"=>clk_out<=clk_1Hz;--dang 2
WHEN "11"=>clk_out<=clk_2Hz;--dang 3
WHEN OTHERS=>clk_out<='0';
END CASE;
END PROCESS p10;
---------------------------------------------------------------------------点阵显示
p11:PROCESS(clk_1kHz,clk_out,clr)
V ARIABLE picture:STD_LOGIC_VECTOR(1 DOWNTO 0):="00";
BEGIN
IF clr='0' THEN row_temp<="11111111";colr_temp<="00000000";colg_temp<="00000000";picture:="00";
ELSE
IF clk_out'EVENT AND clk_out='1' THEN
IF picture="11" THEN picture:="00";
ELSE picture:=picture+"01";
END IF;
END IF;
IF clk_1kHz'EVENT AND clk_1kHz='1' THEN
CASE row_temp IS
WHEN "01111111"=>row_temp<="10111111";
WHEN "10111111"=>row_temp<="11011111";
WHEN "11011111"=>row_temp<="11101111";
WHEN "11101111"=>row_temp<="11110111";
WHEN "11110111"=>row_temp<="11111011";
WHEN "11111011"=>row_temp<="11111101";
WHEN "11111101"=>row_temp<="11111110";
WHEN "11111110"=>row_temp<="01111111";
WHEN OTHERS =>row_temp<="01111111";
END CASE;
END IF;
IF picture="00" THEN
CASE row_temp IS
WHEN
"01111111"=>colr_temp<="10000000";colg_temp<="00000001";
WHEN
"10111111"=>colr_temp<="01000000";colg_temp<="00000010";
WHEN
"11011111"=>colr_temp<="00100000";colg_temp<="00000100";
WHEN
"11101111"=>colr_temp<="00010000";colg_temp<="00001000";
WHEN
"11110111"=>colr_temp<="00001000";colg_temp<="00010000";
WHEN
"11111011"=>colr_temp<="00000100";colg_temp<="00100000";
WHEN
"11111101"=>colr_temp<="00000010";colg_temp<="01000000";
WHEN
"11111110"=>colr_temp<="00000001";colg_temp<="10000000";
WHEN OTHERS=>colr_temp<="00000000";colg_temp<="00000000";
END CASE;--shape 1
ELSIF picture="01" THEN
CASE row_temp IS
WHEN
"01111111"=>colr_temp<="00010000";colg_temp<="00000000";
WHEN
"10111111"=>colr_temp<="00010000";colg_temp<="00000000";
WHEN
"11011111"=>colr_temp<="00010000";colg_temp<="00000000";
WHEN
"11101111"=>colr_temp<="00010000";colg_temp<="00001111";
WHEN
"11110111"=>colr_temp<="00001000";colg_temp<="11110000";
WHEN
"11111011"=>colr_temp<="00001000";colg_temp<="00000000";
WHEN
"11111101"=>colr_temp<="00001000";colg_temp<="00000000";
WHEN
"11111110"=>colr_temp<="00001000";colg_temp<="00000000";
WHEN OTHERS=>colr_temp<="00000000";colg_temp<="00000000";
END CASE;--shape 2
ELSIF picture="10" THEN
CASE row_temp IS
WHEN
"01111111"=>colr_temp<="00000001";colg_temp<="10000000";
WHEN
"10111111"=>colr_temp<="00000010";colg_temp<="01000000";
WHEN
"11011111"=>colr_temp<="00000100";colg_temp<="00100000";
WHEN
"11101111"=>colr_temp<="00001000";colg_temp<="00010000";
WHEN
"11110111"=>colr_temp<="00010000";colg_temp<="00001000";
WHEN
"11111011"=>colr_temp<="00100000";colg_temp<="00000100";
WHEN
"11111101"=>colr_temp<="01000000";colg_temp<="00000010";
WHEN
"11111110"=>colr_temp<="10000000";colg_temp<="00000001";
WHEN OTHERS=>colr_temp<="00000000";colg_temp<="00000000";
END CASE;--shape 3
ELSIF picture="11" THEN
CASE row_temp IS
WHEN
"01111111"=>colr_temp<="00000000";colg_temp<="00010000";
WHEN
"10111111"=>colr_temp<="00000000";colg_temp<="00010000";
WHEN
"11011111"=>colr_temp<="00000000";colg_temp<="00010000";
WHEN
"11101111"=>colr_temp<="00001111";colg_temp<="00010000";
WHEN
"11110111"=>colr_temp<="11110000";colg_temp<="00001000";
WHEN
"11111011"=>colr_temp<="00000000";colg_temp<="00001000";
WHEN
"11111101"=>colr_temp<="00000000";colg_temp<="00001000";
WHEN
"11111110"=>colr_temp<="00000000";colg_temp<="00001000";
WHEN OTHERS=>colr_temp<="00000000";colg_temp<="00000000";
END CASE;--shape 4
END IF;
END IF;
row<=row_temp;
colr<=colr_temp;
colg<=colg_temp;
END PROCESS p11;
---------------------------------------------------------------------------节拍分频
p12:PROCESS(clk)
V ARIABLE CLKCnt:INTEGER RANGE 0 TO 1041666;
BEGIN
IF(clk' EVENT AND clk = '1') THEN
IF(CLKCnt < 1041666) THEN
CLKCnt := CLKCnt + 1;
ELSE CLKCnt := 0;tape_clk <= NOT tape_clk;
END IF;
END IF;
END PROCESS p12;
----------------------------------------------------------------------------音调分频
p13:PROCESS(clk,tone_tmp)
V ARIABLE CLKCnt:INTEGER RANGE 0 TO 64000;
BEGIN
IF(clk' EVENT AND clk = '1') THEN
IF tone_tmp=0 THEN tone_clk<='0';
ELSE
IF(CLKCnt < tone_tmp) THEN CLKCnt := CLKCnt + 1;
ELSE CLKCnt := 0;tone_clk <= NOT tone_clk;
END IF;
END IF;
END IF;
END PROCESS p13;
----------------------------------------------------------------------------分频系数输出p14:PROCESS(tape_clk,clr)
V ARIABLE tape_tmp:INTEGER RANGE 0 TO 192:=0;
BEGIN
IF clr='0' THEN tape_tmp:=0;tone_tmp<=0;
ELSIF(tape_clk'EVENT AND tape_clk = '1') THEN
IF(tape_tmp < 192) THEN tape_tmp := tape_tmp + 1;
END IF;
CASE(tape_tmp) IS
WHEN 0=>tone_tmp<=47774;--1
WHEN 11=>tone_tmp<=0;
WHEN 12=>tone_tmp<=47774;--1
WHEN 17=>tone_tmp<=0;
WHEN 18=>tone_tmp<=47774;--1
WHEN 23=>tone_tmp<=0;
WHEN 24=>tone_tmp<=47774;--1
WHEN 35=>tone_tmp<=0;
WHEN 36=>tone_tmp<=47774;--1
WHEN 41=>tone_tmp<=0;
WHEN 42=>tone_tmp<=47774;--1
WHEN 47=>tone_tmp<=0;
WHEN 48=>tone_tmp<=37919;--3
WHEN 59=>tone_tmp<=0;
WHEN 60=>tone_tmp<=31888;--5
WHEN 65=>tone_tmp<=0;
WHEN 66=>tone_tmp<=31888;--5
WHEN 71=>tone_tmp<=0;
WHEN 72=>tone_tmp<=37919;--3
WHEN 77=>tone_tmp<=0;
WHEN 78=>tone_tmp<=37919;--3
WHEN 83=>tone_tmp<=0;
WHEN 84=>tone_tmp<=47774;--1
WHEN 95=>tone_tmp<=0;
WHEN 96=>tone_tmp<=42568;--2
WHEN 107=>tone_tmp<=0;
WHEN 108=>tone_tmp<=42568;--2
WHEN 113=>tone_tmp<=0;
WHEN 114=>tone_tmp<=42568;--2
WHEN 119=>tone_tmp<=0;
WHEN 120=>tone_tmp<=42568;--2
WHEN 131=>tone_tmp<=0;
WHEN 132=>tone_tmp<=42568;--2
WHEN 137=>tone_tmp<=0;
WHEN 138=>tone_tmp<=42568;--2
WHEN 143=>tone_tmp<=0;
WHEN 144=>tone_tmp<=50617;---7
WHEN 155=>tone_tmp<=0;
WHEN 156=>tone_tmp<=42568;--2
WHEN 161=>tone_tmp<=0;
WHEN 162=>tone_tmp<=42568;--2
WHEN 167=>tone_tmp<=0;
WHEN 168=>tone_tmp<=50617;---7
WHEN 173=>tone_tmp<=0;
WHEN 174=>tone_tmp<=50617;---7
WHEN 179=>tone_tmp<=0;
WHEN 180=>tone_tmp<=63775;---5
WHEN 191=>tone_tmp<=0;
WHEN OTHERS=>NULL;
END CASE;
END IF;
END PROCESS p14;
----------------------------------------------------------------------------蜂鸣器输出
p15:PROCESS(clr,tone_clk)
BEGIN
IF(clr = '1') THEN beep <= tone_clk;
ELSE beep <= '0';
END IF;
END PROCESS p15;
END display;
五、功能说明及资源利用情况
1.功能说明
本次数电实验除倒计时部分外,基本实现了题目要求功能。
将程序下载到实验板上,开始的状态即为关机状态,拨动拨码开关SW0即开机,档位显示为1,温度显示为20℃,无时间显示,风扇点阵转动频率为0.5Hz。
温度调节模块:使用BTN1和BTN0键即可实现温度的增加或减少,温度可在10~40℃内反复调节,一直按BTN键可实现温度的持续变化。
档位和点阵风扇的
转动频率也会随着温度及时正确地变化。
倒计时模块:由于看题时误以为时间是内置的,故仅设定了30作为倒计时的时间。
拨动开关SW7,即开始倒计时从30秒开始递减,一直减到时间为00时,倒计时停止,风扇静止不动,档位显示变为4档。
倒计时过程中也可以随时调节温度来实现对风扇转动速率的控制。
再次拨动拨码开关,档位恢复原状,风扇再次开始转动,倒计时时间显示消失。
音乐模块:由拨码开关SW0判断音乐是否响起,音乐的每小节为2s,总共四个小节,共播放音乐8秒,音乐代码是根据钢琴曲《十个小印第安人》改编。
点阵模块:点阵由1kHz时钟和另一个低频时钟共同组成,高频扫描行,低频实现画面切换,点阵模块实现了图案的正确显示与切换。
2.资源利用情况
(1)EDA开发板上应用的电路
按键(BTN1、BTN0)、数码管DISP0-DISP5、8*8双色点阵、蜂鸣器、拨码开关
(SW7、SW0)。
(2)管脚分配
图9
图10
图11
六、故障及问题分析
故障1:数码管显示扫描频率不合适,不能显示清晰的数字。
问题分析:出现数字的闪烁,由于数码管显示是利用扫描的方式,数字闪烁不清,是扫描频率的问题。
解决办法:反复调节扫描频率,直到数字稳定显示,最终将扫描频率定在了1kHz。
故障2:编程的时候结构设计不佳,总是出现两个进程需要同时修改一个变量的问题,编译器报错(报错内容是不能正确分配存储器)。
问题分析:对上学期实验内容的遗忘,导致出现了这个毫无技术含量的问题,在开始设计整个系统之前复习了VHDL的基本语句,对这种语言规则的问题存在着一
定的忽视,也提醒了我以后在利用某种语言设计系统前,一定要明确语法规则,否则不但可能发生编译不通过的问题,还有可能需要推翻整个设计结构。
解决办法:添加控制信号,修改结构,避免两个进程同时修改一个变量。
故障3:在温度调节部分要同时调节BTN1和BTN0,需要同时检测两个电平变化。
问题分析:在VHDL的PROCESS中不可以对同一时钟的上升沿和下降沿同时操作有如下限制:1、禁止一个进程存在两个寄存器。
如同时存在CLK1和CLK2;2、禁止使用IF语句的ELSE;3、寄存器描述中必须带入信号值,如Y<=TMP)。
解决办法:同时在CLK的上升沿和下降沿对数据进行采集。
故障4:出现锁定管脚时输入管脚正常,而输出管脚缺少了一部分。
问题分析:以前从未发生过这种问题,于是就去向老师寻求帮助,首先进行了再次编译,然后进行了再次的仿真,发现仿真时的管脚设置部分同样缺少输出管脚这一问题,老师给出的建议是代码本身存在问题。
解决办法:针对代码部分进行仔细检查,发现是变量声明的地方出现了问题,定义了一个向量row(0 DOWNTO 7),应该改为row(7 DOWNTO 0),由于编译通过了,开始就没有发现这一问题。
故障5:蜂鸣器多次修改代码,下载仍然不能发声。
问题分析:软件如果确定没有问题,就应该是硬件出错了。
解决办法:我换用了旁边同学的电路板,成功发声,后来知道是板子的蜂鸣器位置需要把外露的两个引脚连接起来。
故障6:实验室的下载板电脑不能识别。
问题分析:这个问题也经常出现在身边的同学身上,解决方法往往是板子本身出现了一些问题,我刚开始也换了身边同学已经能够成功下载的板子,依旧不能识别,应该不是板子的问题。
解决办法:我猜测问题应该出现在连接线或者接口上,换用了身边同学的usb 连接线,依旧是不能识别。
在换用不同的usb接口,终于在5个usb接口中找到了一个可用的接口。
故障7:点阵显示列方向呈轴对称。
问题分析:管脚设置问题。
解决办法:将列方向的管脚重新按列方向轴对称翻转。
七、总结和结论
1.总结
本次实验室对上学期所学的VHDL和QUARTUSII的知识的进一步巩固和应用。
VHDL是超高速集成电路硬件描述语言,用于PGA/CPLD/EPLD的设计中。
本次实验室软件和硬件的结合,让我更加深刻的理解了数字电路的相关知识,加强了对时序电路、译码器等概念的理解。
从上学期简单的模块化程序到现在的设计数字系统,提高了编程能力和逻辑分析能力。
本次实验我充分体验了编写程序的关键不在于写程序而在于调试程序,不仅在C++中,在硬件设计语言VHDL中也是,本实验在搭建了温度调节、倒计时的基本功能后,调试到波形完全正确并没有花费很多时间,大部分的时间都用在了最后将各部分代码合用的地方,还有修改一些小功能上。
通过仿真波形判断程序是否正确提高了对数字电路的认识和抽象思维的能力,对日后的编程学习帮助很大。
2.结论
通过这次实验,我对VHDL语言自顶向下的编程逻辑有了更加深刻的理解,对硬件描述语言的使用也更加熟悉。
从大学一年级的C++到现在的硬件描述语言,再到正在学习的汇编语言,自顶向下这一设计思想贯穿始终,是编程的重要思想之一。
本次实验,我成功的完成了实验任务,提升了实验能力和自信心,感谢老师的悉心指导和身边同学们的帮助。