《FPGA学习》->呼吸灯_fpga呼吸灯_朽木自雕i
呼吸灯,简而言之就像人类呼吸一样,有节奏的让LED灯从:灭->微微亮->微亮->亮->高亮,然后再从:高亮->亮->微亮->微微亮->灭的这样一个过程。...
🍎 与其担心未来,不如现在好好努力。在这条路上,只有奋斗才能给你安全感。你若努力,全世界都会为你让路。呼吸灯,简而言之就像人类呼吸一样,有节奏的让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 //模块结束
仿真波形如下:
![]()
从图中可以看出,运行后的仿真波形与设计需求保持一致,任务完成。
🔥🔥🔥本系列文章持续更新,喜欢的话可以关注收藏~🔥🔥🔥
相关文章
- 网络安全面试复习资料_一青一柠
- 微信小程序开发uni-app_upws软工菜鸡
- 信息服务上线渗透检测网络安全检查报告和解决方案2(安装文件信息泄漏、管理路径泄漏、XSS漏洞、弱口令、逻辑漏洞、终极上传漏洞升级)_漏刻有时
- Java 使用 Redis_qq_33291299
- 【第十六篇】Camunda系列-动态表单_波波烤鸭_camunda表单
- SpringBoot基础入门_全栈测试笔记
- 广州周立功CanTest卡使用教程一_兔云程序
- Selenium4新特性-关联定位策略_大牛测试
- PHP 和 Redis_qq_33291299
- VueJs中如何使用Teleport组件_itclanCoder
- “零”代码改动,静态编译让太乙Stable Diffusion推理速度翻倍_OneFlow深度学习框架
- JAVA练习28_Mikudd3
- mysql之DDL_linab112
- 2022年过去了,我不怀恋它_公众号明天上线
- 零入门容器云实战之测试环境说明、技术支持、网盘资源_码二哥
- 梦想不会亏待任何人!_李肖遥