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

news/2024/11/26 19:16:37/

一、论文概述

        基于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信号发生器,支持多位输出、相位控制、死区时间和斜坡控制。


http://www.ppmy.cn/news/1550121.html

相关文章

三种蓝牙架构实现方案

一、蓝牙架构方案 1、hostcontroller双芯片标准架构 手机里面包含很多SoC或者模块&#xff0c;每颗SoC或者模块都有自己独有的功能&#xff0c;比如手机应用跑在AP芯片上&#xff0c;显示屏&#xff0c;3G/4G通信&#xff0c;WiFi/蓝牙等都有自己专门的SoC或者模块&#xff0…

(功能测试)第五章 APP项目测试

熟悉APP项目 模型介绍 更新速度取决于开发模型 上面所说的京东&#xff0c;就是做一次发布一次&#xff0c;传统行业用的是瀑布模型&#xff0c;互联网行业用的是敏捷模型&#xff0c; 瀑布模型就像是瀑布一般&#xff0c;从上到下&#xff0c;上一个环节没有完成下一个环节是没…

牛客周赛69第一题:JAVA

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 小歪有两个整数 a 和 b &#xff0c;他想找到这样一个整数 c &#xff0c;使得这三个整数在经过排序后能成为一个等差数列。 输入描述: 在一行上输入两个整数 a,b(1≦a,b≦106)a,b\left(1 \l…

【失败经验】将算法模型封装为安卓应用

背景&#xff1a;不懂安卓开发&#xff0c;希望能使用大模型编码完成安卓应用生成&#xff0c;调用算法模型进行预测。 模型准备&#xff1a; pip方案安装pcnn&#xff1b; 然后需要将pytorch训练完成的算法模型保存为torchscript模型&#xff0c;然后使用pcnn转换为ncnn的模…

DICOM图像深入解析:为何部分DR/CR图像默认显示为反色?

概述 在数字医学影像处理中,CR(Computed Radiography,计算机放射摄影)和DR(Digital Radiography,数字放射摄影)技术广泛应用于医疗影像获取与分析。然而,临床实践中常常遇到这样一个问题:部分CR/DR图像在默认打开时呈现为反色(即负片效果),需手动反色后才能正常阅片…

【C语言】传值调用与传址调用:深度解析与实现

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;什么是传值调用和传址调用&#xff1f;1. 传值调用&#xff08;Call by Value&#xff09;2. 传址调用&#xff08;Call by Reference&#xff09; &#x1f4af;传值调…

故障排除-------K8s挂载集群外NFS异常

故障排除-------K8s挂载集群外NFS异常 1. 故障现象2. 原因梳理2.1 排查思路2.2 确认yaml内容2.3 创建k8s内的nfs测试2.3.1 创建nfs和svc2.3.2 测试创建pvc2.3.3 测试结果 2.4 NFS服务端故障排除2.4.1 网络阻断排除2.4.2 排除服务状态问题2.4.3 排查NFS权限问题 3. 故障排除 1. …

生成式AI在教育技术中的应用:变革与创新

引言 在过去的几十年中&#xff0c;人工智能技术在教育领域的应用引发了显著的变革&#xff0c;从早期的简单自动化评估系统到现在的个性化学习助手。生成式AI&#xff08;AIGC&#xff09;作为AI领域的重要分支&#xff0c;正在快速进入教育技术的主流&#xff0c;为教育带来…