基于VHDL的空调控制器设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字系统设计与硬件描述语言
期末考试作业
题目:空调控制器的设计学院:电子信息工程学院专业:物联网工程
学号:3014204328
姓名:刘涵凯
2016-12-14
一、选题设计描述
1.功能介绍
设计内容为空调控制器,可实现空调的开关、模式切换、温度控制、风速控制、定时设置。
模式默认为制冷,可切换为制热、除湿。
温度默认为26度,可按“温度+”、“温度-”调节,每次调节1度,最高30度,最低16度。
风速默认为中挡,可按“风速+”、“风速-”切换为低挡、高挡、睡眠模式。
睡眠模式中,在低挡与停止间循环。
定时设置默认关闭,开启时默认30分钟,可按“定时+”、“定时-”调节,每次调节30分钟,最高24小时,最低30分钟。
定时倒计时结束时,关闭空调。
定时开启时,可按“取消定时”关闭定时。
空调控制器模拟界面如下:
2.算法简介
1)空调控制器
其输入与输出在主程序kt中已标明,在此不做介绍。
2)单脉冲模块
这是非常重要以和核心的模块。
当a产生一个上升沿时,输出一个单脉冲,脉冲将持续到经过一个clk上升沿后的clk下降沿。
3)开关模块
a连接空调的开关,b连接开关控制模块的输出,c为空调各工作模块的开关信号,d连接数码管显示开关状况。
当定时时间结束,b输入一个单脉冲,空调关闭。
4)开关控制模块
此模块的作用是保证开关模块能够正常工作。
开关打开时,a输入一个单脉冲,重置c。
b连接定时模块,当定时结束,b输入一个单脉冲,使c输出1,使开关模块输出0
5)温度模块
a连接开关模块,b为温度+1,c为温度-1,输出为温度的十位和个位。
6)风速模块
a连接开关模块,b为风速+1,c为风速-1。
di,zhong,gao为抵挡、中挡、高挡的状态(无睡眠模式,因为睡眠模式是抵挡-停止模式)。
其他连接数码管,显示睡眠模式、抵挡、中挡、高挡的状态。
7)模式模块
b连接开关模块,c为切换模式,输出类似于模式模块。
8)定时模块
a连接开关模块,b为定时模块开启,c为取消定时,up、down为定时时间+、-。
clk1为空调时钟,clk2为模拟的倒计时时钟(周期1分钟)。
clk2周期远大于clk1。
当时间倒计时结束时,sw1输出1,使开关控制模块控制开关关闭。
其他输出连接倒计时模块。
9)倒计时模块
a连接开关模块,clk连接定时模块的clk2,输入时间发生变化时,重新倒计时。
倒计时结束时,finish输出1,使定时模块的sw1输出1。
10)数码管模块
a连接开关模块,此为7段译码器。
11)计数器模块
此为六位计数器。
a连接睡眠模式开关,rst为睡眠模式打开时的重置信号,每6次输出一次1。
二、程序源代码和说明
1)空调控制器
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
ENTITY kt IS
PORT(switchin,modeset,fanup,fandown,tempup,tempdown,timerop,timercancel,timerup,t imerdown,clk1,clk2: IN STD_LOGIC;
--电源开关、模式切换、风速+、风速-、温度+、温度-、定时、取消定时、定时+、定时-、时钟信号、倒计时时钟信号
cools,heats,drys,dis,zhongs,gaos: OUT STD_LOGIC; --通向空调内部的制冷、制热、除湿、抵挡、中挡、高挡状态输出
switchstate,tempd,temps,coolstate,heatstate,drystate,distate,zhongstate,gaostate,sleepstate ,hdstate,hsstate,tdstate,tsstate: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
--由数码管显示的开关、温度、制冷、制热、除湿、抵挡、中挡、高挡、睡眠状态和倒计时剩余时间
END ENTITY kt;
ARCHITECTURE behave OF kt IS
COMPONENT switch --开关模块
PORT(a,b,clk: IN STD_LOGIC; --b受定时模块的控制,时间减为0时,关闭开关
c: OUT STD_LOGIC;
d: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --输送给数码管END COMPONENT switch;
COMPONENT control --开关控制模块
PORT(a,b,clk: IN STD_LOGIC;
c: OUT STD_LOGIC);
END COMPONENT control;
COMPONENT fan --风速模块
PORT(a,b,c,clk: IN STD_LOGIC;
di,zhong,gao: OUT STD_LOGIC; --由于high和low是敏感词汇,所以此处用拼音,可以看到此处没有睡眠模式,是因为睡眠模式其实是抵挡-停止模式ssleep,sdi,szhong,sgao: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --不同于发给空调内部的信号,睡眠模式的状态应显示在外
END COMPONENT fan;
COMPONENT BCD7 --数码管模块
PORT(a: IN STD_LOGIC;
b: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
q : OUT STD_LOGIC_VECTOR(0 TO 6) );
END COMPONENT BCD7;
COMPONENT pulse --单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT pulse;
COMPONENT temp --温度模块
PORT(a,b,c,clk: IN STD_LOGIC; --a控制开关,b提高1度,c降低1度
temp1,temp2: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT temp;
COMPONENT timer --定时模块
PORT(a,b,c,up,down,clk1,clk2: IN STD_LOGIC;
sw1: OUT STD_LOGIC; --总开关关闭信号
oh1,oh2,ot1,ot2: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --输送给数码管显示剩余时间
END COMPONENT timer;
COMPONENT mode
PORT(b,c,clk: IN STD_LOGIC;
cool,heat,dry: OUT STD_LOGIC;
cool1,heat1,dry1: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT mode;
SIGNAL swa,swb,swc:STD_LOGIC;
SIGNAL sigBCD7_1,sigBCD7_2,sigBCD7_3,sigBCD7_4,sigBCD7_5,
sigBCD7_6,sigBCD7_7,sigBCD7_8,sigBCD7_9,sigBCD7_10,
sigBCD7_11,sigBCD7_12,sigBCD7_13,sigBCD7_14:STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
U1: switch PORT MAP(a=>switchin,b=>swb,c=>swa,clk=>clk1,d=>sigBCD7_1);
U2: control PORT MAP(a=>switchin,b=>swc,clk=>clk1,c=>swb);
U3: fan PORT MAP(a=>swa,b=>fanup,c=>fandown,clk=>clk1,di=>dis,zhong=>zhongs,gao=>gaos,ssle ep=>sigBCD7_2,sdi=>sigBCD7_3,szhong=>sigBCD7_4,sgao=>sigBCD7_5);
U4: temp PORT MAP(a=>swa,b=>tempup,c=>tempdown,clk=>clk1,temp1=>sigBCD7_6,temp2=>sigBC D7_7);
U5: timer PORT MAP(a=>swa,clk1=>clk1,clk2=>clk2,b=>timerop,c=>timercancel,up=>timerup,down=> timerdown,sw1=>swc,oh1=>sigBCD7_8,oh2=>sigBCD7_9,ot1=>sigBCD7_10,ot2=>sig BCD7_11);
U6: mode PORT MAP(b=>swa,c=>modeset,clk=>clk1,cool=>cools,heat=>heats,dry=>drys,cool1=>sigBC D7_12,heat1=>sigBCD7_13,dry1=>sigBCD7_14);
U7: BCD7 PORT MAP(a=>swa,b=>sigBCD7_1,q=>switchstate);
U8: BCD7 PORT MAP(a=>swa,b=>sigBCD7_2,q=>sleepstate);
U9: BCD7 PORT MAP(a=>swa,b=>sigBCD7_3,q=>distate);
U10: BCD7 PORT MAP(a=>swa,b=>sigBCD7_4,q=>zhongstate);
U11: BCD7 PORT MAP(a=>swa,b=>sigBCD7_5,q=>gaostate);
U12: BCD7 PORT MAP(a=>swa,b=>sigBCD7_6,q=>tempd);
U13: BCD7 PORT MAP(a=>swa,b=>sigBCD7_7,q=>temps);
U14: BCD7 PORT MAP(a=>swa,b=>sigBCD7_8,q=>hdstate);
U15: BCD7 PORT MAP(a=>swa,b=>sigBCD7_9,q=>hsstate);
U16: BCD7 PORT MAP(a=>swa,b=>sigBCD7_10,q=>tdstate);
U17: BCD7 PORT MAP(a=>swa,b=>sigBCD7_11,q=>tsstate);
U18: BCD7 PORT MAP(a=>swa,b=>sigBCD7_12,q=>coolstate);
U19: BCD7 PORT MAP(a=>swa,b=>sigBCD7_13,q=>heatstate);
U20: BCD7 PORT MAP(a=>swa,b=>sigBCD7_14,q=>drystate);
PROCESS(clk1)
BEGIN
END PROCESS;
END ARCHITECTURE behave;
2)单脉冲模块
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
ENTITY pulse IS --单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END ENTITY pulse;
ARCHITECTURE behave OF pulse IS
SIGNAL d:STD_LOGIC:='0';
SIGNAL f:STD_LOGIC:='0';
SIGNAL g:STD_LOGIC:='0'; --确保经过第一个clk上升沿时输出1 SIGNAL h:STD_LOGIC:='0'; --同上
BEGIN
PROCESS(a,clk)
BEGIN
IF(clk'EVENT AND clk='1')THEN
IF(f='1')THEN
g<='1';
ELSE g<='0';
END IF;
END IF;
END PROCESS;
PROCESS(a,clk)
BEGIN
IF(clk'EVENT AND clk='0')THEN
IF(a='1')THEN
IF(f='1')THEN
IF(g='1')THEN
d<='1';
ELSE d<='0';
END IF;
ELSE d<='1';
END IF;
ELSE d<='0'; --a为0时,重置此单脉冲发生器
END IF;
END IF;
END PROCESS;
PROCESS(d)
BEGIN
IF(a='1')THEN
IF(d='1')THEN
f<='0';
ELSE f<='1';
END IF;
ELSE f<='0';
END IF;
b<=f;
END PROCESS;
END ARCHITECTURE behave;
3)开关模块
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY switch IS --开关模块
PORT(a,b,clk: IN STD_LOGIC; --b受定时模块的控制,时间减为0时,关闭开关
c: OUT STD_LOGIC;
d: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --输送给数码管END ENTITY switch;
ARCHITECTURE behave OF switch IS
COMPONENT pulse --调用单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT pulse;
SIGNAL p1 : STD_LOGIC:='0';
SIGNAL p2 : STD_LOGIC:='0';
BEGIN
U1: pulse PORT MAP(a=>a,b=>p1,clk=>clk);
U2: pulse PORT MAP(a=>b,b=>p2,clk=>clk);
PROCESS(a,b,clk)
BEGIN
IF(clk'EVENT AND clk='1')THEN
IF(p1='1')THEN --空调开关打开
c<='1';d<="0001";
END IF;
IF(p2='1')THEN --时间减为0时,定时模块返回1,关闭开关
c<='0';d<="0000";
END IF;
END IF;
END PROCESS;
END ARCHITECTURE behave;
4)开关控制模块
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY control IS --开关控制模块
PORT(a,b,clk: IN STD_LOGIC;
c: OUT STD_LOGIC);
END ENTITY control;
ARCHITECTURE behave OF control IS
COMPONENT pulse --调用单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT pulse;
SIGNAL p1 : STD_LOGIC:='0';
SIGNAL p2 : STD_LOGIC:='0';
BEGIN
U1: pulse PORT MAP(a=>a,b=>p1,clk=>clk);
U2: pulse PORT MAP(a=>b,b=>p2,clk=>clk);
PROCESS(a,b,clk)
BEGIN
IF(clk'EVENT AND clk='1')THEN
IF(p1='1')THEN --空调开关打开
c<='0';
END IF;
IF(p2='1')THEN --时间减为0时,定时模块返回1,关闭开关
c<='1';
END IF;
END IF;
END PROCESS;
END ARCHITECTURE behave;
5)温度模块
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
ENTITY temp IS --温度模块,最高30度,最低16度,默认26度PORT(a,b,c,clk: IN STD_LOGIC; --a控制开关,b提高1度,c降低1度temp1,temp2: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END ENTITY temp;
ARCHITECTURE behave OF temp IS
COMPONENT pulse --调用单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT pulse;
SIGNAL t1 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL t2 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL p1 : STD_LOGIC:='0';
SIGNAL p2 : STD_LOGIC:='0';
SIGNAL p3 : STD_LOGIC:='0';
BEGIN
U1: pulse PORT MAP(a=>b,b=>p1,clk=>clk);
U2: pulse PORT MAP(a=>c,b=>p2,clk=>clk);
U3: pulse PORT MAP(a=>a,b=>p3,clk=>clk);
PROCESS(a,clk)
BEGIN
IF(clk'EVENT AND clk='1')THEN
IF(p3='1')THEN --开关打开时,默认26度t1<="0010";t2<="0110";
ELSIF(a='0')THEN
t1<="0000";t2<="0000";
END IF;
IF(a='1')THEN
IF(p1='1')THEN --判断"温度+"按键按下
IF(t1="0011")THEN
t1<="0011";t2<="0000";
ELSIF(t2="1001")THEN
t1<=t1+'1';
t2<="0000";
ELSE t2<=t2+'1';
END IF;
END IF;
IF(p2='1')THEN --判断"温度-"按键按下
IF(t1="0001")THEN
IF(t2="0110")THEN
t1<="0001";t2<="0110";
ELSE t2<=t2-'1';
END IF;
ELSIF(t2="0000")THEN
t1<=t1-'1';
t2<="1001";
ELSE t2<=t2-'1';
END IF;
END IF;
ELSE t1<="0000";t2<="0000";
END IF;
END IF;
temp1<=t1;temp2<=t2;
END PROCESS;
END ARCHITECTURE behave;
6)风速模块
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
ENTITY fan IS --风速模块:睡眠、低、中、高;默认中挡;睡眠模式在低挡和停止之间循环
PORT(a,b,c,clk: IN STD_LOGIC;
di,zhong,gao: OUT STD_LOGIC; --由于high和low是敏感词汇,所以此处用拼音,可以看到此处没有睡眠模式,是因为睡眠模式其实是抵挡-停止模式ssleep,sdi,szhong,sgao: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --不同于发给空调内部的信号,睡眠模式的状态应显示在外
END ENTITY fan;
ARCHITECTURE behave OF fan IS
COMPONENT pulse --调用单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT pulse;
COMPONENT count6 --调用计数器
PORT ( a,clk,rst : IN STD_LOGIC;
o: OUT STD_LOGIC);
END COMPONENT count6;
SIGNAL e : STD_LOGIC_VECTOR(2 DOWNTO 0):="000"; --停止000、睡眠001、抵挡010、中挡011、高挡100
SIGNAL p1 : STD_LOGIC:='0';
SIGNAL p2 : STD_LOGIC:='0';
SIGNAL p3 : STD_LOGIC:='0';
SIGNAL op : STD_LOGIC:='0';
SIGNAL op1 : STD_LOGIC:='0'; --其上升沿用于开启睡眠模式
SIGNAL op2 : STD_LOGIC:='0';
SIGNAL rst1 : STD_LOGIC:='0';
SIGNAL rst2 : STD_LOGIC:='0';
SIGNAL change : STD_LOGIC:='0';
SIGNAL m : STD_LOGIC:='0'; --睡眠模式中使用,由于睡眠模式是循环模式,所以不设置置0
BEGIN --模式在按键操作下可循环滚动
U1: pulse PORT MAP(a=>b,b=>p1,clk=>clk);
U2: pulse PORT MAP(a=>c,b=>p2,clk=>clk);
U3: pulse PORT MAP(a=>a,b=>p3,clk=>clk);
U4: pulse PORT MAP(a=>rst1,b=>rst2,clk=>clk);
U5: count6 PORT MAP(a=>op,rst=>rst2,clk=>clk,o=>change);
PROCESS(a,clk)
BEGIN
IF(clk'EVENT AND clk='1')THEN
op1<=op2;
IF(p3='1')THEN --开关打开时,默认中挡
e<="011";
ELSIF(a='0')THEN
e<="000";
END IF;
IF(a='1')THEN
IF(p1='1')THEN --判断"风速+"按键按下
IF(e="100")THEN --高挡时按下,则切换为睡眠
e<="001";op1<='1';
ELSE e<=e+'1';op1<='0';
END IF;
END IF;
IF(p2='1')THEN --判断"风速"-"按键按下
IF(e="001")THEN --睡眠时按下,则切换为高挡
e<="100";op1<='0';
ELSIF(e="010")THEN
e<=e-'1';op1<='1';
ELSE e<=e-'1';op1<='0';
END IF;
END IF;
ELSE e<="000";
END IF;
END IF;
END PROCESS;
PROCESS(change)
BEGIN
IF(change'EVENT AND change='1')THEN
IF(m='1')THEN
m<='0';
ELSE m<='1';
END IF;
END IF;
END PROCESS;
PROCESS(e)
BEGIN
op2<=op1;
IF(e="001")THEN --睡眠时的低挡-停止循环
IF(op2'EVENT AND op2='1')THEN
op<='1';rst1<='1';
END IF;
op<='1';
CASE m IS
WHEN '1' => di<='1';zhong<='0';gao<='0';ssleep<="0001";sdi<="0000";szhong<="0000";sgao<="0000";
WHEN '0' => di<='0';zhong<='0';gao<='0';ssleep<="0001";sdi<="0000";szhong<="0000";sgao<="0000";
END CASE;
ELSE
op<='0';--关闭睡眠模式
IF(e="010")THEN
di<='1';zhong<='0';gao<='0';ssleep<="0000";sdi<="0001";szhong<="0000";sgao<="0000";
ELSIF(e="011")THEN
di<='0';zhong<='1';gao<='0';ssleep<="0000";sdi<="0000";szhong<="0001";sgao<="0000";
ELSIF(e="100")THEN
di<='0';zhong<='0';gao<='1';ssleep<="0000";sdi<="0000";szhong<="0000";sgao<="0001";
ELSIF(e="000")THEN
di<='0';zhong<='0';gao<='0';ssleep<="0000";sdi<="0000";szhong<="0000";sgao<="0000";
END IF;
END IF;
END PROCESS;
END ARCHITECTURE behave;
7)模式模块
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
ENTITY mode IS --模式模块:制冷、制热、除湿
PORT(b,c,clk: IN STD_LOGIC;
cool,heat,dry: OUT STD_LOGIC;
cool1,heat1,dry1: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END ENTITY mode;
ARCHITECTURE behave OF mode IS
COMPONENT pulse --单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT pulse;
SIGNAL e : STD_LOGIC_VECTOR(1 DOWNTO 0):="00";
SIGNAL p1 : STD_LOGIC:='0';
SIGNAL p2 : STD_LOGIC:='0';
BEGIN
U1: pulse PORT MAP(a=>b,b=>p1,clk=>clk);
U2: pulse PORT MAP(a=>c,b=>p2,clk=>clk);
PROCESS(b,c,p1,p2,clk) --按键选择模式
BEGIN
IF(clk'EVENT AND clk='1')THEN
IF(b='1')THEN
IF(p1='1')THEN --默认制冷模式
e<="01";
END IF;
IF(p2='1')THEN
IF(e="11")THEN
e<="01";
ELSE e<=e+'1';
END IF;
END IF;
ELSE e<="00";
END IF;
END IF;
END PROCESS;
PROCESS(e)
BEGIN --由于第一个PROCESS中,a为0时e为"00",所以此处不再考虑a CASE e IS
WHEN "01" => cool<='1';heat<='0';dry<='0';cool1<="0001";heat1<="0000";dry1<="0000";
WHEN "10" => cool<='0';heat<='1';dry<='0';cool1<="0000";heat1<="0001";dry1<="0000";
WHEN "11" => cool<='0';heat<='0';dry<='1';cool1<="0000";heat1<="0000";dry1<="0001";
WHEN OTHERS => cool<='0';heat<='0';dry<='0';cool1<="0000";heat1<="0000";dry1<="0000";
END CASE;
END PROCESS;
END ARCHITECTURE behave;
8)定时模块
ENTITY timer IS --定时模块:最低30分钟,最高24小时,每次按键调整30分钟,可取消定时
PORT(a,b,c,up,down,clk1,clk2: IN STD_LOGIC;
sw1: OUT STD_LOGIC; --总开关关闭信号
oh1,oh2,ot1,ot2: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); --输送给数码管显示剩余时间
END ENTITY timer;
ARCHITECTURE behave OF timer IS
COMPONENT pulse --调用单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT pulse;
COMPONENT cd --调用倒计时模块
PORT(a,clk: IN STD_LOGIC;
time1,time2,time3,time4: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
finish: OUT STD_LOGIC;
outtime1,outtime2,outtime3,outtime4: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT cd;
SIGNAL cl : STD_LOGIC:='0';
SIGNAL op : STD_LOGIC:='0';
SIGNAL p1 : STD_LOGIC:='0';
SIGNAL p2 : STD_LOGIC:='0';
SIGNAL p3 : STD_LOGIC:='0';
SIGNAL sw : STD_LOGIC:='0';--倒计时模块开关信号
SIGNAL h11 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL h22 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL t11 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0011";
SIGNAL t22 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL h1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL h2 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL t1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL t2 : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
U1: pulse PORT MAP(a=>b,b=>op,clk=>clk1);
U2: pulse PORT MAP(a=>c,b=>cl,clk=>clk1);
U3: pulse PORT MAP(a=>up,b=>p1,clk=>clk1);
U4: pulse PORT MAP(a=>down,b=>p2,clk=>clk1);
U5: pulse PORT MAP(a=>sw,b=>p3,clk=>clk1);
U6: cd PORT MAP(a=>sw,clk=>clk2,time1=>h1,time2=>h2,time3=>t1,time4=>t2,finish=>sw1,outtime1= >oh1,outtime2=>oh2,outtime3=>ot1,outtime4=>ot2);
PROCESS(a,op,cl)
BEGIN
IF(a='1')THEN
IF(op='1')THEN
sw<='1';
END IF;
IF(cl='1')THEN
sw<='0';
END IF;
ELSE sw<='0';
END IF;
END PROCESS;
PROCESS(sw,clk1)
BEGIN
IF(clk1'EVENT AND clk1='1')THEN
IF(p3='1')THEN --定时开启时,默认30分钟h11<="0000";h22<="0000";t11<="0011";t22<="0000"; ELSIF(sw='0')THEN
h11<="0000";h22<="0000";t11<="0000";t22<="0000"; END IF;
IF(sw='1')THEN
IF(p1='1')THEN --判断"时间+"按键按下
IF(h11="0010")THEN
IF(h22="0100")THEN
h11<="0010";h22<="0100";t11<="0000";t22<="0000";
ELSIF(t11="0000")THEN
t11<="0011";
ELSE h22<=h22+'1';t11<="0000";
END IF;
ELSIF(h22="1001")THEN
IF(t11="0000")THEN
t11<="0011";
ELSE h11<=h11+'1';h22<="0000";t11<="0000";
END IF;
ELSIF (t11="0011")THEN
h22<=h22+'1';t11<="0000";
ELSE t11<="0011";
END IF;
END IF;
IF(p2='1')THEN --判断"时间-"按键按下
IF(h11="0000")THEN
IF(h22="0000")THEN
h11<="0000";h22<="0000";t11<="0011";t22<="0000";
ELSIF(t11="0011")THEN
t11<="0000";
ELSE h22<=h22-'1';t11<="0011";
END IF;
ELSIF(h22="0000")THEN
IF(t11="0011")THEN
t11<="0000";
ELSE h11<=h11-'1';h22<="1001";t11<="0011";
END IF;
ELSIF (t11="0011")THEN
t11<="0000";
ELSE h22<=h22-'1';t11<="0011";
END IF;
END IF;
END IF;
END IF;
h1<=h11;h2<=h22;t1<=t11;t2<=t22;
END PROCESS;
END ARCHITECTURE behave;
9)倒计时模块
LIBRARY IEEE ;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
ENTITY cd IS --倒计时模块,仅在定时开启时有效
PORT(a,clk: IN STD_LOGIC;
time1,time2,time3,time4: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
finish: OUT STD_LOGIC;
outtime1,outtime2,outtime3,outtime4: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END ENTITY cd;
ARCHITECTURE behave OF cd IS
COMPONENT pulse --调用单脉冲模块
PORT(a,clk: IN STD_LOGIC;
b: OUT STD_LOGIC);
END COMPONENT pulse;
SIGNAL s : STD_LOGIC:='0';
SIGNAL intime11 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL intime22 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL intime33 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL intime44 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL stime1 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL stime2 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL stime3 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL stime4 : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";
SIGNAL intime5 : STD_LOGIC_VECTOR (1 DOWNTO 0):="00";
SIGNAL intime6 : STD_LOGIC_VECTOR(1 DOWNTO 0):="01";
SIGNAL intime7 : STD_LOGIC_VECTOR(1 DOWNTO 0):="01";
BEGIN
U1: pulse PORT MAP(a=>a,b=>s,clk=>clk);
PROCESS(time1,time2,time3,time4,clk) --为当定时时间更改时,令变量重新赋值BEGIN
IF(clk'EVENT AND clk='1')THEN
IF(s='1')THEN
intime5<="11";
ELSIF(a='1')THEN
IF(stime1/=time1 OR stime2/=time2 OR stime3/=time3 OR stime4/=time4)THEN stime1<=time1;
stime2<=time2;
stime3<=time3;
stime4<=time4;
IF(intime5="01")THEN
intime5<="10";
ELSE intime5<="01";
END IF;
END IF;
ELSE intime5<="00";
END IF;
END IF;
intime11<=time1;
intime22<=time2;
intime33<=time3;
intime44<=time4;
END PROCESS;
PROCESS(clk,intime5,intime6)
V ARIABLE intime1,intime2,intime3,intime4 : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
IF(clk'EVENT AND clk='1')THEN
IF(a='1')THEN
IF(intime5/=intime6)THEN --第一个PROCESS运行时,变量被重新赋值
intime6<=intime5;
intime1:=intime11;
intime2:=intime22;
intime3:=intime33;
intime4:=intime44;
END IF;
IF(intime4/="0000")THEN
intime4:=intime4-'1';
finish<='0';
ELSIF(intime3/="0000")THEN
intime4:="1001";
intime3:=intime3-'1';
finish<='0';
ELSIF(intime2/="0000")THEN
intime3:="0101";
intime4:="1001";
intime2:=intime2-'1';
finish<='0';
ELSIF(intime1/="0000")THEN
intime2:="1001";
intime3:="0101";
intime4:="1001";
intime1:=intime1-'1';
finish<='0';
ELSE
intime2:="0000";
intime3:="0000";
intime4:="0000";
intime1:="0000";
finish<='1';
END IF;
ELSE
intime2:="0000";
intime3:="0000";
intime4:="0000";
intime1:="0000";
finish<='0';
END IF;
outtime1<=intime1;
outtime2<=intime2;
outtime3<=intime3;
outtime4<=intime4;
END IF;
END PROCESS;
END ARCHITECTURE behave;
10)数码管模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY BCD7 IS --数码管模块
PORT(a: IN STD_LOGIC;
b: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --数据输入
q : OUT STD_LOGIC_VECTOR(0 TO 6) ); --7段输出END BCD7;
ARCHITECTURE behav OF BCD7 IS
BEGIN
PROCESS (b)
BEGIN
IF(a='1')THEN
CASE b(3 DOWNTO 0) IS -- BCD 7段译码表
WHEN "0000" => q<="1111110"; WHEN "0001" => q<="0110000";
WHEN "0010" => q<="1101101"; WHEN "0011" => q<="1111001";
WHEN "0100" => q<="0110011"; WHEN "0101" => q<="1011011";
WHEN "0110" => q<="1011111"; WHEN "0111" => q<="1110000";
WHEN "1000" => q<="1111111"; WHEN "1001" => q<="1111011";
WHEN OTHERS => q<="0000000";
END CASE;
ELSE q<="1111110";
END IF;
END PROCESS;
END behav;
11)计数器模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY count6 IS --计数器模块
PORT ( a,clk,rst : IN STD_LOGIC;
o: OUT STD_LOGIC);
END;
ARCHITECTURE behav OF count6 IS
SIGNAL q : STD_LOGIC_VECTOR (3 DOWNTO 0);
BEGIN
PROCESS(clk,rst)
BEGIN
IF(rst='1')THEN
q<="0000";
ELSIF rising_edge(clk) THEN
IF(a='1')THEN
q<=q+1;
IF q>= "0101" THEN
q<="0000";
END IF;
ELSE q<="0000";
END IF;
END IF;
END PROCESS;
PROCESS(q)
BEGIN
IF(a='1')THEN
IF (q="0000")THEN
o<='1';
ELSE o<='0';
END IF;
ELSE o<='0';--关闭时输出0
END IF;
END PROCESS;
END;
三、仿真结果和分析
仿真的部分解析与算法描述中相同,故省略。
1)单脉冲模块
2)开关模块
注意:a并非空调的开机状态,而是类似于“按下开机键的时间”。
故a由1变为0时无变化发生。
3)开关控制模块
定时结束时,b接收到一个脉冲c输出1,而当空调重新打开时,c重置为0。
4)温度模块
可能看不清,拆为两部分截图:
默认为26度,最高为30度,最低为16度。
5)风速模块
可能看不清,拆为两部分截图:
b为1的较长一段为睡眠模式。
可以看到,默认为中挡。
睡眠模式时,在低挡和停止间循环。
6)模式模块
7)定时模块
可能看不清,拆为若干部分截图:
由于仿真需要,所以在某些地方调整了时钟频率。
b上升沿触发定时开启,默认30分钟。
最高24小时,之后再按时间+键依然重置为24小时(即仿真图中的23:59)。
倒计时为0时,sw1输出1。
取消定时时(c),关闭定时。
取消定时后再按定时(b),可重新开启定时。
8)倒计时模块
可能看不清,拆为两部分截图:
输入时间改变时,重新计时。
倒计时为0时,finish输出1。
9)数码管模块
10)计数器模块
11)空调控制器
由于仿真图太长太宽,屏幕截图不到clk,所以先截图输入,为配合仿真截图,将主要测试变化集中于左右两部分:
左半部分主要对定时模式的作用、其他模式互不干扰工作、睡眠模式进行测试。
右半部分主要对取消定时模式进行仿真。
最后横向分段截取全图:
受仿真长度限制,总程序的仿真无法在保证结果可读性强的情况下仿真各种状态发生,但分模块的仿真做到了这一点。
对仿真的疑问之处,请参考模块仿真。
四、心得体会
一开始构思的开关的两个输入分别是开关信号和时间信号,其中一个信号为0时,输出为0。
首先我想到用开关模块的输入开启时间模块,但这有一个逻辑问题:时间模块没有收到开始信号,就没法给开关模块传输信息,所以最终我决定让开关输入信号同时给时间模块一个脉冲。
睡眠模式需要调用计数器,为使仿真结果可读性强,使用6位加法计数器。
因为时间模块与睡眠模式都需要用到单脉冲信号,所以我决定编写一个单脉冲发生器,即输入为1时,输出一个脉冲。
这小小的器件编写起来却非常艰难,因为我发现它涉和到很多语法问题和逻辑问题,我尝试了很多种方法,而让我没有想到的是,最终成功的程序是一个简洁明了的小程序。
后来我很惊喜地发现,这个小模块可以灵活应用在很多地方,比如模拟一次按键。
但是有一个问题是,单脉冲持续到下一个clk的上升沿,如何保证其他程序的clk上升沿时,单脉冲输出仍保持1?所以我再次编写了这个程序,更改之后程序逻辑比较复杂,使单脉冲持续到经过一个上升沿后的下降沿,这样也避免了输出紊乱,完美解决了我的问题。
在温度模块,单脉冲发生器发挥了很大作用,它使模块可以在process只能有一个沿判定的情况下,成功进行了对“+”、“-”的判定。
风速模块的编写是一项困难的工作。
有了模式模块的编写经验,使得它的总体架构很容易就编写了出来。
但难点在于睡眠模式,这一模式在低挡和停止间循环,需要调用单脉冲发生器和计数器。
编写时发生了很多语法错误。
最终的一个错误是:计数器的返回信号无法触发睡眠模式中的改变信号(m)。
我尝试了许多方法都没能成功改正,最终编写了一个新的process,使问题得到了解决。
原计划最后一个模块是定时模块。
考虑到这个模块的复杂性,我决定将它拆分为定时模块与倒计时模块。
我首先编写的是倒计时模块。
如果仅仅做一个小时和分钟的倒计
基于VHDL的空调控制器设计
时的话很简单,但如何让倒计时能够在需要的时候重置为需要的数值?我尝试了很多方法。
老实说,我已经不记得当时的编程历程,只是在各种错误中反复尝试,最终取得了理想的结果。
关于定时模块,我先编写的是开启和关闭倒计时模块的信号,我在两个长久以来的问题上反复折腾了几个小时:同一个process不能有多个event;同一个信号不能在多个process中赋值。
最终我决定换一种方法:调用了单脉冲模块,结果出奇的顺利,只用了几行代码就解决了困扰我许久的问题。
定时模块的编写建立在前面模块的经验基础上,所以并不难。
当编写完各个模块后,我在主程序中将它们整合并略加修改了各个模块。
但这时出现了一个问题,这个问题不太好描述,大体上就是说开关无法正常工作。
所以我又编写了一个开关控制模块以保证开关模块的正常运转。
当这一切结束,编译成功,并且多次不同仿真都成功时,我非常激动。
数天来的艰苦奋战没有白费,在这过程中,我对VHDL的诸多基础问题有了一定的认知,同时我的编程思路也逐渐向硬件编程靠近,比如我意识到“signal”其实是导线。
通过这次实践,我掌握了很多看书时忽视的东西。
过程艰辛,而结果让我比较满意。