洗衣机控制系统 VHDL语言 状态机实现
来源:互联网 发布:origin8.0软件下载 编辑:程序博客网 时间:2024/04/28 14:46
题目要求如下:
一、设计任务
洗衣机有注水、洗涤、排水、脱水和漂洗等功能,每个功能均有对应的显示灯,运行在某种工作状态时,其对应显示灯一直亮,直到此功能工作结束。其中,注水功能提供低,中,高三个水位等级供用户选择;洗涤功能有弱洗,普通,强洗三个洗涤等级可供选择。注水,洗涤,排水,脱水,漂洗状态的转变分别由各自的使能端控制。
系统有六个工作模式。其中,模式1=洗涤+漂洗+脱水,模式2=洗涤+漂洗,模式3=漂洗+脱水,模式4=洗涤,模式5=漂洗,模式6=脱水。
二、需求分析
(1)系统所有操作均有统一的时钟信号,统一的复位端。
(2)系统设有暂停端,当处于某一工作状态时,若按下暂停端,则停在此工作状态。
(3)在当前的运行状态时,有数码显示当前剩余时间;
(4)所有操作完成之后,有响铃提示。
三、设计方案
该系统由输入模块、控制模块和输出模块构成。输入模块完成洗涤时间的预置与编码,控制模块完成洗涤时间计时以及对电机运行状态的控制,输出模块完成电机运行状态的指示。
四、必须用状态机实现(为后续课程组原做准备),经典状态机代码如下:
1. Moore型状态机:
library ieee;
use ieee.std_logic_1164.all;
entity Moore is
port(
Reset:in std_logic;
Clock:in std_logic;
DIN:in std_logic;
DOUT:out std_logic_vector(2 downto 0)
);
end Moore;
architecture Mooremachine of Moore is
type State_type is(S0,S1,S2,S3);
signal PresenState:State_type;
signal NextnState:State_type;
begin
State_Reg:
process(Reset,Clock)
begin
if Reset='1'then
PresenState<=S0;
elsif rising_edge(Clock)then
PresenState<=NextnState;
end if;
end process;
Change_State:
process(PresenState,DIN)
begin
case PresenState is
when S0=>
if DIN='1'then
NextnState<=S1;
else
NextnState<=S0;
end if;
DOUT<="001";
when S1=>
if DIN='1'then
NextnState<=S2;
else
NextnState<=S1;
end if;
DOUT<="011";
when S2=>
if DIN='1'then
NextnState<=S3;
else
NextnState<=S2;
end if;
DOUT<="101";
when S3=>
if DIN='1'then
NextnState<=S0;
else
NextnState<=S1;
end if;
DOUT<="111";
end case;
end process;
end Mooremachine;
2. Mealy型状态机:
library ieee;
use ieee.std_logic_1164.all;
entity Mealy is
port(
Reset:in std_logic;
Clock:in std_logic;
DIN:in std_logic;
DOUT:out std_logic_vector(2 downto 0)
);
end Mealy;
architecture Statemachine of Mealy is
type State_type is(S0,S1,S2,S3);
signal State:State_type;
begin
Change_State:
process(State,DIN)
begin
if Reset='1'then
State<=S0;
elsif rising_edge(Clock)then
case State is
when S0=>
if DIN='1' then
State<=S1;
end if;
when S1=>
if DIN='1' then
State<=S2;
end if;
when S2=>
if DIN='1' then
State<=S3;
end if;
when S3=>
if DIN='1' then
State<=S0;
else
State<=S1;
end if;
end case;
end if;
end process;
Output_Process:
process(State,DIN)
begin
case State is
when S0=>
if DIN='0' then
DOUT<="000";
else
DOUT<="001";
end if;
when S1=>
if DIN='0' then
DOUT<="010";
else
DOUT<="011";
end if;
when S2=>
if DIN='0' then
DOUT<="100";
else
DOUT<="101";
end if;
when S3=>
if DIN='0' then
DOUT<="110";
else
DOUT<="111";
end if;
end case;
end process;
end Statemachine;
——————————————————————————————————————————————
以下是设计及实现:
一、设计思路
先确定输入有哪些,通过观察题目可知,“系统的所有操作均有统一时钟信号,统一的复位端”,“系统有六个工作模式。模式1=洗涤+漂洗+脱水….”,“系统设有暂停端”,“注水功能提供低,中,高三个水位等级供用户选择;洗涤功能有弱洗,普通,强洗三个洗涤等级可供选择”。综上可得出输入有以下几个:clk:时钟信号;reset:复位端,相当于开关,为‘1’时复位,为‘0’时洗衣机才可正常工作;user_input:用户输入的模式选择001—110分别为模式1—模式6;zanting:暂停端,为‘1’时暂停;zs_time:注水有低中高三个水位等级,可用注水时间长短来表示(当注水3s表示低水位,4s表示中水位,5s表示高水位);px_time:漂洗时间(当漂洗水3s表示弱洗,4s表示普通,5s表示强洗)。其余功能时间设置均为5s。
再确定输出,仍分析题目:“每个功能均有对应的显示灯,运行在某种工作状态时,其对应显示灯一直亮,直到此功能工作结束”,“在当前的运行状态时,有数码显示当前剩余时间”,“所有操作完成之后,有响铃提示”。综上得输出有以下几个:light1,light2...light5:每个功能所对应的显示灯,当该功能被运行时,显示灯会一直亮;time_3s:3s倒计时显示器;time_4s:4s倒计时显示器;time_5s:5s倒计时显示器;ring:铃。
整个系统由三个模块组成,第一个模块是输入模块,在这个模块,需要用户输入所选择的模式,以及注水漂洗的时间,若选择的模式为3,4或6,则可略去洗涤时间,然后把模式编码,编码对应如下:
1. 模式1=漂洗+洗涤+脱水001->001 010 011 100 101 110 (注水+漂洗+洗涤+脱水+排水+响铃)
2. 模式2=漂洗+洗涤 010->001 010 011 000 101 110 (注水+漂洗+洗涤+ 空 +排水+响铃)
3. 模式3=漂洗+脱水 011->001 000 011 100 101 110 (注水+漂洗+ 空 +脱水+排水+响铃)
4. 模式4=漂洗 100->001 010 000 000 101 110 (注水+漂洗+ 空 + 空 +排水+响铃)
5. 模式5=洗涤 101->001 000 011 000 101 110 (注水+ 空 +洗涤+ 空 +排水+响铃)
6. 模式6=脱水 110->001 000 000 100 101 110 (注水+ 空 + 空 +脱水+排水+响铃)
第二个模块为计时模块,包含3部分:3s计时器,4s计时器和5s计时器;
第三个模块为控制模块,本次课设选用的是米里机,这个模块需要进行状态转换,一共有6个状态,当reset为‘1’时是S0状态,否则当上升沿到来时,转为S1状态(注水),此时读取注水时间,激活相应计时器,当计时器到时候反馈回一个计时结束的信号时,转为S2状态(漂洗)或S3状态(洗涤)或S4状态(脱水),视读取的编码而定....直至S6状态响铃,然后转为S7灯灭铃熄。具体见下文代码。
二、具体实现
输入文件:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY shuru IS
PORT
(
user_input :INSTD_LOGIC_vector(2 downto 0);
reset : INSTD_LOGIC;
clk : INSTD_LOGIC;
user_output : OUT STD_LOGIC_vector(17 downto 0)
);
END shuru;
ARCHITECTURE b OF shuru IS
BEGIN
PROCESS (reset,clk)
BEGIN
IF reset = '1' then
user_output <= "000000000000000000";
elsif (clk'EVENT AND clk = '1') THEN
if user_input = "001" then --模式一
user_output <= "001010011100101110";
elsif user_input = "010" then --模式二
user_output <= "001010011000101110";
elsif user_input = "011" then --模式三
user_output <= "001000011100101110";
elsif user_input = "100" then --模式四
user_output <= "001010000000101110";
elsif user_input = "101" then --模式五
user_output <= "001000011000101110";
elsif user_input = "110" then --模式六
user_output <= "001000000100101110";
else user_output <= "000000000000000000";
end if; --user_input
END IF; --reset
END PROCESS;
END b;
状态转换文件:
library ieee;
use ieee.std_logic_1164.all;
entity Mealy_control is
port(
reset : in std_logic;
clk : in std_logic;
zs_time : in std_logic_vector(2 downto 0); --注水时间(100: 4s, 011: 3s, 101: 5s)
px_time : in std_logic_vector(2 downto 0); --漂洗时间(100: 4s, 011: 3s, 101: 5s)
time_4s : in std_logic; --从计时器反馈过来的信号,为'1'时表示4s已经结束
time_3s : in std_logic;
time_5s : in std_logic;
enable_4s : out std_logic; --为'1'时启动4s计时器
enable_3s : out std_logic;
enable_5s : out std_logic;
light1 : out std_logic;
light2 : out std_logic;
light3 : out std_logic;
light4 : out std_logic;
light5 : out std_logic;
ring : out std_logic;
transfer : in std_logic_vector(17 downto 0);
DOUT : out std_logic_vector(2 downto 0)
);
end Mealy_control;
architecture a of Mealy_control is
type State_type is(s0, s1, s2, s3, s4, s5, s6, s7);
signal State : State_type;
signal DIN : std_logic_vector(2 downto 0);
signal DIN_DIN : std_logic_vector(2 downto 0);
--signal DIN : std_logic_vector(2 downto 0);
begin
process(State, transfer)
begin
if reset='1' then
State<=s0;
elsif(clk'event and clk='1')then
case State is
when s0=> --s0到s1状态的转换经过了两个上升沿????????????????
DIN <= transfer(17)&transfer(16)&transfer(15);
if DIN="001" then
State<=s1;
if zs_time="100" then enable_4s<='1';enable_3s<='0';enable_5s<='0';
elsif zs_time="011" then enable_4s<='0';enable_3s<='1';enable_5s<='0';
elsif zs_time="101" then enable_4s<='0';enable_3s<='0';enable_5s<='1';
end if;
else State<=s0;
end if;
when s1=>
DIN<=transfer(14)&transfer(13)&transfer(12);
DIN_DIN<=transfer(11)&transfer(10)&transfer(9);
if DIN="010" and (time_4s='1' or time_3s='1' or time_5s='1') then
State<=s2;
if px_time="100" then enable_4s<='1';enable_3s<='0';enable_5s<='0';
elsif px_time="011" then enable_4s<='0';enable_3s<='1';enable_5s<='0';
elsif px_time="101" then enable_4s<='0';enable_3s<='0';enable_5s<='1';
end if;
elsif DIN="000" and DIN_DIN="000" and (time_4s='1' or time_3s='1' or time_5s='1') then
State<=s4;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
elsif DIN="000" and (time_4s='1' or time_3s='1' or time_5s='1') then
State<=s3;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
else State<=s1;
end if;
when s2=>
DIN<=transfer(11)&transfer(10)&transfer(9);
DIN_DIN<=transfer(8)&transfer(7)&transfer(6); --模式四
if DIN="011" and (time_4s='1' or time_3s='1' or time_5s='1') then
State<=s3;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
elsif DIN="000" and DIN_DIN="000" and (time_4s='1' or time_3s='1' or time_5s='1') then
State<=s5;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
elsif DIN="000" and (time_4s='1' or time_3s='1' or time_5s='1') then
State<=s4;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
else State<=s2;
end if;
when s3=>
DIN<=transfer(8)&transfer(7)&transfer(6);
if DIN="100" and time_5s='1' then
State<=s4;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
elsif DIN="000" and time_5s='1' then
State<=s5;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
else State<=s3;
end if;
when s4=>
DIN<=transfer(5)&transfer(4)&transfer(3);
if DIN="101" and time_5s='1' then
State<=s5;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
else State<=s4;
end if;
when s5=>
DIN<=transfer(2)&transfer(1)&transfer(0);
if DIN="110" and time_5s='1' then
State<=s6;
enable_4s<='0';enable_3s<='0';enable_5s<='1';
else State<=s5;
end if;
when s6=> --当响铃时刻
if time_5s='1' then
State<=s7; --s0之后的状态--错误!
else State<=s6;
end if;
when s7=>
enable_4s<='0';enable_3s<='0';enable_5s<='0';
end case;
end if;
end process;
process(State, transfer)
begin
case State is
when s0=>
light1<='0';light2<='0';light3<='0';light4<='0';light5<='0';ring<='0';
DOUT<="000";
when s1=>
light1<='1';light2<='0';light3<='0';light4<='0';light5<='0';ring<='0';
DOUT<="001";
when s2=>
light1<='0';light2<='1';light3<='0';light4<='0';light5<='0';ring<='0';
DOUT<="010";
when s3=>
light1<='0';light2<='0';light3<='1';light4<='0';light5<='0';ring<='0';
DOUT<="011";
when s4=>
light1<='0';light2<='0';light3<='0';light4<='1';light5<='0';ring<='0';
DOUT<="100";
when s5=>
light1<='0';light2<='0';light3<='0';light4<='0';light5<='1';ring<='0';
DOUT<="101";
when s6=>
light1<='0';light2<='0';light3<='0';light4<='0';light5<='0';ring<='1';
DOUT<="110";
when s7=>
light1<='0';light2<='0';light3<='0';light4<='0';light5<='0';ring<='0';
DOUT<="000";
end case;
end process;
end a;
计时器文件
(1)3s计时器文件
library ieee;
use ieee.std_logic_1164.all;
entity jishi_3s is
port(
clk : in std_logic;
reset_enable : in std_logic; --重置
zanting : in std_logic; --暂停端 1为暂停
output_3s : out STD_LOGIC_vector(1 downto 0);
time_3s : out std_logic --反馈给控制模块,为'1'时表示1s倒计时结束
);
end jishi_3s;
architecture d of jishi_3s is
begin
process(reset_enable,clk)
variable count : integer range 0 to 3;
begin
if(reset_enable='0')then
count:=3;
--output_3s<="00";
output_3s<="11";
time_3s<='0';
elsif(clk'event and clk='1')then
if zanting='0' then --未暂停
count:=count-1;
if(count=2)then output_3s<="10";time_3s<='0';
elsif(count=1)then output_3s<="01";time_3s<='0';
elsif(count=0)then output_3s<="00";time_3s<='1';count:=3;
end if; --if count=0
end if; --zanting
end if; --if reset
end process;
end d;
(2)4s计时器文件
library ieee;
use ieee.std_logic_1164.all;
entity jishi_4s is
port(
clk : in std_logic;
reset_enable : in std_logic; --重置
zanting : in std_logic; --暂停端 1为暂停
output_4s : out STD_LOGIC_vector(2 downto 0);
time_4s : out std_logic --反馈给控制模块,为'1'时表示4s倒计时结束
);
end jishi_4s;
architecture d of jishi_4s is
begin
process(reset_enable,clk)
variable count : integer range 0 to 4;
begin
if(reset_enable='0')then
count:=4;
output_4s<="100";
time_4s<='0';
elsif(clk'event and clk='1')then
if zanting='0' then --未暂停
count:=count-1;
if(count=3)then output_4s<="011";time_4s<='0';
elsif(count=2)then output_4s<="010";time_4s<='0';
elsif(count=1)then output_4s<="001";time_4s<='0';
elsif(count=0)then output_4s<="000";time_4s<='1';count:=4;
end if; --if count=0
end if; --zanting
end if; --if reset
end process;
end d;
(3)5s计时器文件
library ieee;
use ieee.std_logic_1164.all;
entity jishi_5s is
port(
clk : in std_logic;
reset_enable : in std_logic; --重置
zanting : in std_logic; --暂停端 1为暂停
output_5s : out STD_LOGIC_vector(2 downto 0);
time_5s : out std_logic --反馈给控制模块,为'1'时表示1s倒计时结束
);
end jishi_5s;
architecture d of jishi_5s is
begin
process(reset_enable,clk)
variable count : integer range 0 to 5;
begin
if(reset_enable='0')then
count:=5;
output_5s<="101";
time_5s<='0';
elsif(clk'event and clk='1')then
if zanting='0' then --未暂停
count:=count-1;
if(count=4)then output_5s<="100";time_5s<='0';
elsif(count=3)then output_5s<="011";time_5s<='0';
elsif(count=2)then output_5s<="010";time_5s<='0';
elsif(count=1)then output_5s<="001";time_5s<='0';
elsif(count=0)then output_5s<="000";time_5s<='1';count:=5;
end if; --if count=0
end if; --zanting
end if; --if reset
end process;
end d;
三个文件连接的bdf图如下所示
得到的仿真结果如下,第一张是模式一,第二张是模式5,其余略。
哈哈,仔细看仿真结果你就会发现其实是有错误的,但是一个个分别运行这三个文件得出的仿真结果又正确,所以说问题就出在控制部分的时钟沿和计时器的时钟沿没有协调好,这个错误 我现在还没想到解决方法,如果众位大神知道如何做最少的修改能改掉这个错误,恳请一定要告诉我,在此谢过!
- 洗衣机控制系统 VHDL语言 状态机实现
- VHDL状态机
- VHDL 键盘扫描程序,用状态机实现
- PLC 全自动洗衣机控制系统
- VHDL温度控制系统设计
- 用vhdl语言实现寄存器
- VHDL描述状态机
- 状态机的VHDL设计
- C语言实现状态机
- VHDL状态机控制ADC0809[转贴]
- C语言状态机的实现
- VHDL语言实现的任意整数分频器。
- 计算机组成原理课程设计(vhdl语言实现)
- VHDL语言
- 基于C语言的状态机实现技术
- 层次状态机的实现 c语言
- 基于C语言的状态机实现技术
- 一个简单C++语言状态机实现
- Windows多线程编程
- HDU 1014 Uniform Generator(水~)
- 华为OJ(坐标移动)
- Unity打包xcode工程编译错误及解决方法
- SFTP工具类
- 洗衣机控制系统 VHDL语言 状态机实现
- Hibernate关联之 一对多外键双向关联
- [linux] 命令
- linux mongo 安装
- jsp垂直导航栏 悬浮和选中特效
- 华为虚拟化fusioncompute组件安装失败解决方法
- myeclipse 2013 jad 反编译插件安装
- 记录几个自己做的xml效果
- Parallels Desktop 11 for Mac新增功能