《FPGA学习》->呼吸灯

news2024/9/17 8:29:23
🍎 与其担心未来,不如现在好好努力。在这条路上,只有奋斗才能给你安全感。你若努力,全世界都会为你让路。

呼吸灯,简而言之就像人类呼吸一样,有节奏的让LED灯从:灭->微微亮->微亮->亮->高亮,然后再从:高亮->亮->微亮->微微亮->灭的这样一个过程。

而LED的亮暗程度取决与电压的高低,在安全范围内,电压越高LED亮度越大,电压越低LED亮度越小。但是我们没办法去自动控制电压的高低,所以我们采用通过改变其占空比的方式来调节,即PWM(脉冲宽度调制)技术。简单来说就是在一定的时间周期内,改变高电平所占用的时间。

呼吸灯框架图如下:

PWM调制原理如下图所示:

对PWM有了了解以后,我们开始画波形图,然后对照波形图编写代码,波形图如下:

①sys_clk:时钟信号;

②sys_rst_n:复位信号,低电平有效;

③cnt_1us:因为开发板为50MHz,所以一个时钟周期为20ns,那1us秒即50个时钟周期;

④cnt_1ms:1000个1us进1;

⑤cnt_1s:1000个1ms进1;

⑥cnt_en:使能信号标志位,用来判断LED状态是否到了反转时刻;

⑦led_out:LED状态输出。

源代码如下:

module breath_led          //模块开始,定义名称为waterfall_light
#(
    parameter CNT_1US_MAX = 6'd49   ,  //定义全局变量CNT_1US_MAX,时间周期为1us 
    parameter CNT_1MS_MAX = 10'd999 ,  //定义全局变量CNT_1MS_MAX,时间周期为1ms 
    parameter CNT_1S_MAX  = 10'd999    //定义全局变量CNT_1S_MAX,时间周期为1s 
)
(
    input    wire    sys_clk   ,     //定义sys_clk为输入模式   (时钟)
    input    wire    sys_rst_n ,     //定义sys_rst_n为输入模式 (复位)
    
    output    reg        led_out          //定义led_out为寄存器类型的输出模式
);

    reg  [5:0]    cnt_1us;           //定义cnt_1us为6位宽的寄存器类型
    reg  [9:0]    cnt_1ms;           //定义cnt_1ms为10位宽的寄存器类型
    reg  [9:0]    cnt_1s ;           //定义cnt_1s为10位宽的寄存器类型
    reg          cnt_en ;           //定义cnt_en为寄存器类型
    
always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)               //复位信号到来
            begin
                cnt_1us <= 6'd0;            //使cnt_1us清零
            end
        else    if(cnt_1us == CNT_1US_MAX)  //判断cnt_1us是否计数到最大值
            begin
                cnt_1us <= 6'd0;            //使cnt_1us清零
            end
        else 
            cnt_1us <= cnt_1us + 6'd1;        //使cnt_1us + 1
    end
    
always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)               //复位信号到来
            begin
                cnt_1ms <= 10'd0;           //使cnt_1ms清零
            end
        else    if((cnt_1ms == CNT_1MS_MAX)&&(cnt_1us == CNT_1US_MAX))  //判断cnt_1us和cnt_1ms是否同时计数到最大值 
            begin
                cnt_1ms <= 10'd0;           //使cnt_1ms清零
            end
        else    if(cnt_1us == CNT_1US_MAX)  //判断cnt_1us是否计数到最大值
            begin
                cnt_1ms <= cnt_1ms + 10'd1;   //使cnt_1ms + 1
            end
        else 
            cnt_1ms <= cnt_1ms;
    end
    
always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)               //复位信号到来
            begin
                cnt_1s <= 10'd0;           //使cnt_1s清零
            end
        else    if((cnt_1s  == CNT_1S_MAX)&& (cnt_1ms == CNT_1MS_MAX)&&(cnt_1us == CNT_1US_MAX))  //判断cnt_1us,cnt_1ms,cnt_1s是否同时计数到最大值 
            begin
                cnt_1s <= 10'd0;           //使cnt_1s清零
            end
        else    if((cnt_1ms == CNT_1MS_MAX)&&(cnt_1us == CNT_1US_MAX))  //判断cnt_1us和cnt_1ms是否同时计数到最大值 
            begin
                cnt_1s <= cnt_1s + 10'd1;  //使cnt_1s + 1
            end
        else 
            cnt_1s <= cnt_1s;              //使cnt_1s保持不变
    end

always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)              //复位信号到来
            begin
                cnt_en <= 1'b0;            //使cnt_1s清零
            end
        else    if((cnt_1s  == CNT_1S_MAX)&& (cnt_1ms == CNT_1MS_MAX)&&(cnt_1us == CNT_1US_MAX))  //判断cnt_1us,cnt_1ms,cnt_1s是否同时计数到最大值 
            begin
                cnt_en <= ~cnt_en;         //使cnt_en取反
            end
        else 
            cnt_en <= cnt_en;              //使cnt_en保持不变    
    end

always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(sys_rst_n == 1'b0)              //复位信号到来
            begin
                led_out <= 1'b1;            //使led_out置1
            end
        else    if(((cnt_en  == 1'b0)&&(cnt_1ms <= cnt_1s)) || ((cnt_en  == 1'b1)&&(cnt_1ms > cnt_1s))) //判断cnt_en为0且cnt_1ms计数值小于等于cnt_1s
            begin                                                                                       //或者判断cnt_en为1且cnt_1ms计数值大于cnt_1s执行
                led_out <= 1'b0;            //使led_out置0
            end
        else 
            led_out <= 1'b1;                //使led_out置1
    end
    
endmodule         //模块结束

生成的RTL电路图如下:

仿真代码如下:

`timescale 1ns/1ns               //时间尺度预编译指令      时间单位/时间精度

module tb_breath_led ();     //定义模块名称为tb_breath_led

reg        sys_clk   ;     //定义sys_clk为reg型
reg        sys_rst_n ;     //定义sys_rst_n为reg型
wire    led_out   ;     //定义led_out为reg型

breath_led                  //例化对象名称
#(
    .CNT_1US_MAX (6'd4)    ,            //改变parameter定义的参数
    .CNT_1MS_MAX (10'd9)   ,            //改变parameter定义的参数
    .CNT_1S_MAX  (10'd9)                //改变parameter定义的参数
)
breath_led_inst            //实例化名称
(
    .sys_clk      (sys_clk),       //使sys_clk信号端口例化为sys_clk
    .sys_rst_n    (sys_rst_n),     //使sys_rst_n信号端口例化为sys_rst_n
                                 
    .led_out      (led_out)        //使led_out信号端口例化为led_out
);

initial                          //初始化
    begin                        
        sys_clk   = 1'b1  ;      //使sys_clk初始化为高电平状态
        sys_rst_n = 1'b0  ;      //使sys_clk初始化为低电平状态
        #20                      //延时20ns
        sys_rst_n = 1'b1  ;      //使sys_rst_n电平拉高
    end                          
                                 
always #10 sys_clk = ~sys_clk;   //使sys_clk电平10ns电平状态反转一次
    
endmodule            //模块结束

仿真波形如下:

从图中可以看出,运行后的仿真波形与设计需求保持一致,任务完成。

🔥🔥🔥本系列文章持续更新,喜欢的话可以关注收藏~🔥🔥🔥

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/359022.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python HZK16字库使用

注&#xff1a; 从个人博客园移植而来 环境&#xff1a; windows7, python2.7 简介 偶然在网上看到热心网友使用python讲微信头像进行了组字&#xff0c;感觉很有意思&#xff0c;就做下研究。 感谢&#xff0c;原文参考: Python玩微信头像组字 需求的相关工具&#xff1a; …

spring cloud gateway 实现redis动态路由及自动项目路由上报

前言 spring cloud gateway默认为内存存储策略&#xff0c;通过配置文件加载的方式生成路由定义信息 可以看到&#xff0c;RouteDefinitionRepository继承了两个父接口&#xff0c;分别为RouteDefinitionLocator和RouteDefinitionWriter&#xff0c;RouteDefinitionLocator定…

Java并发知识点

文章目录1. start()和run()方法的区别&#xff1f;2. volatile关键字的作用&#xff1f;使用volatile能够保证&#xff1a;防止指令重排3. sleep方法和wait方法有什么区别&#xff1f;sleep()方法4. 如何停止一个正在运行的线程&#xff1f;方法一&#xff1a;方法二&#xff1…

MindFusion Diagramming for Java, 最新版 Crack

Diagramming for Java, V4.6.1 A unique Java Swing library for any type of flowchart.您需要的每一个图表功能 图表、方案、图形、网络、算法、树、图表 - 所有这些都是使用 MindFusion Diagramming for Java 工具快速轻松地构建的。结果令人着迷。 Java Dagram 库&#xff…

论文阅读 | Real-Time Intermediate Flow Estimation for Video Frame Interpolation

前言&#xff1a;ECCV2022 快速插帧方法 Real-Time Intermediate Flow Estimation for Video Frame Interpolation 引言 进行视频插帧目前比较常见的方法是基于光流法&#xff0c;分为两个步骤&#xff1a;1.通过光流对齐输入帧&#xff0c;融合对齐的帧 光流并不能直接同于…

CS224W课程学习笔记(三):DeepWalk算法原理与说明

引言 什么是图嵌入&#xff1f; 图嵌入&#xff08;Graph Embedding&#xff0c;也叫Network Embedding&#xff09; 是一种将图数据&#xff08;通常为高维稠密的矩阵&#xff09;映射为低微稠密向量的过程&#xff0c;能够很好地解决图数据难以高效输入机器学习算法的问题。…

arxiv2017 | 用于分子神经网络建模的数据增强 SMILES Enumeration

论文标题&#xff1a;SMILES Enumeration as Data Augmentation for Neural Network Modeling of Molecules论文地址&#xff1a;https://arxiv.org/abs/1703.07076代码地址&#xff1a;https://github.com/Ebjerrum/SMILES-enumeration一、摘要摘要中明显提出&#xff1a;先指…

TCP/IP网络编程——多播与广播

完整版文章请参考&#xff1a; TCP/IP网络编程完整版文章 文章目录第 14 章 多播与广播14.1 多播14.1.1 多播的数据传输方式以及流量方面的优点14.1.2 路由&#xff08;Routing&#xff09;和 TTL&#xff08;Time to Live,生存时间&#xff09;&#xff0c;以及加入组的办法14…

STM32开发(11)----CubeMX配置独立看门狗(IWDG)

CubeMX配置独立看门狗&#xff08;IWDG&#xff09;前言一、独立看门狗的介绍二、实验过程1.STM32CubeMX配置独立看门狗2.代码实现3.硬件连接4.实验结果总结前言 本章介绍使用STM32CubeMX对独立看门狗定时器进行配置的方法。门狗本质上是一个定时器&#xff0c;提供了更高的安…

华为云计算之容灾技术

容灾是物理上的容错技术&#xff0c;不是逻辑上的容错同步远程复制&#xff1a;主备距离≤200km&#xff0c;只有在主备设备上都写成功&#xff0c;才会告诉主机写成功&#xff0c;不会丢失数据异步远程复制&#xff1a;主备距离&#xff1e;200km&#xff0c;只要主设备上写成…

掌握MySQL分库分表(二)Mysql数据库垂直分库分表、水平分库分表

文章目录垂直分表拆分方法举例垂直分库水平分表水平分库小结垂直角度&#xff08;表结构不一样&#xff09;水平角度&#xff08;表结构一样&#xff09;垂直分表 需求&#xff1a;商品表字段太多&#xff0c;每个字段访问频次不⼀样&#xff0c;浪费了IO资源&#xff0c;需要…

标题标题标题

图床&#xff08;Typora uPic/PicGo 七牛云&#xff09; 图床&#xff08;Typora uPic/PicGo 七牛云&#xff09; 笔者平时使用 Typora 编写 markdown 文档&#xff0c;文档中常常会放置图片&#xff0c;如果文档不需要分享的话&#xff0c;其实讲图片存放在本地就可以了…

SpringCloud alibaba-Sentinel服务降级策略

文章目录RT&#xff1a;异常比例&#xff1a;异常数&#xff1a;RT&#xff1a; 平均响应时间 (DEGRADE_GRADE_RT)&#xff1a;当 1s 内持续进入 N 个请求&#xff0c;对应时刻的平均响应时间&#xff08;秒级&#xff09;均超过阈值&#xff08;count&#xff0c;以 ms 为单位…

一文吃透 Spring 中的IOC和DI(二)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【前端八股文】浏览器系列:单进程与多进程、浏览器进程、异步、事件循环、同源策略、输入URL回车后、TCP三次挥手四次握手

文章目录概述单进程VS多进程浏览器进程主要分为异步场景事件循环同源策略与跨域问题输入URL回车后过程URL几大部分TCP连接与释放TCP三次握手TCP四次挥手参考本系列目录&#xff1a;【前端八股文】目录总结 是以《代码随想录》八股文为主的笔记。详情参考在文末。 代码随想录的博…

AI又进化了,突破性革命来了

大家好&#xff0c;我是 Jack。 2023 年&#xff0c;AI 真的杀疯了。短短不到一年的时间&#xff0c;当我们还在感慨 AI 一键生成的二次元画作精美万分的时候&#xff0c;它已经进化到了写实美照也能手到擒来的地步。 更多的效果&#xff0c;可以看刚刚发布的视频&#xff0c;…

Java爬虫系列 - 爬虫补充内容+ElasticSearch展示数据

一&#xff0c;定时任务Cron表达式Component public class TaskTest {Scheduled(cron "0/5 * * * * *") // 从0秒开始&#xff0c;每个五秒 执行一次 { 秒 分 时 天 月 周 }public void test(){System.out.println("定时任务执行了");} }二&#xff0c;网…

第一章 初识 Spring Security

第一章 初识 Spring Security 1、权限管理 权限管理 基本上涉及到用户参与的系统都要进行权限管理&#xff0c;权限管理属于系统安全的范畴&#xff0c;权限管理实现了对用户访问系统的控制&#xff0c;按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资…

【白话科普】聊聊网络架构变革的关键——SDN

最近二狗子在网上冲浪的时候&#xff0c;不小心将 CDN 搜索成了 SDN&#xff0c;结果跳出来了一大堆相关的知识点。 好学的二狗子当然不会随随便便糊弄过去&#xff0c;于是认认真真学习了好久&#xff0c;终于了解了 SDN 是什么。 原来&#xff0c;SDN 的全称是 Software De…

第十一届“泰迪杯”数据挖掘挑战赛携“十万”大奖火热来袭

第十一届“泰迪杯”数据挖掘挑战赛 竞赛组织 主办单位&#xff1a; 泰迪杯数据挖掘挑战赛组织委员会 承办单位&#xff1a; 广东泰迪智能科技股份有限公司 人民邮电出版社 协办单位&#xff1a; 重庆市工业与应用数学学会、广东省工业与应用数学学会、广西数学学会、河北省工业…