PWM 呼吸灯实验

news/2024/5/19 16:10:37/文章来源:https://blog.csdn.net/weixin_45090728/article/details/130116869

PWM 呼吸灯实验

FPGA实现一个PWM模块(硬件)来控制灯的亮灭。

实验原理

PWM本质上就是一个输出脉冲的硬件,通过改变一个周期高电平(占空比)的时间来对其他的硬件进行控制,比如电机。
呼吸灯的实现利用了人眼的视觉特性,控制灯亮和暗的间隔时间就形成了对灯亮度的调节。
通过一个N比特的计数器(溢出相当于从0开始)和一个值就可以实现一个占空比可调的脉冲输出。

实验步骤

  1. 设计PWM模块
  2. 用硬件描述语言实现设计
  3. 查看硬件设计,添加管脚约束和时钟约束
  4. 本地仿真
  5. 上板验证

实验记录

  1. 设计PWM模块
信号名称方向说明
clkin时钟输入
rstin异步输入复位,高有效
periodinPWM 脉宽周期(频率)控制。实际是每次计数的步进值,根据系统输入时钟可以计算出pwm输出频率
dutyin占空比,小于该值时输出低电平,否则输出高电平
pwm_outoutpwm输出
  1. 用硬件描述语言实现设计
    ax_pwm.v
`timescale 1ns / 1ps
module ax_pwm
#(parameter N = 16
)
(input clk,input rst,input [N-1:0] period,input [N-1:0] duty,output pwm_out
);reg[N-1:0] period_r;
reg[N-1:0] duty_r;
reg[N-1:0] period_cnt;
reg pwm_r;assign pwm_out = pwm_r;always @(posedge clk or posedge rst)
beginif(rst==1)beginperiod_r <= {N{1'b0}};duty_r <= {N{1'b0}};endelsebeginperiod_r <= period;duty_r <= duty;end
endalways @(posedge clk or posedge rst)
beginif(rst==1)period_cnt <= {N{1'b0}};elseperiod_cnt <= period_cnt + period_r;
endalways @(posedge clk or posedge rst)
beginif(rst==1)beginpwm_r <= 1'b0;endelsebeginif(period_cnt >= duty_r)pwm_r <= 1'b1;elsepwm_r <= 1'b0;end
endendmodule

PWM测试模块

`timescale 1ns / 1psmodule pwm_test(input  sys_clk_p,    // 时钟是一个200MHz的差分时钟input  sys_clk_n,input  rst_n,        // 复位由一个按键来控制,按键默认状态为高,所以低复位output wire led          // 输出给led
);
localparam CLK_FREQ = 200 ; //200MHz,周期为 1s/200MHz = 1/200 us
localparam US_COUNT = CLK_FREQ ; //1 us counter,200个时钟周期是1us 
localparam MS_COUNT = CLK_FREQ*1000 ; //1 ms counter  1个ms的周期计数localparam DUTY_STEP = 32'd100000 ; //duty step, 占空比调整大小,单次调整 100000/2^32 = 0.000000000232
localparam DUTY_MIN_VALUE = 32'h6fffffff ; //duty minimum value, 最小占空比 0.437
localparam DUTY_MAX_VALUE = 32'hffffffff ; //duty maximum value, 最大占空比 0.999localparam IDLE = 0; //IDLE state 
localparam PWM_PLUS = 1; //PWM duty plus state 
localparam PWM_MINUS = 2; //PWM duty minus state 
localparam PWM_GAP = 3; //PWM duty adjustment gapwire pwm_out; //pwm output 
reg[31:0] period; //pwm step value 
reg[31:0] duty; //duty value 
reg pwm_flag ; //duty value plus and minus flag, 0: plus; 1: minusreg[3:0] state; 
reg[31:0] timer; //duty adjustment counter 该测试模块计数的assign led = ~pwm_out ; //led low activewire clk;
// 差分转单端
IBUFDS IBUFDS_inst(.O(clk),.I(sys_clk_p),.IB(sys_clk_n)
);always@(posedge clk or negedge rst_n) 
begin if(rst_n == 1'b0) begin  // 复位,设置初始值period <= 32'd0; timer <= 32'd0; duty <= 32'd0; pwm_flag <= 1'b0 ; state <= IDLE; endelse case(state) IDLE: begin // N位计数器,CLK Hz的时钟(周期1/CLK s),要输出n Hz的PWM波,PWM周期为1/n s,要在一个PWM周期计数完一轮,而一个周期会计数((1/n)/(1/CLK))次//  2^N/((1/n)/(1/CLK)) = 2^32*n/CLK  //  这个地方的时钟写的50M,PWM是800Hz的,周期0.00125s。period <= 32'd17179; //The pwm step value, pwm 200Hz(period = 200*2^32/50000000) state <= PWM_PLUS; duty <= DUTY_MIN_VALUE; end PWM_PLUS : begin if (duty > DUTY_MAX_VALUE - DUTY_STEP) //if duty is bigger than DUTY MAX VALUE minus DUTY_STEP , begin to minus duty value begin pwm_flag <= 1'b1 ; duty <= duty - DUTY_STEP ; end else begin pwm_flag <= 1'b0 ; duty <= duty + DUTY_STEP ; end state <= PWM_GAP ; endPWM_MINUS : begin if (duty < DUTY_MIN_VALUE + DUTY_STEP) //if duty is little than DUTY MIN VALUE plus duty step, begin to add duty value begin pwm_flag <= 1'b0 ; duty <= duty + DUTY_STEP ; end else begin pwm_flag <= 1'b1 ;duty <= duty - DUTY_STEP ; end state <= PWM_GAP ; end PWM_GAP: begin if(timer >= US_COUNT*100) //adjustment gap is 100us begin if (pwm_flag) state <= PWM_MINUS ; else state <= PWM_PLUS ; timer <= 32'd0; end else begin timer <= timer + 32'd1; end enddefault: begin state <= IDLE; end endcase
endax_pwm
#(
.N(32)
)
ax_pwm_m0(.clk(clk),.rst(~rst_n),.period(period),.duty(duty),.pwm_out(pwm_out)
);endmodule
  1. 查看硬件设计,添加管脚约束和时钟约束
    约束文件
set_property PACKAGE_PIN AE15 [get_ports led]
set_property PACKAGE_PIN AE14 [get_ports rst_n]
set_property PACKAGE_PIN AE5 [get_ports sys_clk_p]
set_property IOSTANDARD LVCMOS33 [get_ports led]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD DIFF_SSTL12 [get_ports sys_clk_p]
create_clock -period 5.000 -name sys_clk_p -waveform {0.000 2.500} [get_ports sys_clk_p]
  1. 本地仿真
    激励文件
`timescale 1ns / 1psmodule pwm_test_tb;
// Inputs
reg sys_clk_p;
wire sys_clk_n;
reg rst_n;
wire led ;// Instantiate the Unit Under Test (UUT)
pwm_test uut (.sys_clk_p(sys_clk_p), 		.sys_clk_n(sys_clk_n), 	.rst_n		(rst_n),.led       (led)
);initial begin// Initialize Inputssys_clk_p = 0;rst_n = 0;// Wait 100 ns for global reset to finish#100;rst_n = 1;      endalways #2.5 sys_clk_p = ~ sys_clk_p;   //5ns一个周期,产生200MHz时钟源assign sys_clk_n = ~ sys_clk_p;endmodule

这里的PWM周期为1.25ms,和前面的分析相符。
在这里插入图片描述

  1. 上板验证
    加载后会产生类似流水灯的效果。

实验总结

  1. 时钟很重要,是硬件系统的心跳,有了时钟硬件才可以动起来。如果PWM模块没有时钟输入的话,就无法被驱动,无法正常工作。另外设计的时候不考虑时钟,将会无从下手。
  2. 逻辑调试和软件调试虽然形式有所不一样,但本质都是相同的,需要一级一级的分析问题出在哪里,不能慌张。
  3. 本地调试很有必要,可以看到更详细的信号,有利于找出问题。

问题记录

  1. 时序约束没让添加时钟的约束,不知道什么原因,手动添加。
  2. 上板的时候流水灯没亮,本地仿真发现led是一个蓝色的线,发现原因是少了一行assign语句,没把pwm的输出接出去。

参考资料

  1. PWM原理 PWM频率与占空比详解
  2. Xilinx 7系列SelectIO结构之IO标准和端接匹配(三)
  3. XILINX 原语的使用之 IBUFDS 差分转单端、OBUFDS 单端转差分

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

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

相关文章

ChatGPT实现语义分析情感分类

语义分析情感分类 我们从开源社区找到了中科院谭松波博士整理的携程网酒店评论数据集(https://raw.githubusercontent.com/SophonPlus/ChineseNlpCorpus/master/datasets/ChnSentiCorp_htl_all/ChnSentiCorp_htl_all.csv)。一共七千余条数据&#xff0c;包括 label 和 review …

vue封装公共组件库并发布到npm库详细教程

vue组件封装的原理&#xff1a;利用vue框架提供的api: Vue.use( plugin )&#xff0c;我们需要把封装好组件的项目打包成vue库&#xff0c;并提供install方法&#xff0c;然后发布到npm中。Vue.use( plugin )的时候会自动执行插件中的install方法。 一、组件库代码目录 目录…

【Python_Opencv图像处理框架】边缘检测、轮廓检测、图像金字塔

写在前面 本篇文章是opencv学习的第四篇文章&#xff0c;主要讲解了边缘及轮廓检测的主要操作&#xff0c;并对两种图像金字塔简单的介绍了一下&#xff0c;作为初学者&#xff0c;我尽己所能&#xff0c;但仍会存在疏漏的地方&#xff0c;希望各位看官不吝指正&#x1f60d; …

C语言 sizeof, size_t, strlen

C语言 sizeof, size_t, strlen 文章目录 C语言 sizeof, size_t, strlen一. sizeof1.1 返回结构体长度 二. size_t三. sizeof 和 strlen 一. sizeof 返回一个结构体或者类型所占的内存字节数 1.1 返回结构体长度 这里我编写了2个结构体&#xff0c;区别在于数组问题 #include …

基于本地知识构建简易的chatPDF

Langchain chatglm-6b 文章目录 Langchain chatglm-6b前言一、实验记录1.1 环境配置1.2 代码理解1.3 补充内容 二、总结 前言 介绍&#xff1a;一种利用 ChatGLM-6B langchain 实现的基于本地知识的 ChatGLM 应用 Github: https://github.com/imClumsyPanda/langchain-Chat…

《个人博客部署上线教程一》Halo搭建个人博客网站

Halo搭建个人博客网站 一、docker部署Halo 目前测试了两种方法安装Halo&#xff0c;第一种是使用Jar包安装:提供JAR包资源&#xff0c;不过因为使用jar包部署需要Java11才可以&#xff0c;我本机使用的是Java8&#xff0c;所以暂时不做调整。第二种是通过docker安装。 1.1 启…

if条件语句

if条件语句 条件测试 test 测试表达式是否成立&#xff0c;若成立返回0&#xff0c;否则返回其他数值 格式1 &#xff1a;test 条件表达式&#xff1b;格式2 &#xff1a;[ 条件表达式 ] echo $?参数作用-d测试是否为目录 (Directory)-e测试目录或文件是否存在(Exist)-f测…

【java笔记】java多线程

目录 一、概念 1.1 什么是进程&#xff1f; 1.2 什么是线程&#xff1f; 1.3 什么事多线程&#xff1f; 1.4 进程和线程的关系 二、线程对象的生命周期 三、实现线程有两种方式 3.1 继承 java.lang.Thread&#xff0c;重写 run方法 3.2 实现 java.lang.Runnable 接口…

八、vue_options之computed、watch属性选项

一、computed计算属性使用 &#xff08;1&#xff09;复杂data的处理方式 &#xff08;2&#xff09;computed 计算属性 computed计算属性初体验&#xff1a; 在我们通过Vue调用createApp方法传入一个对象的时候&#xff0c;我们之前写了data属性、methods属性&#xff0c;这…

HTB-Time

HTB-Time 信息收集80端口 立足pericles -> root 信息收集 80端口 有两个功能&#xff0c;一个是美化JSON数据。 一个是验证JSON&#xff0c;并且输入{“abc”:“abc”}之类的会出现报错。 Validation failed: Unhandled Java exception: com.fasterxml.jackson.core.JsonPa…

低代码是开发的未来,还是只能解决边角问题的鸡肋?

随着互联网行业寒冬期的到来&#xff0c;降本增效、开源节流几乎成为了全球互联网厂商共同的应对措施&#xff0c;甚至高薪酬程序员的“35岁危机”一下子似乎变成了现实。程序员的高薪吸引了各行各业的“跨界选手”&#xff0c;是编程门槛降低了吗&#xff1f;不全是&#xff0…

Linux Ansible管理变量、管理事实、管理机密

目录 Ansible变量 变量定义范围 变量类型 定义变量并引用 事实变量与魔法变量 事实变量 魔法变量 Ansible加密 ansible-vault参数 ansible-vault举例 Ansible变量 Ansible支持利用变量来存储值&#xff0c;并且可以在Ansible项目的所有文件中重复使用这些值 变量可能…

Hadoop3.2.4+Hive3.1.2+sqoop1.4.7安装部署

目录 一、软件包 二、JDK部署 1.JDK解压 2.设置环境变量 3.环境验证 4.分发JDK相关文件至Node_02、Node_03 5.环境生效 三、Zookeeper部署 1.Zookeeper解压 2.Zookeeper配置 3.创建myid文件 4.设置环境变量并添加映射 5.分发ZooKeeper 相关文件至Node_02、Node_0…

Qt — Graphics/View框架

文章目录 前言一、Qt图形系统介绍二、Graphics/View框架 前言 Qt的Graphics/View框架被用来存放、显示二维图形元素&#xff0c;处理那些对图形元素进行操作的交互命令。 一、Qt图形系统介绍 Qt 应用程序的图形界面包含各种控件&#xff0c;比如窗口、按钮、滚动条等。所有这…

【单目标优化算法】沙猫群优化算法(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

4月24日~4月26日学习总结

一&#xff0c;刷题目情况&#xff0c;已经完成了8道题目&#xff0c;对于其中一些题目做一下题解。 这个题目的意思是找到的两个位置l和r&#xff0c;为了做到这个数组的l到r的子数组经过排序后&#xff0c;会变成输入的另外一个数组&#xff0c;这个题目的思路就是首先找到在…

服务(第十篇)Nginx和tomcat反向代理(动静分离)

正向代理&#xff1a; 当用户想访问某一网址时&#xff0c;用户先访问代理服务器&#xff0c;然后由代理服务器向目标网址发送请求最终将数据返回代理服务器&#xff0c;最后代理服务器将数据返回给用户这一过程我们称之为正向代理。 反向代理&#xff1a;基本流程是与正向代理…

(04)基础强化:接口,类型转换cast/convert,异常处理,传参params/ref/out,判断同一对象

一、复习 1、New的截断是指什么&#xff1f; new除了新开空间创建初始化对象外&#xff0c;还有一个隐藏父类同名方法的作用。 当子类想要隐藏父类同名的方法时用new&#xff0c;用了new后父类同名方法将到此为止&#xff0c;后面 继承的…

centos7部署FastDFS服务

一、安装需要的相关依赖 yum -y install make cmake gcc gcc-c 因为我的服务器已经安装了gcc&#xff0c;所以略去 使用gcc -v查看版本 yum -y install zip unzip 安装性能事件通知库 yum -y install libevent 安装nginx依赖 yum -y install libevent yum -y install zli…

最新版TensorFlow的GPU版本不支持原生Windows系统(大坑预警)

一、前言 首先需要说明&#xff0c;按照官方中文文档安装是无法正常检测到GPU的。因为TensorFlow 2.10是支持原生Windows系统GPU环境的最后版本&#xff0c;默认安装的版本都比较高。 中文文档没有说明&#xff0c;英文文档是有提到的&#xff1a; &#xff08;我在GitHub上找…