FPGA实现呼吸灯(带演示)

目录


前言

一、设计要求

二、设计思路

三、VHDL设计代码

四、引脚分配

五、试验演示

总结


前言

        上一次写的代码不是很好,这次的我个人感觉更加容易理解和实现,更加的好看。

一、设计要求

         使用VHDL语言建模,让开发板上的任意一个 LED实现呼吸灯的效果,即由灭渐亮(过程为2秒),然后再由亮渐灭(过程为2秒),可实现复位和随时暂停。PWM频率为50Hz,灰度级为50。

二、设计思路

        第一步:分频系统时钟得到50HZ的pwm时钟,该时钟用于控制占空比的递增递减

        第二步:调整占空比,每一pwm周期占空比加 1 或减 1,占空比的灰度级设置为50

        第三步:利用占空比和系统时钟来控制LED的亮灭以达到呼吸效果,在这里不使用pwm时钟来控制,即相当于又设置了一个50HZ的时钟。

        第四步:在原来基础上加入复位和暂停功能,复位键按下LED熄灭,松手呼吸灯重新开始(从亮到灭,再从灭到亮),占空比跳到最大;暂停键按下LED断气停止“呼吸”,再次按下LED恢复“呼吸”,并保留“断气”前的占空比和呼吸状态。

 PWM 占空比示意图:

三、VHDL设计代码

library ieee;
use ieee.std_logic_1164.all;

entity new_breathing is
    port(sys_clk:in std_logic;--系统时钟
    sys_rst:in std_logic;--复位键,按下状态恢复为由亮到灭
    pause:in std_logic;--暂停键,第一次按下呼吸灯暂停,再次按下呼吸灯继续亮灭
    led:out std_logic);
end new_breathing;

architecture behav of new_breathing is 
signal pwm_clk:std_logic:='0';--pwm时钟
signal duty_cycle:integer range 0 to 51:=0;--占空比,范围0~50,选51是怕后续会溢出报错,但应该也不会,因为2^8>51
signal mode:std_logic:='0';--'0'为由亮到灭,'1'为由灭到亮
signal state:std_logic:='1';--'0'为暂停,'1'为开始
    begin
    --时钟分频为50hz
        process(sys_clk, sys_rst, pause)
            variable count:integer range 0 to 500000:=0;--这里说明pwm的周期为50M/(500000*2)=50hz,用于调整呼吸长短(t = (2*x)/1000000)秒
            begin
                if(rising_edge(sys_clk)) then--这里是时钟分频
                    if(count<500000) then
                        count:=count+1;
                    else pwm_clk<= not pwm_clk;--翻转
                        count:=0;--重新计数
                    end if;
                end if;
                if(sys_rst='1') then--复位键会覆盖暂停键
                    if(rising_edge(pause)) then--暂停键,只有按下的时候才翻转,符合暂停的定义
                        state<=not state;
                    end if;
                elsif(sys_rst='0') then
                    state<= '1';--如果复位了则暂停键失效
                end if;
            end process;
            
        process(pwm_clk, sys_rst, pause)
            begin
                if(rising_edge(pwm_clk)) then--pwm每周期占空比会加1或减1以达到连续的效果
                    if(sys_rst='1') then
                        if(state='1') then--未复位
                            if(mode='0') then--由亮到暗
                                if(duty_cycle>0) then
                                    duty_cycle<=duty_cycle-1;--占空比逐渐减少
                                elsif(duty_cycle=0) then
                                    mode<='1';--模式跳转
                                end if;
                            elsif(mode='1') then--由暗到亮
                                if(duty_cycle<51) then
                                    duty_cycle<=duty_cycle+1;--占空比逐渐增大
                                elsif(duty_cycle=51) then
                                    mode<='0';--模式跳转
                                end if;
                            end if;
                        elsif(state='0') then--暂停效果
                            duty_cycle<=duty_cycle;--占空比保持
                            mode<=mode;--模式保持,多余的,因为mode只受duty_cycle影响
                        end if;
                    elsif(sys_rst='0') then--复位效果
                        mode<='0';--模式跳转为由亮到暗
                        duty_cycle<=50;--占空比跳到最大
                    end if;
                end if;
            end process;
                
        process(sys_clk, sys_rst)
        variable count2:integer range 0 to 1000000:=0;--pwm周期50M/1M=50hz
            begin
                if(rising_edge(sys_clk)) then
                    count2:=count2+1;
                    if(sys_rst='1') then
                        if(count2<duty_cycle*20000) then--50/1000000=1/20000
                            led<='1';                        
                        elsif(count2>duty_cycle) then
                            led<='0';
                        elsif(count2=1000000) then
                            count2:=0;
                            led<='0';--如果为'1'则led会闪烁一下
                        end if;
                    elsif(sys_rst='0') then--复位效果
                        count2:=0;--重新开始计数
                        led<='0';--断气
                    end if;
                end if;
            end process;
    end behav;

四、引脚分配

        我的板子是正点原子的新起点v2,芯片型号:EP4CE10F17C8

引脚分配见下图:

五、试验演示

视频链接:点击这里_哔哩哔哩_bilibili


总结

        这次书写比上次更加得心应手,没有卡顿的地方,上次想得太复杂了。

(我是小白,不喜轻喷)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值