FPGA综合设计实验:基于PWM脉宽调制的呼吸流水灯设计

目录

一、引言

二、项目准备

1.项目预期目标

2.项目原理及总体实现思路

三、项目模块设计

1.顶层模块

2.按键控制模块

3.呼吸灯模块

4.数码管显示模块

5.二进制转BCD码模块

四、项目测试

1.仿真测试

2.实物测试

五、项目总结

1.选题思考与过程反思

2.设计的具体完成情况详细描述

3.项目可改进之处

4.项目设计心得

参考文献


引言

近年来,FPGA技术的快速发展使得其在数字化系统的设计中扮演着越来越重要的角色,尤其是在嵌入式系统、通信系统和图像处理等领域有广泛的应用。PWM脉宽调制技术是一种常用的电子控制技术,通过调整周期不变的脉冲波形的占空比实现对电路的控制,从而达到精准、稳定的控制效果。呼吸流水灯作为一种极具艺术效果的LED灯光效果,可以产生一种逐渐由暗变明再由明变暗的渐进式变化,能够为现代家居和公共场所提供更加温馨、舒适的氛围。

本次综合设计旨在将FPGA技术和PWM脉宽调制技术相结合,在实验六的基础上扩展,以实现呼吸流水灯灯光效果的控制。通过该课程的学习,我们将学习如何使用FPGA技术实现基于PWM脉宽调制控制LED灯的电路设计,以及如何使用Verilog语言编写控制程序,实现呼吸流水灯灯效的渐变控制。同时,我们还将学习到如何使用Xilinx VIVADO软件进行FPGA硬件电路设计和Verilog代码编写,以及在实际中如何进行调试和优化。

本课程的目标是深入了解FPGA技术和PWM脉宽调制技术的原理和应用,提高其在数字化系统设计中的实践能力和创新能力。

项目准备

1.项目预期目标

以10Hz的频率,点亮实验开发板上的发光二极管LED9~LED0,显示过程中各个点亮的发光二极管的亮度呈现出明暗变化,形似呼吸。SW0 向下系统复位,LED灯全灭。SW0向上,LED呈现呼吸状显示。

分组显示两组不同渐变周期的呼吸灯,Key0控制LED4~LED0显示, KEY1 控制LED9~LED5显示,渐变周期由SW1~SW9输入,同时数码管分别显示2组呼吸灯对应周期数。

完成呼吸灯的仿真测试,对仿真结果进行分析说明。

2.项目原理及总体实现思路

上电后不显示,在按下SW0向上时以10Hz的频率,点亮实验开发板上的发光二极管LED9~LED0,显示过程中各个点亮的发光二极管的亮度呈现出明暗变化,形似呼吸。SW0 向下系统复位,LED灯全灭。SW0向上,LED呈现呼吸状显示,分组显示两组不同渐变周期的呼吸灯,Key0控制LED4~LED0显示, KEY1 控制LED9~LED5显示,渐变周期由SW1~SW9输入二进制编码,同时数码管分别显示2组呼吸灯对应周期数。

为了让“呼吸”的效果表达的比较完美,我们把从灭到亮的时间初始设置为 1s,也就是 led 灯在 1s 的时间内完成从灭到亮的效果,同理从亮到灭也是一样的时间。通过控制 PWM 的占空比来实现 led 灯越亮的效果。我们知道同一时间段内,如果供给led灯一个脉冲信号的低电平持续的时间越长(高电平持续的时间越短),led灯就越亮,我们就是通过调整 PWM(如图1—1—1) 实现高低电平的占 空来调控 led 灯的亮度,我们取 n 个相同的时间段,然后让低电平的持续时间按照相等的 时间间隔逐渐增多,这样子我们看上去的 led 灯就会越来越亮了。

项目模块设计

1.顶层模块

(1)我给模块取名led,设置为顶层模块用于调用其他模块,所以时钟和复位信号也是必须有的,且输入有时钟和复位信号和开关0~9,以及和两个按键。

(2)模块原理图

 

(3)模块代码

受报告篇幅限制仅展示部分关键代码

//数据的输入input   wire            sys_clk     ,input   wire            sys_rst_n   ,  input   wire    [9:0]   sw_in       ,  input   wire            key_in1     ,  input   wire            key_in2     , //led的输出output  wire   [9:0]   led_out      ;//key1和key2 控制输入的频率ctrl ctrl_inst(.sys_clk   (sys_clk)  ,.sys_rst_n (sys_rst_n)  ,  .sw_in     (sw_in)  ,  .key_in1   (key_in1)  ,  .key_in2   (key_in2)  ,.data_in1  (data_in1) ,.data_in2  (data_in2) );//开关输入的二进制数,转换为BCD码用于数码管显示binTobcd binTobcd_inst1( .bin (data_in1),   // binary.bcd (bcd1)); //led的输出breath_led breath_led_inst1(.sys_clk     (sys_clk  ),.sys_rst_n   (sys_rst_n),.data      (data_in1),.led_out     (led_out[4:0]  ));//数码管显示seg seg_int1(.sys_clk   (sys_clk)  ,.sys_rst_n (sys_rst_n)  ,.sw0       (sw_in[0])  ,.bcd       (bcd1)  ,.ge        (ge1) ,.shi       (shi1) ,.bai       (bai1) );

 

2.按键控制模块

(1)我给模块取名ctrl,设置为按键控制模块用于通过输入的开关选择控制前后的灯模块和把输入的拨码开关的数值转换和寄存,所以时钟和复位信号也是必须有的,且输入有时钟和复位信号和开关0~9,以及和两个按键。

(2)模块输入输出设计

(3)模块源代码核心代码

reg              begin_reg        ;//开始的标志,开始时10hz的频率reg              sw0_reg          ;//sw[0]的延时一拍reg              key_in1_reg      ;//按键1控制后面的数据reg              key_in2_reg      ;  //按键2控制前面的数据wire             sw0_flag          ; //SW[0]拨动了的标志信号//最开SW0拨上去就赋值给数据初始值10hz,按下按键后跳转always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)sw0_reg <= 1'd0;elsesw0_reg <= sw_in[0];assign  sw0_flag = ((sw_in[0])&&(~ sw0_reg));always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)begin_reg <= 1'd0;else    if(key_in1 == 1'd0 ||key_in2 == 1'd0)begin_reg <= 1'd0;else    if(sw0_flag == 1'd1)begin_reg <= ~ begin_reg;elsebegin_reg <=  begin_reg;// 按下按键获得对前后数据的控制权always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)key_in2_reg <= 1'd0;else    if(sw_in[0] == 1'd0)key_in2_reg <= 1'd0;else    if(key_in1 == 1'd0)key_in2_reg <= 1'd0;else    if(sw_in[0] == 1'd1 && key_in2 == 1'd0)key_in2_reg <= 1'd1;elsekey_in2_reg <= key_in2_reg;//把数据传输给寄存器always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)data_in1 <= 9'd0;else    if(sw_in[0] == 1'd0)data_in1 <= 9'd0;else    if(sw_in[0] == 1'd1 && begin_reg == 1'd1)data_in1 <= 9'd10;else    if(key_in1_reg == 1'd1)data_in1 <= sw_in[9:1] ;elsedata_in1 <= data_in1;   endmodule

3.呼吸灯模块

(1)我们给模块取名为 breath_led,同样本例我们也会用到计数器,所以时钟和复位信号也 是必须有的,且输入只有时钟和复位信号以及拨码开关的数据。我们需要控制分别两组的 led 灯进行“呼吸”就可以了,所以输出是一个名为 led_out 的输出信号。根据上面的分析设计出的 Visio 框图如图所示。

(2模块输入输出设计

 

(3)模块部分关键代码

//cnt_1ms:1ms计数器always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_1ms <=  10'd0;else    if((cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))cnt_1ms <=  10'd0;else    if(cnt_1us == CNT_1US_MAX)cnt_1ms <=  cnt_1ms + 10'd1;elsecnt_1ms <=  cnt_1ms;//cnt_1s:1s计数器以及用1S来作为基础,通过1/data来获得新的频率让led的闪亮always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_1s  <=  10'd0;else    if(data == 9'd0)cnt_1s  <=  10'd0;else    if((cnt_1s == CNT_1S_MAX / data) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))cnt_1s  <=  10'd0;else    if((cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))cnt_1s  <=  cnt_1s + 10'd1;elsecnt_1s  <=  cnt_1s;//cnt_1s:1s计数器以及用1S来作为基础,通过1/data来获得新的频率让led的闪亮的使能信号always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_en  <=  1'b0;else    if(data == 9'd0)cnt_en  <=  1'b0;else    if((cnt_1s == CNT_1S_MAX / data) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))cnt_en  <=  ~cnt_en;elsecnt_en  <=  cnt_en;//利用PWM脉宽调制呼吸流水always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)led_out <=  5'b00000;else    if(data == 9'd0)led_out <=  5'b00000;else    if(((cnt_en == 1'b0) && (cnt_1ms <= cnt_1s)) || ((cnt_en == 1'b1) && (cnt_1ms > cnt_1s)))led_out <=  5'b00000;elseled_out <=  5'b11111;

4.数码管显示模块

(1)我们给模块取名为 seg,同样本例我们也会用到数据手册的数码管模块的使用,所以时钟和复位信号也是必须有的,且输入只有时钟和复位信号以及转换成BCD码的拨码开关的寄存数据。我们把BCD码作为条件使用case语句,所以输出是一个名为ge,shi,bai三个数码位的输出信号。根据上面的分析设计出的 Visio 框图如图所示。

(2)模块输入输出

(3)模块核心代码:

 

module  seg(input   wire            sys_clk     ,//系统时钟50Mhzinput   wire            sys_rst_n   ,//key3全局复位input   wire            sw0         ,//sw0的拨码输入input   wire    [10:0]  bcd         ,//转换后的BCd码output  reg    [6:0]    ge         ,//个位的输出output  reg    [6:0]    shi        ,//十位的输出output  reg    [6:0]    bai        //百位的输出);//个位的输出always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)ge <= 7'b1_111_111;else    if(sw0 == 1'd0)ge <= 7'b1_111_111;else    case(bcd[3:0])4'b0000:ge <= 7'b1_000_000;4'b0001:   ge <= 7'b1_111_001;4'b0010:   ge <= 7'b0_100_100;4'b0011:   ge <= 7'b0_110_000;4'b0100:   ge <= 7'b0_011_001;4'b0101:   ge <= 7'b0_010_010;4'b0110:   ge <= 7'b0_000_010;4'b0111:   ge <= 7'b1_111_000;4'b1000:   ge <= 7'b0_000_000;4'b1001:   ge <= 7'b0_010_000;default:    ge <= 7'b1_000_000;endcaseendmodulemodule  seg(input   wire            sys_clk     ,//系统时钟50Mhzinput   wire            sys_rst_n   ,//key3全局复位input   wire            sw0         ,//sw0的拨码输入input   wire    [10:0]  bcd         ,//转换后的BCd码output  reg    [6:0]    ge         ,//个位的输出output  reg    [6:0]    shi        ,//十位的输出output  reg    [6:0]    bai        //百位的输出);//个位的输出always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)ge <= 7'b1_111_111;else    if(sw0 == 1'd0)ge <= 7'b1_111_111;else    case(bcd[3:0])4'b0000:ge <= 7'b1_000_000;4'b0001:   ge <= 7'b1_111_001;4'b0010:   ge <= 7'b0_100_100;4'b0011:   ge <= 7'b0_110_000;4'b0100:   ge <= 7'b0_011_001;4'b0101:   ge <= 7'b0_010_010;4'b0110:   ge <= 7'b0_000_010;4'b0111:   ge <= 7'b1_111_000;4'b1000:   ge <= 7'b0_000_000;4'b1001:   ge <= 7'b0_010_000;default:    ge <= 7'b1_000_000;endcaseendmodule

5.二进制转BCD码模块

(1)利用移三位加法原理设计一个二进制转换BCD码的模块,以输入为8位二进制数10100101(十进制165)为例,8位二进制数表示范围为0~255,BCD码需要表示百位、十位、个位:
送入最高位1;
送入第二位0得到10;
送入第三位1得到101 ,因为101 > 100,修正:101 + 011 = 1000;
送入第四位0得到1_0000;
送入第五位0得到10_0000;
送入第六位1得到100_0001;
送入第七位0得到1000_0010,1000 > 100,修正:1000 + 011 = 1011;
送入第八位1得到1_0110_0101,得到输出结果为0001_0110_0101(十进制165)。

我们给模块取名binTobcd,输入寄存的二进制数据,输出BCD码,如图所示

(2)模块核心代码如下

//移3进位的算法always @(*) beginones = 4'd0;tens = 4'd0;hundreds = 3'd0;for(i = 8; i >= 0; i = i - 1) beginif (ones >= 4'd5) ones = ones + 4'd3;if (tens >= 4'd5) tens = tens + 4'd3;if (hundreds >= 4'd5) hundreds = hundreds + 4'd3;hundreds = {hundreds[1:0],tens[3]};tens  = {tens[2:0],ones[3]};ones  = {ones[2:0],bin[i]};endend

项目测试

1.仿真测试

仿真部分不显示数码管状态波形如下

​​​​​​​

信号分析

sys_clk:时钟信号        sys_rst_n:使能端

sw_in:拨码控制输出信号频率

Key_in1、Key_in2:分别控制led0~led4和led5~led9

led_out:显示led的波形信息

 

观察波形2

Key_in1出现置0led_out波形发生了频率和占空比的变化且led[9]~led[5]不显示波形

 

观察波形图3,在黄线处,sw_in[8]和sw_in[6]由低电平变为高电平,led_out波形发生了频率和占空比的变化体现了拨码信号对输出波形的控制占空比的变化也使其呈现呼吸状变化

2.实物测试

开发板:bassy3

按下key2,控制输入7hz的频率,使右边5个led灯亮此时灯亮的频率由拨码开关控制

 

 

 ​​​​​​​

 

受图片形式限制,无法展示亮灯频率的变化

五、项目总结

1.选题思考与过程反思

此次综合实验设计,最初是打算使用VGA进行贪吃蛇游戏的设计,但在实现老师的要求“在VGA上显示姓名学号及校徽”时遇到的了困难,虽然可以很好的实现图片的显示,但在文字的显示这一问题上一直未能解决。于是在验收前几天选择了一个更简单易通过的呼吸灯设计。

回望整个综合实验的设计过程,时间大部分花在代码的调试上,无论是最初的VGA图片和文字显示还是呼吸灯中如何更新颖的呈现亮灯过程。其次便是查阅资料的过程,任何一个环节都需要自己去主动的查找有关的资料并进行知识的检索和学习,然后运用到自己的项目设计上。总之,此次综合设计实验让我收获很大,虽然最终是以难度较低的呼吸灯进行验收,但在课程结束后的课余时间,我依旧会进行VGA项目的学习和设计。

2.设计的具体完成情况详细描述

开始上电后全部都进入待机状态,然后按上开关0过后,然后显示10hz并呼吸灯以10hz频率开始闪烁。然后按下key 0的时候获得后面三位的控制权,输入频率可以改变呼吸灯的闪亮频率和数码管上的具体数值,然后按下key1的时候可以获得前面的控制权。可以对前面的呼吸灯的频率改变和改变数码管的具体数值,然后拨上。开关临时全部又进入了待机状态。完成了所有要求的实验步骤和功能。

3.项目可改进之处

经过自己在验收后的思考总结,发现一些可以改进的地方。

(1)实验难度的提升:最初我认为自己无法在最后一次课上完成综合实验设计的验收(VGA相关设计),于是换了一个更简单的实验。在验收才觉得自己完全可以结合VGA再次进行功能的拓展。

(2)针对本项目呼吸灯的设置,频率的调节方法,用了一个比较复杂的数据直接控制最大计数范围的方法,但是还应该可以有更简便的方法。在代码的过程中,使用了比较多的寄存量。在后面代码的简化和优化过程中,都可以对寄存量以及代码的减少。

(3)本功能使用了较多的模块,目前也只想到了这个方法如果有更好的方法,可以学习加以改进。

   

4.项目设计心得

(1)本次FPGA综合实验设计“基于PWM脉宽调制的呼吸流水灯设计”让我收获了很多。在整个项目的过程中,我主要从以下几个方面得到了很大的提升和收获。

首先是理论知识方面。在本次项目中,我学习了PWM脉宽调制技术和FPGA硬件设计的原理和应用,包括FPGA电路设计和Verilog语言编程等方面的知识。通过这些理论知识的学习,同时前期对于VGA相关实验的探索对FPGA开发有了进一步的理解不断的探索也让我更加深入地理解了数字电路设计和控制的原理和方法,并且对FPGA技术的实际应用有了更加清晰的认识。

其次是实践能力方面。在项目的过程中,我亲手设计和实现了一个基于PWM脉宽调制的呼吸流水灯控制系统,从FPGA电路设计到Verilog语言程序编写、仿真调试和最终实际硬件测试,每一个环节都亲身参与了并且深刻理解了每一个步骤的重要性以及设计中需要注意的细节。这些实践过程让我更加自信,并且增强了我解决实际问题的能力。

最后是和沟通能力方面。在这个项目中,我和班上的同学进行有效的合作和沟通,进行了很多有效的探索。通过交流和合作,我们更好地理解了各自的专业领域和思路,相互帮助,一起攻克问题和难题,使得整个项目可以有条不紊地完成。虽然最终未能完成使用VGA进行文字的显示这对我的团队合作和沟通能力提升非常有帮助。

总结来说,本次FPGA综合实验设计“基于PWM脉宽调制的呼吸流水灯设计”让我受益匪浅,虽然最后难度相对VGA相关开发偏低但依旧加深了我的理论知识和实践经验,让我更加熟悉了团队合作和沟通的重要性和方法。这是我成长和提升的重要机会,也是一个非常有意义的项目体验。

参考文献

  1. 黄继业潘松.EDA技术实用教程--Verilog HDL [M]:第六版.北京科学出版社,2018.8.
  2. 何宾.Xilinx FPGA权威设计指南[M].北京电子工业出版社,2015.2.
  3. 王明.脉冲宽度调制的原理和实现[EB].http://www.doc88.com/p-54859547918569.html,2023-04-23.
  4. 张亮.数字电路设计与Verilog HDL[M].北京:人民邮电出版社,2000.

2023-06-15

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

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

相关文章

Android 短视频直播特效,音视频图像处理 FFmepg OpenGLES OpenCV开发详细内容

1 音视频开发基础 2 Android OpenGL ES开发基础 3 Android FFmpeg OpenGLES 音视频播放器核心开发 4 Android FFmpeg H.264 AAC 封装mp4 5 Android OpenCV 机器学习人脸标定SDK开发实战 6 Android OpenCV 开发实践 7 Android 短视频App FFmpeg OpenGL ES OpenCV人脸特效渲…

Nanopc T4 教程使用及获取

所有资料从以下链接获取 ● Wiki教程&#xff1a;http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T4/zh 机械结构图&#xff08;dxf格式&#xff09;&#xff1a;http://wiki.friendlyarm.com/wiki/images/b/bc/NanoPC-T4_1802_Drawing%28dxf%29.zip 原理图&#xff1a;h…

基于matlab处理 RGB-D图像数据以构建室内环境地图并估计相机的轨迹(附源码)

一、前言 视觉同步定位和映射 &#xff08;vSLAM&#xff09; 是指计算摄像机相对于周围环境的位置和方向&#xff0c;同时映射环境的过程。 您可以使用单眼摄像头执行 vSLAM。但是&#xff0c;深度无法准确计算&#xff0c;估计的轨迹未知&#xff0c;并且随着时间的推移而漂…

神经网络术语解释

目录 Padding&#xff1a; 填充步幅&#xff08;stride&#xff09;Pooling Layer:池化层Batch NormalizationSeparable ConvolutionsREFERENCE Padding&#xff1a; 填充 在进行卷积层的处理之前&#xff0c;有时要向输入数据的周围填入固定的数据&#xff08;比 如0等&#…

电动汽车充电站监控系统设计_kaic

1 绪论 1.1 引言 汽车工业的告诉发展&#xff0c;汽车带来的环境污染、能源短缺、资源枯竭和安全等方面的问题越来越突出。为了保持国民经济的可持续发展&#xff0c;保护人类居住环境和能源供给&#xff0c;各国政府不惜巨资&#xff0c;投入大量人力、物力&#xff0c;寻…

Ae 效果:CC Threshold RGB

风格化/CC Threshold RGB Stylize/CC Threshold RGB CC Threshold RGB&#xff08;CC 阈值 RGB&#xff09;效果可以为红、绿、蓝三个原色通道分别设置阈值&#xff0c;即&#xff0c;通道上高于此阈值时为纯白&#xff0c;低于此阈值时纯黑&#xff0c;以实现对原色通道的二值…

获取系统时间日期相关接口梳理

时间&日期 ##MyTime.hpp #pragma once #include <iostream> #include <ctime> #include <string>using namespace std;class MyTime { public:MyTime() {};~MyTime() {};time_t timeSec(void);uint64_t timeMs(void);string timeDate(void); };##MyTim…

大语言模型的百家齐放

基础语言模型 概念 基础语言模型是指只在大规模文本语料中进行了预训练的模型&#xff0c;未经过指令和下游任务微调、以及人类反馈等任何对齐优化。 如何理解 只包含纯粹的语言表示能力,没有指导性或特定目标。 只在大量无标注文本上进行无监督预训练,用于学习语言表示。 …

TCP连接管理(三次握手,四次挥手)

目录 一、回顾一下TCP包头二、连接的建立——“三次握手”三、连接的建立——“四次挥手”保活计时器 一、回顾一下TCP包头 源端口号&#xff08;Source Port&#xff09;&#xff1a;16 位字段&#xff0c;表示发送方的端口号。 目的端口号&#xff08;Destination Port&…

Python——爬虫入门

爬虫的流程 第一步:获取网页内容 浏览器访问网页时也是一样&#xff0c;都是先发个请求获取网页内容&#xff0c;但是浏览器多了个渲染的步骤。 程序获取的内容都是网页源代码 第二步:解析网页内容 第三步:储存或分析数据 要做数据集就存起来&#xff0c;要做数据分析就形…

IP 协议(网络层协议)

IP协议 IP 协议作用地址管理动态分配 IP 地址NAT 机制IPv6IP 地址的组成 路由选择 IP 协议作用 主要有两点 : 地址管理 为每个上网的设备分配一个唯一地址. 路由选择 两台主机间的信息交互, 具体走哪条线路. 地址管理 先来看看 IP协议 报文格式 : IP 协议最主要就是 32 位的…

web学习笔记1

计算机&#xff1a; 课程大纲&#xff1a;html&#xff08;五条猫结构&#xff09; 结构 css 表现 JavaScript 行为 html&#xff1a;超文本标记语言 超&#xff1a;超链接&#xff0c;能从一个网页跳转到另一个网页 标记&#xff1a;文本要变成超文本&#xff0c;就需要各…