09 呼吸灯

呼吸灯简介

呼吸灯实际展示的效果就是一个 LED 灯的亮度由亮到暗,再由暗到亮的变化过程,并且该过程是循环往复的,像呼吸一样那么有节奏。 呼吸灯通常是采用 PWM(Pulse Width Modulation,即脉冲宽度调制) 的方式实现,在 PWM 频率固定的情况下,通过调整其占空比来控制 LED 灯亮度的变化。
在固定周期的 PWM 信号下,如果其占空比为 0,则 LED 灯不亮;如果其占空比为100%,则 LED 灯最亮。将占空比从 0 到 100%,再从 100%到 0 不断变化,就可以实现 LED 灯的“呼吸”效果,PWM 占空比调节示意图如下所示:
在这里插入图片描述

PWM信号的产生

可以使用1个寄存器和一个比较值来控制 PWM 信号的产生,寄存器进行周期计数,控制 PWM 的周期,在计数器周期计数过程中同时将计数值与比较值比较,当周期计数器的值小于比较寄存器时输出低电平,否则输出高电平,此时通过调节比较值便可调节 PWM 占空比,调节周期计数器的最大计数值便可调节 PWM 的周期,PWM 信号产生原理如下图所示:
在这里插入图片描述

原理图

LED0 到 LED3 这 4 个发光二极管的阴极分别连到 S8050(NPN 三极管)的集电极上,阳极都与 3.3V 电压相连,三极管的基极分别与 FPGA 相连,这是由于 FPGA 的 IO 口的电压只有 1.5V,电压较低,所以此处连接三极管是为了起到放大电压的作用。这样就可以通过改变三极管的状态来控制 LED 的亮灭。当 FPGA 输出到为高电平时,三极管导通,LED 灯亮;当 FPGA 输出到为低电平时,三极管截止,LED 灯灭。
在这里插入图片描述
在这里插入图片描述
此实验中只用到了LED0

系统框图

系统框图如下,包括两部分,分别是产生PWM信号的PWM模块和控制PWM占空比的呼吸灯模块
在这里插入图片描述

编写代码

PWM信号生成模块

PWM信号生成模块包含一个周期计数器和一个比较值,比较值通过模块外部输入的占空比结合PWM周期转换得到(这里由呼吸灯模块进行占空比控制),模块代码如下:

`timescale 1ns / 1ns

module pwm_generate
(
	input sys_clk,							//系统时钟
	input sys_rst_n,						//系统复位,低电平有效

	input [31:0] period,					//PWM周期
	input [31:0] duty_cycle,				//PWM占空比

	output pwm_out							//输出的PWM信号
);

//PWM周期
wire [31:0] pwm_period;
//PWM比较值
wire [31:0] pwm_compare;
//周期计数器,用于控制PWM周期
reg [31:0] count;

//PWM周期,不能小于1
assign pwm_period = (period < 1) ? 1 : period;
//将PWM占空比转换为比较值
assign pwm_compare = (duty_cycle < period) ? (period - duty_cycle) : 0;

//周期计数器的值小于比较寄存器时输出低电平,否则输出高电平
assign pwm_out = (count < pwm_compare) ? 0 : 1;

//进行周期计数,用于控制PWM输出周期
always @(posedge sys_clk) begin
	if(!sys_rst_n)
		count <= 0;
	else if(count < (period - 1))
		count = count + 1;
	else
		count <= 0;
end

endmodule

PWM信号生成模块仿真激励代码

PWM信号生成模块仿真激励代码很简单,就是在周期产生时钟信号的同时调整PWM占空比即可,代码如下:

`timescale 1ns / 1ns	//仿真单位/仿真精度

module tb_pwm_generate();

reg sys_clk;					//时钟
reg sys_rst_n;					//复位
reg [31:0] duty_cycle;			//占空比
wire pwm_out;					//PWWM信号

initial begin
	sys_clk = 1'b0;
	sys_rst_n = 1'b0;
	duty_cycle = 0;
	#200
	sys_rst_n = 1'b1;

	//占空比为1
	#1000
	duty_cycle = 1;

	//占空比为2
	#1000
	duty_cycle = 2;

	//占空比为3
	#1000
	duty_cycle = 3;

	//占空比为4
	#1000
	duty_cycle = 4;

	//占空比为5
	#1000
	duty_cycle = 5;

	//占空比为6
	#1000
	duty_cycle = 6;

	//占空比为7
	#1000
	duty_cycle = 7;

	//占空比为8
	#1000
	duty_cycle = 8;

	//占空比为9
	#1000
	duty_cycle = 9;

	//占空比为10
	#1000
	duty_cycle = 10;
end

//产生时钟
always #10 sys_clk = ~sys_clk;

pwm_generate u_tb_pwm_generate_inst (
	.sys_clk(sys_clk),					//系统时钟
	.sys_rst_n(sys_rst_n),				//系统复位,低电平有效

	.period(10),						//PWM周期
	.duty_cycle(duty_cycle),			//PWM占空比

	.pwm_out(pwm_out)					//输出的PWM信号
);

endmodule

呼吸灯模块

呼吸灯模块用于向PWM模块输出一个占空比,内部包含以下几个部分:

  • 一个周期计数器,用于控制PWM占空比调节的间隔
  • 根据占空比调节方向调节占空比
  • 记录占空比调节次数
  • 当占空比连续递增(递减)到指定次数时说明占空比达到最大(最小),此时改变占空比调节方向标志
    完整的代码如下:
`timescale 1ns / 1ns

module breath_led #(
	parameter PWM_PERIOD = 100_000,				//pwm信号的周期
	parameter BREATH_PERIOD = 100_000_000,		//呼吸灯周期
	parameter BRIGHT_LEVEL = 100				//亮度等级
)
(
	input sys_clk,								//系统时钟
	input sys_rst_n,							//系统复位,低电平有效

	output reg [31:0] duty_cycle				//PWM占空比
);

//PWM占空比调节步进,分100个亮度等级进行占空比调节
localparam DUTY_CYCLE_STEP = PWM_PERIOD / BRIGHT_LEVEL;
//PWM占空比调节间隔,分100个亮度等级进行占空比调节
localparam STEP_INTERVAL = BREATH_PERIOD / BRIGHT_LEVEL;

//周期计数器,用于控制PWM占空比调节间隔
reg [31:0] period_count;
//占空比调节次数计数器,用于记录调节占空比的次数
reg [31:0] step_count;
//占空比调节方向控制,为0占空比加,为1占空比减
reg inc_dec_flag;

//进行周期计数,用于控制PWM占空比调节间隔
always @(posedge sys_clk) begin
	if(!sys_rst_n)
		period_count <= 0;
	else if(period_count < (STEP_INTERVAL - 1))
		period_count <= period_count + 1;
	else
		period_count <= 0;
end

//根据占空比调节方向标志进行占空比调节,控制LED亮度
always @(posedge sys_clk) begin
	if(!sys_rst_n)
		duty_cycle <= 0;
	else if(period_count == (STEP_INTERVAL - 1)) begin
		if((inc_dec_flag == 1'b0) && ((PWM_PERIOD - duty_cycle) >= DUTY_CYCLE_STEP))
			duty_cycle <= duty_cycle + DUTY_CYCLE_STEP;
		else if((inc_dec_flag == 1'b1) && (duty_cycle >= DUTY_CYCLE_STEP))
			duty_cycle <= duty_cycle - DUTY_CYCLE_STEP;
	end
end

//记录调节占空比的次数
always @(posedge sys_clk) begin
	if(!sys_rst_n)
		step_count <= 0;
	else if(period_count == (STEP_INTERVAL - 1)) begin
		if(step_count < (BRIGHT_LEVEL - 1))
			step_count <= step_count + 1;
		else
			step_count <= 0;
	end
end

//占空比调节方向控制,为0占空比加,为1占空比减
//当占空比连续递增(递减)到指定次数时说明占空比达到最大(最小),此时改变占空比调节方向标志
always @(posedge sys_clk) begin
	if(!sys_rst_n)
		inc_dec_flag <= 0;
	else if(period_count == (STEP_INTERVAL - 1)) begin
		if(step_count == (BRIGHT_LEVEL - 1))
			inc_dec_flag <= ~inc_dec_flag;
	end
end

endmodule

呼吸灯模块仿真激励代码

呼吸灯模块仿真激励代码非常简单,只需要产生激励时钟即可,代码如下:

`timescale 1ns / 1ns	//仿真单位/仿真精度

module tb_breath_led();

reg sys_clk;					//时钟
reg sys_rst_n;					//复位
wire [31:0] duty_cycle;			//占空比

initial begin
	sys_clk = 1'b0;
	sys_rst_n = 1'b0;
	#200
	sys_rst_n = 1'b1;
end

//产生时钟
always #10 sys_clk = ~sys_clk;

breath_led #(
	.PWM_PERIOD(100),				//pwm信号的周期
	.BREATH_PERIOD(10_000),			//呼吸灯周期
	.BRIGHT_LEVEL(10)				//亮度等级
)
u_tb_breath_led_inst(
	.sys_clk(sys_clk),					//系统时钟
	.sys_rst_n(sys_rst_n),				//系统复位,低电平有效

	.duty_cycle(duty_cycle)				//PWM占空比
);

endmodule

顶层模块

顶层模块主要用于例化PWM生成模块和呼吸灯模块,并将两个模块进行关联,代码如下:

`timescale 1ns / 1ns

module top_breath_led #(
	parameter PWM_PERIOD = 100_000,				//pwm信号的周期
	parameter BREATH_PERIOD = 100_000_000,		//呼吸灯周期
	parameter BRIGHT_LEVEL = 100				//亮度等级
)
(
	input sys_clk,								//系统时钟
	input sys_rst_n,							//系统复位,低电平有效

	output led									//LED
);

//PWM占空比
wire [31:0] duty_cycle;

//例化呼吸灯模块
breath_led #(
	.PWM_PERIOD(PWM_PERIOD),				//pwm信号的周期
	.BREATH_PERIOD(BREATH_PERIOD),			//呼吸灯周期
	.BRIGHT_LEVEL(BRIGHT_LEVEL)				//亮度等级
)
u_breath_led_inst (
	.sys_clk(sys_clk),						//系统时钟
	.sys_rst_n(sys_rst_n),					//系统复位,低电平有效

	.duty_cycle(duty_cycle)					//PWM占空比
);

//例化PWM发生模块
pwm_generate u_pwm_generate_inst (
	.sys_clk(sys_clk),						//系统时钟
	.sys_rst_n(sys_rst_n),					//系统复位,低电平有效

	.period(PWM_PERIOD),					//PWM周期
	.duty_cycle(duty_cycle),				//PWM占空比

	.pwm_out(led)							//PWM,用于控制LED
);

endmodule

顶层模块仿真激励代码

顶层模块仿真激励代码非常简单,只需要产生激励时钟即可,代码如下:

`timescale 1ns / 1ns	//仿真单位/仿真精度

module tb_top_breath_led();

reg sys_clk;					//时钟
reg sys_rst_n;					//复位
wire led;						//LED

initial begin
	sys_clk = 1'b0;
	sys_rst_n = 1'b0;
	#200
	sys_rst_n = 1'b1;
end

//产生时钟
always #10 sys_clk = ~sys_clk;

top_breath_led #(
	.PWM_PERIOD(10),					//pwm信号的周期
	.BREATH_PERIOD(1000),				//呼吸灯周期
	.BRIGHT_LEVEL(10)					//亮度等级
)
u_tb_top_breath_led_inst (
	.sys_clk(sys_clk),					//系统时钟
	.sys_rst_n(sys_rst_n),				//系统复位,低电平有效

	.led(led)							//LED
);

endmodule

约束输入

管脚分配如下:
在这里插入图片描述
XDC 约束语句如下:

#时序约束
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]

#IO 管脚约束
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS15} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U7 IOSTANDARD LVCMOS15} [get_ports sys_rst_n]
set_property -dict {PACKAGE_PIN V9 IOSTANDARD LVCMOS15} [get_ports led]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言实现直接插入排序

直接插入排序 其平均复杂度是 O(n2)&#xff0c;因此应用场景较少。 接插入排序的思路是&#xff1a; 每次处理一个数据&#xff0c;将其插入到一个已经排好序的子序列中&#xff0c;直到数据处理完毕。 下面给出一个动画示例&#xff1a; 这里写图片描述&#xff1a;从上面来…

C#之WPF学习之路(5)

目录 内容控件&#xff08;2&#xff09; TextBlock文字块 TextBox文本框 TextBoxBase基类 TextBox控件 RichTextBox富文本框 ToolTip控件&#xff08;提示工具&#xff09; Popup弹出窗口 Image图像控件 属性成员 事件成员 内容控件&#xff08;2&#xff09; Tex…

基于SSM的车位租赁系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的车位租赁系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

R3F(React Three Fiber)经验篇

之前一直在做ThreeJS方向&#xff0c;整理了两篇R3F&#xff08;React Three Fiber&#xff09;的文档&#xff0c;这是经验篇&#xff0c;如果您的业务场景需要使用R3F&#xff0c;可以参考一下这个文档。下面是目录&#xff0c;按照需求自取。 基础篇 ⬇️ R3F&#xff08;…

港科夜闻|香港科大计划建立北部都会区卫星校园完善科大创新带,发展未来创新科技 未来医药发展及跨学科教育...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大计划建立北部都会区卫星校园完善“科大创新带”&#xff0c;发展未来创新科技、未来医药发展及跨学科教育。香港科大校长叶玉如教授在2月22日的媒体会议上表示&#xff0c;香港科大将在北部都会区建立卫星校园&a…

模型上下文长度达到10000000,又一批创业者完蛋了?

没有疑问&#xff0c;Gemini 1.5 Pro的隆重推出被Sora抢了风头。 社交平台X上OpenAI介绍Sora的第一条动态&#xff0c;现在已经被浏览了超过9000万次&#xff0c;而关于Gemini 1.5 Pro热度最高的一条&#xff0c;来自谷歌首席科学家Jeff Dean&#xff0c;区区123万人。 或许J…

Vue3路由组件练习

Vue3 路由组件练习 演示效果代码分析 安装 vue-router创建路由文件创建路由实例使用 router-link 组件导航 代码实现 index.js 文件App 文件 1. 演示效果 2. 代码分析 2.1. 安装 vue-router 命令&#xff1a;npm i vue-router 应用插件&#xff1a;Vue.use(VueRouter) 2.2…

【Ubuntu】通过网线连接两台电脑以实现局域网连接的方法

有时我们需要将多台计算机连接在一起&#xff0c;以便实现数据共享、资源访问等功能。本文将介绍如何通过网线连接两台运行Ubuntu操作系统的电脑&#xff0c;以便它们能够直接通信&#xff0c;从而实现局域网连接。 1. 准备工作 在开始之前&#xff0c;请准备好&#xff1a; …

车载电子电器架构 —— 基础技术开发概述

车载电子电器架构 —— 基础技术开发概述 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明…

05 EXTI外部中断

一、中断系统 中断系统&#xff1a;管理和执行中断的逻辑结构。中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件——中断源&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继…

Linux配置jdk、tomcat、mysql离线安装与启动

目录 1.jdk安装 2.tomcat的安装&#xff08;开机自启动&#xff09; 3.MySQL的安装 4.连接项目 1.jdk安装 上传jdk安装包 jdk-8u151-linux-x64.tar.gz 进入opt目录&#xff0c;将安装包拖进去 解压安装包 这里需要解压到usr/local目录下&#xff0c;在这里我新建一个文件夹…

普中51单片机学习(DA转换)

DA数模转换 分辨率 分辨率是指输入数字量的最低有效位&#xff08;LSB&#xff09;发生变化时&#xff0c;所对应的输出模拟量&#xff08;电压或电流&#xff09;的变化量。它反映了输出模拟量的最小变化值。 分辨率与输入数字量的位数有确定的关系&#xff0c;可以表示成FS …

FariyGUI × Cocos Creator 3.x 弹窗制作

在fgui里制作一个弹窗 新建一个按钮&#xff0c;作为返回按钮 新建一个标签 做成这个样子 其中包含两个节点&#xff0c;名称分别为title和closeButton 可以阅读fgui的源码window.js得到&#xff0c;closeButton按钮只需要输入名称即可在contentPane设置时自动绑定。 且会…

使用 React 和 MUI 创建多选 Checkbox 树组件

在本篇博客中&#xff0c;我们将使用 React 和 MUI&#xff08;Material-UI&#xff09;库来创建一个多选 Checkbox 树组件。该组件可以用于展示树形结构的数据&#xff0c;并允许用户选择多个节点。 前提 在开始之前&#xff0c;确保你已经安装了以下依赖&#xff1a; Reac…

汇编反外挂

在软件保护领域&#xff0c;尤其是游戏保护中&#xff0c;反外挂是一个重要的议题。外挂通常指的是一种第三方软件&#xff0c;它可以修改游戏数据、操作游戏内存或提供其他作弊功能&#xff0c;从而给玩家带来不公平的优势。为了打击外挂&#xff0c;游戏开发者会采取一系列措…

计算机网络-网络互联

文章目录 网络互联网络互联方法LAN-LAN&#xff1a;网桥及其互连原理使用网桥实现LAN-LAN使用交换机扩展局域网使用路由器连接局域网 LAN-WANWAN-WAN路由选择算法非自适应路由选择算法自适应路由选择算法广播路由选择算法&#xff1a;分层路由选择算法 网络互联 网络互联是指利…

数据存储-文件存储

一、CSV文件存储 csv是python的标准库 列表数据写入csv文件 import csvheader [班级, 姓名, 性别, 手机号, QQ] # 二维数组 rows [[学习一班, 大娃, 男, a130111111122, 987456123],[学习二班, 二娃, 女, a130111111123, 987456155],[学习三班, 三娃, 男, a130111111124, …

Javase补充-Arrays类的常用方法汇总

文章目录 一 . 排序方法二 . 查找方法三 . 判断是否相等的方法四 . 拷贝方法五 . 填充方法 一 . 排序方法 我们第一个要介绍的就是sort方法 这个排序实现的底层逻辑应该是十分复杂的,以我们目前的水平体系应该无法理解,我们今天尝试用我们可以理解的一种排序算法,插入排序来模…

jQuery瀑布流画廊,瀑布流动态加载

jQuery瀑布流画廊&#xff0c;瀑布流动态加载 效果展示 手机布局 jQuery瀑布流动态加载 HTML代码片段 <!-- mediabanner --><div class"mediabanner"><img src"img/mediabanner.jpg" class"bg"/><div class"text&qu…

纽约纳斯达克大屏投放受众群体有哪些-大舍传媒

纽约纳斯达克大屏投放受众群体有哪些-大舍传媒 1. 纳斯达克大屏的概述 纳斯达克大屏是全球金融市场中最出名的电子交易平台之一。作为一个重要的金融信息传递渠道&#xff0c;纳斯达克大屏吸引了来自全球的投资者的目光。在这个巨大的投放平台上&#xff0c;大舍传媒希望为客…