当前位置: 首页 > news >正文

《基于FPGA的便携式PWM方波信号发生器》论文分析(三)——数码管稳定显示与系统调试

一、论文概述

        基于FPGA的便携式PWM方波信号发生器是一篇由任青颖、庹忠曜、黄洵桢、李智禺和张贤宇 等人发表的一篇期刊论文。该论文主要研究了一种新型的信号发生器,旨在解决传统PWM信号发生器在移动设备信号调控中存在的精准度低和便携性差的问题 。其基于现场可编程门阵列(FPGA)技术,设计了一款便携式PWM信号发生器。该设备能够实现占空比以1%的步长可调,频率通过四个按键分别控制实现100 Hz、1 kHz、10 kHz、100 kHz的四个频率脉宽可调的方波信号发生器。系统能够以10 μs的最小分辨率在数码管上进行显示 。对于电子工程和信号处理领域的专业人士提供了一种新的解决方案,有助于提高信号发生器的性能和便携性 。

二、数码管稳定显示

          由于脉宽测量过程中所测量的为所在时刻时的测量脉冲个数,其属于始终变化的动态值,若将其直接显示,数码管的数据会以时钟信号的频率进行跳变。为确保数据的稳定与准确,需保证所显示的数据为输出信号下降沿那一刻时的测量信号个数,即需要对测量数据进行稳定处理,其数码管稳定显示电路图如图6所示:

        由于FD4CE仅在输入上升沿时工作,将输出信号F进行翻转得到FEI,原有的F下降沿即成了FEI的上升沿,此时的Q0、Q1、Q2、Q3被置为输出信号高电平截止时的测量信号个数,将OUT19至OUT0按照从高位到低位的顺序排序即可实现在数码管上的稳定输出。

四、系统性能调试

        依照上述原理搭建可控门电路,对信号产生功能与信号检测功能进行调试检测:先通过占空比按键将占空比调制至所需数据,观察数码管显示;再调制信号频率开关,观察数码管显示;最终调节多信号转换开关,用示波器观察其产生信号,其中50%占空比下脉宽测量实物图如图7所示:

        在四种不同频率的情况下,信号发生器的数码管显示均稳定无误。但在实际的加减调控测试过程中,偶尔存在波动一次开关,同时进行多次加减的情况,根据多次测试我们发现:该情况与按键波动速率存在一定关联,拨动速率越快,该情况出现的概率与跳动的幅度越小,反之则越大。

五、问题分析与改善

        对便携式信号发生器的所有元器件进行逐一检测,发现占空比跳动的根源在于按键开关自身闭合的不灵敏。当其从低电平置为高电平(即按键操作一次)时,应该仅有一次上升沿,其如图8a所示;但因技术以及操作失误等原因,按键开关在实际操作时存在抖动现象,即在短时间内产生多次上升沿,其如图8b所示:

        依照上述设计,可控门电路每捕获一次占空比按键的上升沿,其自身即进行一次相应功能。其中置数功能默认调整至50%,故而在实际操作并无明显变化,而当捕获到多次加减上升沿时,占空比即一次进行多次跳动,即出现了4.1所述之问题。

        为尽可能减少此类因硬件自身缺陷,而对便携式信号发生器性能的影响,特对按键信号进行消抖处理,将按键输入的电平信号置于时钟信号之后,保证系统所读取的仅为已稳定后的加减值,其电路设计如图9所示:

        FDC作为D型触发器,其与加减信号和置数信号相连,将其延迟一个输入周期信号的周期时间,使模100可逆置数模块无法读取抖动部分的信号电平,从而实现对数控模块的消抖。

六、实际信号检测

        将修改后的便捷式信号发生器接入示波器,针对其加减数控开关进行信号测试,将四个频率下的占空比分别调节至30%、50%、70%,其示波器PWM波检测图像如图10所示:

        每进行一次“+”“-”按键调控,占空比分别增加或减少1%,上述问题得到完美解决,并由示波器检测数据可知,该便携式PWM信号发生器的输出信号稳定且精准,并没有出现明显失真,且实际性能满足系统电气指标所需,该便携式信号发生器性能良好。

        围绕FPGA进行相关电路设计,并根据实物情况进行相关改进,可通过频率按键开关组实现PWM波,并可通过“+”“-”按键与一键置位开关,对占空比进行相关调控。同时,它能够测量自身所产生的信号以及外界输入信号的频率与占空比,并在数码管上的最小分辨率进行显示。经过标准示波器的信号检测可知该便携式PWM信号发生器的输出信号稳定且精准,并没有出现明显失真,具有精度高、便携性好、性能稳定的优点。

七、代码示例分析

        此处提供一个基于FPGA的便携式PWM方波信号发生器的示例代码的大致框架和分析。这个示例代码将使用Verilog HDL编写,这是FPGA设计中常用的硬件描述语言。

module PWM_Generator(input clk,          // 时钟信号input rst_n,        // 复位信号,低电平有效input [15:0] freq,  // 频率控制输入input [15:0] duty,  // 占空比控制输入output reg pwm_out  // PWM输出
);// 定义参数
parameter CLOCK_FREQ = 50_000_000;  // FPGA时钟频率
parameter MAX_COUNT = CLOCK_FREQ / 100;  // 最大计数器值// 计数器变量
reg [31:0] counter = 0;
reg [31:0] period = 0;
reg [31:0] high_time = 0;// 计算周期和高电平时间
always @(posedge clk or negedge rst_n) beginif (!rst_n) begincounter <= 0;pwm_out <= 0;end else begincounter <= counter + 1;if (counter >= period) begincounter <= 0;pwm_out <= ~pwm_out;  // 切换输出状态endend
end// 根据频率和占空比更新周期和高电平时间
always @(posedge clk) beginif (counter == 0) beginperiod <= (CLOCK_FREQ / (freq + 1)) - 1;  // 计算周期high_time <= (period * duty) / 100;  // 计算高电平时间end
endendmodule

为了使基于FPGA的PWM方波信号发生器更加复杂和功能丰富,我们可以考虑添加以下功能:

  1. 可配置的频率和占空比:允许通过外部输入动态调整频率和占空比。
  2. 多位频率和占空比控制:使用更多的位数来控制频率和占空比,以提高分辨率。
  3. 多位输出:生成多个PWM通道,每个通道可以独立控制。
  4. 同步和异步复位:提供同步和异步复位选项,以提高系统的灵活性和可靠性。
  5. 死区时间控制:在PWM波形中添加死区时间,以防止短路和电磁干扰。
  6. 中断和事件标志:在特定的PWM事件(如周期结束)时生成中断或事件标志。
  7. 可编程输出极性:允许用户选择PWM输出的高电平或低电平为活动电平。
  8. 动态调整和实时更新:在运行时动态调整频率和占空比,而不需要复位。

以下是一个扩展的示例代码,实现了上述部分功能:

module PWM_Generator_Advanced(input clk,          // 时钟信号input rst_n,        // 复位信号,低电平有效input sync_rst_n,   // 同步复位信号,低电平有效input [15:0] freq,  // 频率控制输入input [15:0] duty,  // 占空比控制输入input [7:0] channel_enable, // 通道使能控制output reg [7:0] pwm_out  // 多位PWM输出
);// 定义参数
parameter CLOCK_FREQ = 50_000_000;  // FPGA时钟频率
parameter MAX_COUNT = CLOCK_FREQ / 100;  // 最大计数器值// 计数器变量
reg [31:0] counter = 0;
reg [31:0] period = 0;
reg [31:0] high_time = 0;
reg [7:0] high_time_array = 0;// 动态调整频率和占空比
always @(posedge clk or negedge rst_n) beginif (!rst_n) begincounter <= 0;pwm_out <= 0;end else if (!sync_rst_n) begincounter <= 0;pwm_out <= 0;end else begincounter <= counter + 1;if (counter >= period) begincounter <= 0;pwm_out <= pwm_out << 1;  // 左移一位,为下一个通道腾出空间if (channel_enable & (1 << 0)) pwm_out[0] <= ~pwm_out[0];  // 通道0if (channel_enable & (1 << 1)) pwm_out[1] <= ~pwm_out[1];  // 通道1// 继续为其他通道添加逻辑endend
end// 根据频率和占空比更新周期和高电平时间
always @(posedge clk) beginif (counter == 0) beginperiod <= (CLOCK_FREQ / (freq + 1)) - 1;  // 计算周期high_time <= (period * duty) / 100;  // 计算高电平时间high_time_array <= high_time;  // 更新高电平时间数组end
end// 动态调整频率和占空比
always @(posedge clk) beginif (counter == 0) beginperiod <= (CLOCK_FREQ / (freq + 1)) - 1;high_time <= (period * duty) / 100;for (int i = 0; i < 8; i++) beginif (channel_enable & (1 << i)) beginhigh_time_array[i] <= (period * duty) / 100;endendend
endendmodule

        这个扩展的示例代码提供了一个更复杂的PWM信号发生器,支持多位输出和动态调整频率和占空比。在实际应用中,可以根据具体需求进一步扩展和优化。

module Advanced_PWM_Generator(input wire clk,                // 主时钟input wire rst_n,              // 异步复位input wire sync_rst_n,         // 同步复位input wire [15:0] freq,        // 频率控制输入input wire [15:0] duty,        // 占空比控制输入input wire [15:0] phase,       // 相位控制输入input wire [15:0] dead_time,   // 死区时间控制输入input wire [7:0] channel_enable, // 通道使能控制output reg [7:0] pwm_out       // 多位PWM输出
);// 定义参数
parameter CLOCK_FREQ = 50_000_000;  // FPGA时钟频率
parameter MAX_COUNT = CLOCK_FREQ / 100;  // 最大计数器值// 内部变量
reg [31:0] counter = 0;
reg [31:0] period = 0;
reg [31:0] high_time = 0;
reg [31:0] low_time = 0;
reg [31:0] dead_count = 0;
reg [31:0] ramp_up = 0;
reg [31:0] ramp_down = 0;
reg [7:0] pwm_state = 0;// 计算周期、高电平时间和低电平时间
always @(posedge clk or negedge rst_n) beginif (!rst_n) begincounter <= 0;pwm_out <= 0;pwm_state <= 0;end else if (!sync_rst_n) begincounter <= 0;pwm_state <= 0;end else begincounter <= counter + 1;case (pwm_state)0: begin // 斜坡上升if (counter < ramp_up) pwm_out <= pwm_out | (1 << pwm_state);else beginpwm_state <= pwm_state + 1;counter <= 0;endend1: begin // 高电平if (counter < high_time) ;else beginpwm_state <= pwm_state + 1;counter <= 0;endend2: begin // 死区时间if (counter < dead_time) ;else beginpwm_state <= pwm_state + 1;counter <= 0;endend3: begin // 低电平if (counter < low_time) ;else beginpwm_state <= pwm_state + 1;counter <= 0;endend4: begin // 斜坡下降if (counter < ramp_down) pwm_out <= pwm_out & ~(1 << (pwm_state - 1));else beginpwm_state <= 0;counter <= 0;endenddefault: pwm_state <= 0;endcaseend
end// 根据频率、占空比、相位和死区时间更新周期、高电平时间和低电平时间
always @(posedge clk) beginif (counter == 0) beginperiod <= (CLOCK_FREQ / (freq + 1)) - 1;high_time <= (period * duty) / 100;low_time <= period - high_time - dead_time;ramp_up <= (high_time * phase) / 100;ramp_down <= (low_time * phase) / 100;dead_count <= dead_time;end
endendmodule

        这个示例代码提供了一个高度复杂的PWM信号发生器,支持多位输出、相位控制、死区时间和斜坡控制。

相关文章:

《基于FPGA的便携式PWM方波信号发生器》论文分析(三)——数码管稳定显示与系统调试

一、论文概述 基于FPGA的便携式PWM方波信号发生器是一篇由任青颖、庹忠曜、黄洵桢、李智禺和张贤宇 等人发表的一篇期刊论文。该论文主要研究了一种新型的信号发生器&#xff0c;旨在解决传统PWM信号发生器在移动设备信号调控中存在的精准度低和便携性差的问题 。其基于现场可编…...

VsCode 插件推荐(个人常用)

VsCode 插件推荐&#xff08;个人常用&#xff09;...

路由策略与路由控制实验

AR1、AR2、AR3在互联接口、Loopback0接口上激活OSPF。AR3、AR4属于IS-IS Area 49.0001&#xff0c;这两者都是Level-1路由器&#xff0c;AR3、AR4的系统ID采用0000.0000.000x格式&#xff0c;其中x为设备编号 AR1上存在三个业务网段A、B、C&#xff08;分别用Loopback1、2、3接…...

训练的decoder模型文本长度不一致,一般设置为多大合适,需要覆盖最长的文本长度么

在训练解码器模型时,文本长度不一致是常见的情况,需要根据任务的特性和数据集的长度分布来设置合理的最大长度 (max_length)。以下是一些指导原则,帮助你设置合适的最大长度: 1. 是否需要覆盖最长文本长度 覆盖最长文本长度: 如果任务对完整性要求很高(例如生成数学公式、…...

过滤条件包含 OR 谓词,如何进行查询优化——OceanBase SQL 优化实践

这篇博客涉及两个点&#xff0c;一个是 “OR Expansion 改写”&#xff0c;另一个是 “基于代价的改写”。 背景 在写SQL查询时&#xff0c;难以避免在过滤条件中使用 OR 谓词&#xff0c;但其往往会导致索引利用效率下降的问题 。本文将分享如何通过查询改写的2种方式进行优化…...

通过异步使用消息队列优化秒杀

通过异步使用消息队列优化秒杀 同步秒杀流程异步优化秒杀异步秒杀流程基于lua脚本保证Redis操作原子性代码实现阻塞队列的缺点 同步秒杀流程 public Result seckillVoucher(Long voucherId) throws InterruptedException {SeckillVoucher seckillVoucher iSeckillVoucherServi…...

AI产业告别“独奏”时代,“天翼云息壤杯”高校AI大赛奏响产学研“交响乐”

文 | 智能相对论 作者 | 陈泊丞 人工智能产业正在从“独奏”时代进入“大合奏”时代。 在早期的AI发展阶段&#xff0c;AI应用主要集中在少数几个领域&#xff0c;如语音识别、图像处理等。这些领域的研究和开发工作往往由少数几家公司或研究机构即可独立完成&#xff0c;犹…...

Hot100 - 字母异位词分组

Hot100 - 字母异位词分组 最佳思路&#xff1a;排序 时间复杂度&#xff1a; O(nmlogm)&#xff0c;其中 n 为 strs 数组的长度&#xff0c;m 为每个字符串的长度。 代码&#xff1a; class Solution {public List<List<String>> groupAnagrams(String[] strs) …...

力扣hot100-->排序

排序 1. 56. 合并区间 中等 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输…...

【VRChat 全身动捕】VIVE 手柄改 tracker 定位器教程,低成本光学动捕解决方案(持续更新中2024.11.26)

更新 0.0.1&#xff08;2024/11/26&#xff09;&#xff1a; 1.解决了内建蓝牙无法识别、“steamVR 蓝牙不可用” 的解决方案 2.解决了 tracker 虽然建立了连接但是在 steamVR 界面上看不到的问题 3.解决了 VIVE 基站1.0 无法被蓝牙识别 && 无法被 steamVR 搜索到 &…...

【Nginx】核心概念与安装配置解释

文章目录 1. 概述2. 核心概念2.1.Http服务器2.2.反向代理2.3. 负载均衡 3. 安装与配置3.1.安装3.2.配置文件解释3.2.1.全局配置块3.2.2.HTTP 配置块3.2.3.Server 块3.2.4.Location 块3.2.5.upstream3.2.6. mine.type文件 3.3.多虚拟主机配置 4. 总结 1. 概述 Nginx是我们常用的…...

Qt界面篇:QMessageBox高级用法

1、演示效果 2、用法注意 2.1 设置图标 用于显示实际图标的pixmap取决于当前的GUI样式。也可以通过设置icon pixmap属性为图标设置自定义pixmap。 QMessageBox::Icon icon(...

【二叉树】【2.1遍历二叉树】【刷题笔记】【灵神题单】

关注二叉树的三个问题&#xff1a; 什么情况适合自顶向下&#xff1f;什么时候适合用自底向上&#xff1f;一般来说&#xff0c;DFS的递归边界是空节点&#xff0c;什么情况下要额外把叶子节点作为递归边界&#xff1f;在什么情况下&#xff0c;DFS需要有返回值&#xff1f;什…...

Mongo数据库 --- Mongo Pipeline

Mongo数据库 --- Mongo Pipeline 什么是Mongo PipelineMongo Pipeline常用的几个StageExplanation with example:MongoDB $matchMongoDB $projectMongoDB $groupMongoDB $unwindMongoDB $countMongoDB $addFields Some Query Examples在C#中使用Aggreagtion Pipeline**方法一: …...

Adobe Illustrator 2024 安装教程与下载分享

介绍一下 下载直接看文章末尾 Adobe Illustrator 是一款由Adobe Systems开发的矢量图形编辑软件。它广泛应用于创建和编辑矢量图形、插图、徽标、图标、排版和广告等领域。以下是Adobe Illustrator的一些主要特点和功能&#xff1a; 矢量绘图&#xff1a;Illustrator使用矢量…...

javax.xml.ws.soap.SOAPFaultException: ZONE_OFFSET

javax.xml.ws.soap.SOAPFaultException 表示 SOAP 调用过程中发生了错误&#xff0c;并且服务端返回了一个 SOAP Fault。 错误信息中提到的 ZONE_OFFSET 可能指的是时区偏移量。在日期和时间处理中&#xff0c;时区偏移量是指格林威治标准时间 (GMT) 的偏移量。如果服务期望特…...

常用的数据结构

队列(FIFO) 栈(LIFO) 链表 hash表 hash冲突处理 开放式寻址 线性探测 表示依次检查索引为 hash(key) + 1、hash(key) + 2 ... 的位置。i 是冲突后的探查步数。公式:hash(i) = (hash(key) + i) % TableSize二次探查 规则:冲突后探查的步长是平方递增的,例如,检查位置为 hash…...

javaweb-day01-html和css初识

html:超文本标记语言 CSS&#xff1a;层叠样式表 1.html实现新浪新闻页面 1.1 标题排版 效果图&#xff1a; 1.2 标题颜色样式 1.3 标签内颜色样式 1.4设置超链接 1.5 正文排版 1.6 页面布局–盒子 &#xff08;1&#xff09;盒子模型 &#xff08;2&#xff09;页面布局…...

C++11特性(详解)

目录 1.C11简介 2.列表初始化 3.声明 1.auto 2.decltype 3.nullptr 4.范围for循环 5.智能指针 6.STL的一些变化 7.右值引用和移动语义 1.左值引用和右值引用 2.左值引用和右值引用的比较 3.右值引用的使用场景和意义 4.右值引用引用左值及其一些更深入的使用场景分…...

基于Springboot的心灵治愈交流平台系统的设计与实现

基于Springboot的心灵治愈交流平台系统 介绍 基于Springboot的心灵治愈交流平台系统&#xff0c;后端框架使用Springboot和mybatis&#xff0c;前端框架使用Vuehrml&#xff0c;数据库使用mysql&#xff0c;使用B/S架构实现前台用户系统和后台管理员系统&#xff0c;和不同级别…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统&#xff0c;支持多语言对话&#xff08;如 中文&#xff0c;英文&#xff0c;日语&#xff09;&#xff0c;语音情感&#xff08;如 开心&#xff0c;悲伤&#xff09;&#x…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看&#xff0c;后端SQL查询确实返回了数据&#xff0c;但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离&#xff0c;并且ai辅助开发的时候&#xff0c;很容易出现前后端变量名不一致情况&#xff0c;还不报错&#xff0c;只是单…...