北邮数电实验洗衣机控制器.docx
《北邮数电实验洗衣机控制器.docx》由会员分享,可在线阅读,更多相关《北邮数电实验洗衣机控制器.docx(31页珍藏版)》请在冰豆网上搜索。
![北邮数电实验洗衣机控制器.docx](https://file1.bdocx.com/fileroot1/2023-2/1/7b9bdfe2-0824-4da6-86a5-9e19e8e2986e/7b9bdfe2-0824-4da6-86a5-9e19e8e2986e1.gif)
北邮数电实验洗衣机控制器
洗衣机控制器
摘要:
本实验在QuartusⅡ软件环境下,利用实验室集成芯片,使用VHDL语言编写程序实现模拟一个洗衣机控制系统的基本功能。
整个系统的设计过程中,采用了up_to_down的设计思想,完成了洗涤、漂洗、脱水、漂洗和脱水、洗涤漂洗和脱水一次完成的模式选择,各项模式下时间的倒计时显示,在各状态中对应的模拟电机指示灯显示,暂停和结束时模拟电机指示灯熄灭洗衣机的开始/暂停,还有预约0至9秒任意时间等功能。
总体来说基本上完成了洗衣机控制器的基本功能。
采用分块设计思想,各主要模块中,分频模块,获得低频时钟供显示模块、防抖模块和报警模块使用,控制模块控制显示模块以及时间倒计时模块,后两个模块进行状态和时间的显示,并通过下载到开发板上验证了程序的正确性,达到了实验的要求。
关键词:
状态VHDL模块控制
一.设计课题实验目的及任务要求:
(1)实验目的:
1.熟练掌握VHDL语言和QuartusII软件的使用;
2.理解状态机的工作原理和设计方法;
3.掌握利用EDA工具进行自顶向下的电子系统设计方法;
(2)基本任务:
1.洗衣机的工作步骤为洗衣、漂洗和脱水三个过程,工作时间分别为:
洗衣20秒,漂洗25秒,脱水15秒;
2.用一个按键实现洗衣程序的手动选择:
A、单洗涤;B、单漂洗;C、单脱水;D、漂洗和脱水;E、洗涤、漂洗和脱水全过程;
3.用显示器件显示洗衣机的工作状态(洗衣、漂洗和脱水),并倒计时显示每个状态的工作时间,全部过程结束后,应提示使用者;
4.用一个按键实现暂停洗衣和继续洗衣的控制,暂停后继续洗衣应回到暂停之前保留的状态;
(3)提高要求:
1.三个过程的时间有多个选项供使用者选择。
2.可以预约洗衣时间。
3.自拟其它功能:
二.系统设计:
(1)设计思路:
根据实验的要求,其中第一项明确要求了预设时间,第二项要求了不同的洗衣组合,第三项是对状态进行显示,而最后一项则是对控制进行了要求,开始和暂停的状态可以看出,这些部分相互作用,共同组成了全自动洗衣的基本功能。
开始、暂停键控制着整个控制部分和显示部分,而控制部分又将洗衣的状态不同以及倒计时时间的不同反映到了状态显示和时间显示部分。
故此可将整个设计过程中,分为按键模块、显示模块、分频模块、报警模块和控制模块组成。
(1)分频模块由100分频模块、1000分频模块、10000分频模块构成的,通过对实验室芯片的系统时钟进行分频为其他模块提供适当的时钟信号。
(2)按键模块由防抖模块和按键信号产生模块构成。
防抖模块用来增加按键的灵活性和有效性;按键控制信号产生模块是通过按键来产生模式选择信号、各模式时间选择信号和开始/暂停信号,形成控制模块需要的各种控制信号。
(3)显示模块由时间显示设置模块、数码管显示模块、选通信号模块、预约时间显示模块以及控制模块的指示灯构成。
其中时间设置模块用来完成时间显示个位和十位信号的设计;数码管显示模块用用来完成模式选择选项的显示数字、倒计时时间的显示数字以及预约时间及预约时间的倒计时的显示数字的信号设计;选通信号用来实现六个七段数码管的同时显示的设计;而指示灯用来完成对各种状态的指示的设计。
(4)报警模块是对于当洗衣机每种模式完成时响起蜂鸣器,达到提示的作用。
(5)控制模块是整个系统的中心部分,是状态机设计部分。
在该模块实现了洗衣机各种状态的运行和转换,还控制着模拟电机的显示模块。
(2)总体框图:
(3)状态转移图:
(4)系统框图:
三.分块设计程序及仿真分析
1.分频模块
分频程序主要由3个程序来实现,利用分频的思想,从50MHz经过分频模块,得到0.5MHz,50000Hz,5000Hz的时钟信号,用于控制模块,防抖模块、显示模块的选通信号模块以及报警模块。
其设计框图如下所示:
以100分频为例,程序和仿真如下:
100分频(fenpin100)
程序:
libraryieee;
useieee.std_logic_1164.all;
entityfenpin100is
port(clk:
instd_logic;--输入时钟信号——50MHz
clkout:
outstd_logic);--分频后的时钟信号——0.5MHz
endfenpin100;
architecturebehaveoffenpin100is
signalclk1:
std_logic;
begin
process(clk)
variablet:
integerrange0to49;
begin
if(clk'eventandclk='1')then
if(t=49)then
t:
=0;
clk1<=notclk1;--时钟信号翻转
elset:
=t+1;
endif;
endif;
clkout<=clk1;--时钟信号不变
endprocess;
end;
仿真:
在仿真图中,clk为输入的时钟信号,clkout为分频后输出的信号,由图可知clkout的频率为clk频率的100分之一。
2.按键模块
采用了每种控制信号采用一个按键通过循环计数的方法来时实现按键的控制。
这一模块由2个程序构成,一个是防抖程序,一个是各种按键信号产生的程序。
后者产生的控制信号将输入控制模块,完成控制输入。
(1)防抖程序(doudong)
本程序是通过计数2个按键时钟信号来确定按键的时间。
按照一般按键时间的长短,将时钟信号设置为100Hz,频率太高或太低都会带来灵敏度的问题。
程序:
libraryieee;
useieee.std_logic_1164.all;
entitydoudongis
port(
clk:
instd_logic;
keyin:
instd_logic;
keyout:
outstd_logic
);
enddoudong;
architecturebehaveofdoudongis
begin
process(clk,keyin)
variablet:
integerrange0to1;--定义变量来计数时钟个数
begin
if(clk'eventandclk='1')then
if(keyin='1')then
if(t=1)then
keyout<='1';
t:
=0;
else
t:
=t+1;
endif;
else
keyout<='0';
endif;--计数两个按键时钟周期来确定按键的时间
endif;
endprocess;
end;
仿真:
仿真图中,clk为用来计数的时钟信号,keyin为按键,clkout为按键后产生的按键信号。
如图在时钟信号有效的情况下,每两个按键时钟产生一个输出的按键信号。
达到了程序设计预期的结果。
(2)按键控制信号产生程序(mykeyboard)
模式选择按键、开始/暂停按键、洗涤时间选择按键、漂洗时间选择按键、脱水时间选择按键均采用一个按键,利用循环计数的方法来产生各种控制信号。
不仅有利于节约按键,而且易于记忆。
由于五种控制信号产生的设计本质相同,形式相似,故采用相似的程序代码,利用多进程在一个程序中实现。
程序:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitymykeyboardis
port
(modekey,startkey,startkey2,keyjs:
instd_logic;
modeout,modeout_mm:
outstd_logic_vector(2downto0);
times,temp,js:
outintegerrange0to60;
light_temp:
outstd_logic_vector(2downto0);--指示灯显示信号
s_p_out,s_p_out2:
outstd_logic
);
endmykeyboard;
architecturebehaveofmykeyboardis
signalmodeout_m:
std_logic_vector(2downto0);
begin
p1:
process(modekey)
variablecout1:
integerrange0to5;
begin
ifrising_edge(modekey)then
ifcout1<=4then
cout1:
=cout1+1;
elsecout1:
=0;
endif;
endif;
CASEcout1IS
WHEN1=>modeout<="001";modeout_m<="001";
light_temp<="100";
WHEN2=>modeout<="010";modeout_m<="010";
light_temp<="010";
WHEN3=>modeout<="100";modeout_m<="100";
light_temp<="001";
WHEN4=>modeout<="110";modeout_m<="110";
light_temp<="010";
WHEN5=>modeout<="111";modeout_m<="111";
light_temp<="100";
WHEN0=>modeout<="000";modeout_m<="000";
light_temp<="000";
WHENothers=>modeout<="000";modeout_m<="000";
light_temp<="000";
ENDCASE;
modeout_mm<=modeout_m;
CASEmodeout_mIS--设置时间,设置时间标志
WHEN"001"=>temp<=0;
times<=20;
WHEN"010"=>temp<=0;
times<=25;
WHEN"100"=>temp<=0;
times<=15;
WHEN"110"=>temp<=15;
times<=40;
WHEN"111"=>temp<=40;
times<=60;
WHEN"000"=>temp<=0;
times<=0;
WHENOTHERS=>temp<=0;
times<=0;
ENDCASE;
endprocess;
p2:
process(startkey)
variablecout2:
integerrange0to1;
begin
ifrising_edge(startkey)then
cout2:
=cout2+1;
endif;
if(cout2=1)then
s_p_out<='1';
else
s_p_out<='0';
endif;
endprocess;
p3:
process(startkey2)
variablecout3:
integerrange0to1;
begin
ifrising_edge(startkey2)then
cout3:
=cout3+1;
endif;
if(cout3=1)then
s_p_out2<='1';
else
s_p_out2<='0';
endif;
endprocess;
p4:
process(keyjs)
variablecoutt:
integerrange0to9;
begin
ifrising_edge(keyjs)then
ifcoutt<=8then
coutt:
=coutt+1;
elsecoutt:
=0;
endif;
endif;
casecouttis
when0=>js<=0;
when1=>js<=1;
when2=>js<=2;
when3=>js<=3;
when4=>js<=4;
when5=>js<=5;
when6=>js<=6;
when7=>js<=7;
when8=>js<=8;
when9=>js<=9;
whenothers=>js<=0;
endcase;
endprocess;
endbehave;
3.显示模块
(1)时间显示设置模块
此模块直接以控制模块输出的时间相连,由于倒计时时间是两位数字,必须用两个数码管来显示,在本程序中用将十位和个位分别显示的方法来实现时间输出显示的设计。
同时将每位上的十进制转换成二进制,以方便于其他程序共同调用相同的数码管显示程序来完成倒计时时间的现实
程序:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitytimesetis
port
(
clk:
instd_logic;
timesout:
inintegerrange0to60;
modeout_mm:
instd_logic_vector(2downto0);
shi,ge:
outstd_logic_vector(3downto0)
);
endtimeset;
architecturebehaveoftimesetis
begin
process(clk)
variableg:
integerrange0to9;
variables:
integerrange0to6;
begin
if(clk'eventandclk='1')then
if(modeout_mm="110"ormodeout_mm="111")then
iftimesout<10then
g:
=timesout;
s:
=0;
elsiftimesout>=10andtimesout<16then
g:
=timesout-10;
s:
=1;
elsiftimesout>=16andtimesout<25then
g:
=timesout-15;
s:
=0;
elsiftimesout>=25andtimesout<35then
g:
=timesout-25;
s:
=1;
elsiftimesout>=35andtimesout<40then
g:
=timesout-35;
s:
=2;
elsiftimesout=40then
g:
=5;
s:
=2;
elsiftimesout>40andtimesout<50then
g:
=timesout-40;
s:
=0;
elsiftimesout>=50andtimesout<60then
g:
=timesout-50;
s:
=1;
else
g:
=0;
s:
=2;
endif;
else
iftimesout<10then
g:
=timesout;
s:
=0;
elsiftimesout>=10andtimesout<20then
g:
=timesout-10;
s:
=1;
elsiftimesout>=20andtimesout<25then
g:
=timesout-20;
s:
=2;
else
g:
=5;
s:
=2;
endif;
endif;
casegis
when0=>ge<="0000";
when1=>ge<="0001";
when2=>ge<="0010";
when3=>ge<="0011";
when4=>ge<="0100";
when5=>ge<="0101";
when6=>ge<="0110";
when7=>ge<="0111";
when8=>ge<="1000";
when9=>ge<="1001";
endcase;
casesis
when0=>shi<="0000";
when1=>shi<="0001";
when2=>shi<="0010";
when3=>shi<="0011";
when4=>shi<="0100";
when5=>shi<="0101";
when6=>shi<="0110";
endcase;
endif;
endprocess;
endbehave;
仿真:
在上述的仿真图中,clk为扫描信号,timesout为输入的需要设计显示的时间,个代表个位的输出显示,十代表十位的输出显示,图中以16为例,可得个位输出的信号为0110(6),十位输出的信号为0001
(1),显然满足了设计的需要。
(2)数码管显示程序(leddecoder、leddecoder1、leddecoder2)
利用数码管显示数字的的原理分别设计了显示1~5的leddecoder,显示0~9的leddecoder2,显示1~3的leddecoder1程序,满足控制器模块倒计时,模式选择,模式时间选择的时间显示。
程序:
ledmode.vhd—在数码管上显示1~5
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityledmodeis
port
(
input:
instd_logic_vector(2downto0);
outseg:
outstd_logic_vector(6downto0)
);
endledmode;
architecturebehaveofledmodeis
begin
process(input)
begin
caseinputis
when"001"=>outseg<="0000110";
when"010"=>outseg<="1011011";
when"100"=>outseg<="1001111";
when"110"=>outseg<="1100110";
when"111"=>outseg<="1101101";
whenothers=>outseg<="0000000";
endcase;
endprocess;
endbehave;
lednumber.vhd在数码管上显示0~9
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitylednumberis
port
(
input:
instd_logic_vector(3downto0);
outseg:
outstd_logic_vector(6downto0)
);
endlednumber;
architecturebehaveoflednumberis
begin
process(input)
begin
caseinputis
when"0000"=>outseg<="0111111";
when"0001"=>outseg<="0000110";
when"0010"=>outseg<="1011011";
when"0011"=>outseg<="1001111";
when"0100"=>outseg<="1100110";
when"0101"=>outseg<="1101101";
when"0110"=>outseg<="1111101";
when"0111"=>outseg<="0000111";
when"1000"=>outseg<="1111111";
when"1001"=>outseg<="1101111";
whenothers=>outseg<="0000000";
endcase;
endprocess;
endbehave;
(3)选通信号程序
由6个数码管分别显示模式选择,各种模式下时间的选择,倒计时时间。
由于六个数码管的8个输入端是并联在一起的,而其共阴极端是相互独立的。
所以采用多个数码管动态扫显示的原理和人的视觉停留误差,使扫描的频率大于50*6=300hz,循环点亮数码管,完成数码管的固定显示。
程序:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityymis
port
(
clk:
instd_logic;
modeout:
instd_logic_vector(6downto0);
time_shi:
instd_logic_vector(6downto0);
time_ge,controlin,jsin,jsin2:
instd_logic_vector(6downto0);
disout:
outstd_logic_vector(6downto0);
sid:
outstd_logic_vector(5downto0)
);
endym;
architecturebehaveofymis
begin
process(clk)
variablet:
integerrange0to5;
begin
ifrising_edge(clk)then
if(t=5)then