VHDL 家用风扇程序设计:7 种状态,自然风,摇头,定时功能
entity fengshan is port( clk : in std_logic; -- 时钟信号 rst : in std_logic; -- 复位信号 btn_close : in std_logic; -- 关闭按钮 btn_lowspeed : in std_logic; -- 低速按钮 btn_midspeed : in std_logic; -- 中速按钮 btn_highspeed : in std_logic; -- 高速按钮 btn_natural : in std_logic; -- 自然风按钮 btn_shake : in std_logic; -- 摇头按钮 btn_timer : in std_logic; -- 定时按钮 wind_out : out std_logic_vector(1 downto 0); -- 风速输出 shake_out : out std_logic; -- 摇头输出 timer_out : out std_logic -- 定时输出 ); end fengshan;
architecture Behavioral of fengshan is -- 定义状态类型 type state_type is (CLOSE, LOWSPEED, MIDSPEED, HIGHSPEED, NATURAL, SHAKE, TIMER); signal state : state_type := CLOSE; -- 状态寄存器 signal cnt : integer := 0; -- 计数器,用于自然风状态的持续时间计算 signal shake_cnt : integer := 0; -- 计数器,用于摇头状态的计时 signal timer_cnt : integer := 0; -- 计数器,用于定时状态的计时 begin process(clk, rst) begin if rst = '1' then -- 复位 state <= CLOSE; -- 状态初始为关闭 cnt <= 0; shake_cnt <= 0; timer_cnt <= 0; wind_out <= "00"; -- 风速输出初始为关闭 shake_out <= '0'; -- 摇头输出初始为关闭 timer_out <= '0'; -- 定时输出初始为关闭 elsif rising_edge(clk) then -- 时钟上升沿 case state is when CLOSE => wind_out <= "00"; -- 关闭状态风速输出为0 if btn_lowspeed = '1' then -- 按下低速按钮 state <= LOWSPEED; -- 进入低速状态 elsif btn_midspeed = '1' then -- 按下中速按钮 state <= MIDSPEED; -- 进入中速状态 elsif btn_highspeed = '1' then -- 按下高速按钮 state <= HIGHSPEED; -- 进入高速状态 elsif btn_natural = '1' then -- 按下自然风按钮 state <= NATURAL; -- 进入自然风状态 cnt <= 0; -- 自然风状态计数器清零 elsif btn_shake = '1' then -- 按下摇头按钮 state <= SHAKE; -- 进入摇头状态 shake_cnt <= 0; -- 摇头计时器清零 elsif btn_timer = '1' then -- 按下定时按钮 state <= TIMER; -- 进入定时状态 timer_cnt <= 0; -- 定时计时器清零 end if; when LOWSPEED => wind_out <= "01"; -- 低速状态风速输出为1 if btn_close = '1' then -- 按下关闭按钮 state <= CLOSE; -- 回到关闭状态 elsif btn_midspeed = '1' then -- 按下中速按钮 state <= MIDSPEED; -- 进入中速状态 elsif btn_highspeed = '1' then -- 按下高速按钮 state <= HIGHSPEED; -- 进入高速状态 elsif btn_natural = '1' then -- 按下自然风按钮 state <= NATURAL; -- 进入自然风状态 cnt <= 0; -- 自然风状态计数器清零 elsif btn_shake = '1' then -- 按下摇头按钮 state <= SHAKE; -- 进入摇头状态 shake_cnt <= 0; -- 摇头计时器清零 elsif btn_timer = '1' then -- 按下定时按钮 state <= TIMER; -- 进入定时状态 timer_cnt <= 0; -- 定时计时器清零 end if; when MIDSPEED => wind_out <= "10"; -- 中速状态风速输出为2 if btn_close = '1' then -- 按下关闭按钮 state <= CLOSE; -- 回到关闭状态 elsif btn_lowspeed = '1' then -- 按下低速按钮 state <= LOWSPEED; -- 进入低速状态 elsif btn_highspeed = '1' then -- 按下高速按钮 state <= HIGHSPEED; -- 进入高速状态 elsif btn_natural = '1' then -- 按下自然风按钮 state <= NATURAL; -- 进入自然风状态 cnt <= 0; -- 自然风状态计数器清零 elsif btn_shake = '1' then -- 按下摇头按钮 state <= SHAKE; -- 进入摇头状态 shake_cnt <= 0; -- 摇头计时器清零 elsif btn_timer = '1' then -- 按下定时按钮 state <= TIMER; -- 进入定时状态 timer_cnt <= 0; -- 定时计时器清零 end if; when HIGHSPEED => wind_out <= "11"; -- 高速状态风速输出为3 if btn_close = '1' then -- 按下关闭按钮 state <= CLOSE; -- 回到关闭状态 elsif btn_lowspeed = '1' then -- 按下低速按钮 state <= LOWSPEED; -- 进入低速状态 elsif btn_midspeed = '1' then -- 按下中速按钮 state <= MIDSPEED; -- 进入中速状态 elsif btn_natural = '1' then -- 按下自然风按钮 state <= NATURAL; -- 进入自然风状态 cnt <= 0; -- 自然风状态计数器清零 elsif btn_shake = '1' then -- 按下摇头按钮 state <= SHAKE; -- 进入摇头状态 shake_cnt <= 0; -- 摇头计时器清零 elsif btn_timer = '1' then -- 按下定时按钮 state <= TIMER; -- 进入定时状态 timer_cnt <= 0; -- 定时计时器清零 end if; when NATURAL => if cnt >= 2_000_000_000 then -- 计数器达到最大值,重置为0 cnt <= 0; else cnt <= cnt + 1; -- 计数器加1 end if; case cnt mod 6 is -- 计数器模6的值为0~5,用于实现风速随机切换 when 0 | 1 => wind_out <= "01"; -- 风速输出为1 when 2 | 3 => wind_out <= "10"; -- 风速输出为2 when 4 | 5 => wind_out <= "11"; -- 风速输出为3 end case; if btn_close = '1' then -- 按下关闭按钮 state <= CLOSE; -- 回到关闭状态 elsif btn_lowspeed = '1' then -- 按下低速按钮 state <= LOWSPEED; -- 进入低速状态 elsif btn_midspeed = '1' then -- 按下中速按钮 state <= MIDSPEED; -- 进入中速状态 elsif btn_highspeed = '1' then -- 按下高速按钮 state <= HIGHSPEED; -- 进入高速状态 elsif btn_shake = '1' then -- 按下摇头按钮 state <= SHAKE; -- 进入摇头状态 shake_cnt <= 0; -- 摇头计时器清零 elsif btn_timer = '1' then -- 按下定时按钮 state <= TIMER; -- 进入定时状态 timer_cnt <= 0; -- 定时计时器清零 end if; when SHAKE => if shake_cnt < 100_000_000 then -- 计时器未达到目标值 shake_cnt <= shake_cnt + 1; -- 计时器加1 shake_out <= '1'; -- 摇头输出为1 elsif shake_cnt < 200_000_000 then -- 计时器达到目标值,但未到下一次目标值 shake_cnt <= shake_cnt + 1; -- 计时器加1 shake_out <= '0'; -- 摇头输出为0 else -- 计时器达到下一次目标值 shake_cnt <= 0; -- 计时器清零 end if; if btn_close = '1' then -- 按下关闭按钮 state <= CLOSE; -- 回到关闭状态 elsif btn_lowspeed = '1' then -- 按下低速按钮 state <= LOWSPEED; -- 进入低速状态 elsif btn_midspeed = '1' then -- 按下中速按钮 state <= MIDSPEED; -- 进入中速状态 elsif btn_highspeed = '1' then -- 按下高速按钮 state <= HIGHSPEED; -- 进入高速状态 elsif btn_natural = '1' then -- 按下自然风按钮 state <= NATURAL; -- 进入自然风状态 cnt <= 0; -- 自然风状态计数器清零 elsif btn_timer = '1' then -- 按下定时按钮 state <= TIMER; -- 进入定时状态 timer_cnt <= 0; -- 定时计时器清零 end if; when TIMER => if timer_cnt < 60_000_000 then -- 计时器未达到目标值 timer_cnt <= timer_cnt + 1; -- 计时器加1 timer_out <= '1'; -- 定时输出为1 else -- 计时器达到目标值 timer_cnt <= 0; -- 计时器清零 timer_out <= '0'; -- 定时输出为0 if btn_close = '1' then -- 按下关闭按钮 state <= CLOSE; -- 回到关闭状态 elsif btn_lowspeed = '1' then -- 按下低速按钮 state <= LOWSPEED; -- 进入低速状态 elsif btn_midspeed = '1' then -- 按下中速按钮 state <= MIDSPEED; -- 进入中速状态 elsif btn_highspeed = '1' then -- 按下高速按钮 state <= HIGHSPEED; -- 进入高速状态 elsif btn_natural = '1' then -- 按下自然风按钮 state <= NATURAL; -- 进入自然风状态 cnt <= 0; -- 自然风状态计数器清零 elsif btn_shake = '1' then -- 按下摇头按钮 state <= SHAKE; -- 进入摇头状态 shake_cnt <= 0; -- 摇头计时器清零 end if; end if; end case; end if; end process; end Behaviora
原文地址: https://www.cveoy.top/t/topic/oz8D 著作权归作者所有。请勿转载和采集!