搜索
bottom↓
回复: 0

【正点原子FPGA连载】第八章自定义IP核-呼吸灯实验--摘自【正点原子】达芬奇之Microblaze 开发指南

[复制链接]

出0入234汤圆

发表于 2020-10-14 10:20:58 | 显示全部楼层 |阅读模式
本帖最后由 正点原子 于 2020-10-16 16:44 编辑

1)实验平台:正点原子达芬奇FPGA开发板
2)购买链接:https://detail.tmall.com/item.htm?id=624335496505
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/fpga/zdyz_dafenqi.html
4) 正点原子官方B站:https://space.bilibili.com/394620890
5)对正点原子FPGA感兴趣的同学可以加群讨论:876744900 点击加入: QQ群头像.png                                                                                                                            
6)关注正点原子公众号,获取最新资料

100846rel79a9p4uelap24.jpg

100846f1ce1fg14zbg0va4.png

第八章自定义IP核-呼吸灯实验


在Vivado软件中,我们可以很方便的通过创建和封装IP向导的方式来自定义IP核。自定义IP核可以定制化系统设计,以达到设计重用的目的,可以很大程度上简化系统设计和缩短产品上市的时间。本章将向大家介绍自定义IP核的方法。
本章包括以下几个部分:
88.1简介
8.2实验任务
8.3硬件设计
8.4软件设计
8.5下载验证


8.1简介
Xilinx官方为我们提供了非常丰富的IP核,如数学运算(乘法器、浮点运算器等)、信号处理(FFT、DDS等),我们可以通过调用这些IP核来快速完成设计。然而随着系统的设计越来越复杂,官方提供的免费IP核有时并不能很好的适用我们的设计,这个时候就需要我们自己来实现这些功能。为了使这些模块或代码以后能够复用,可以通过自定义IP核的方式将这些模块集成到Vivado中的IP库中,以达到简化系统设计和缩短产品上市时间的目的。
在Vivado软件中,通过创建和封装IP向导的方式来自定义IP核,支持将当前工程、工程中的模块或者指定文件目录封装成IP核,当然也可以创建一个带有AXI4接口的IP核,用于MicroBlaze软核处理器和可编程逻辑的数据通信。本次实验选择常用的方式,即创建一个带有AXI接口的IP核,该IP核通过AXI协议实现MicroBlaze软核处理器和可编程逻辑的数据通信。AXI协议是一种高性能、高带宽、低延迟的片内总线,关于该协议的详细内容,我们会在后面的例程中向大家做详细的介绍。本次实验的系统框图如图 8.1.1所示:
阿莫论坛发帖达芬奇专用1674.png

图 8.1.1 系统框图

框图中的UART用于打印信息,Breath LED IP核为自定义的IP核,McroBlaze处理器通过AXI接口为LED IP模块发送配置数据,从而来控制LED灯。
8.2实验任务
本章的实验任务是通过自定义一个LED IP核,来控制LED呈现呼吸灯的效果,并且可以通过AXI接口来控制呼吸灯的开关和呼吸的频率。
8.3硬件设计
首先创建一个LED呼吸灯的IP核。打开Vivado,进入Vivado界面后,点击“Tasks”栏中的“Manage IP”。在弹出的选项中选择“New IP Location...”,如图 8.3.1所示:
阿莫论坛发帖达芬奇专用11020.png

图 8.3.1 点击Manage IP

在弹出的界面中选择“Next”,然后设置Manage IP核的属性,在“IP Location:”一栏指定工程的路径,路径为:G:/vitis_pro/custom_ip,其它保持默认即可。点击“Finish”完成Manage IP工程的创建,如图 8.3.2和图 8.3.3所示。注意,Part一栏中设置开发板的型号,在后面的工程中会重新指定,这里直接保持默认。
阿莫论坛发帖达芬奇专用11330.png

图 8.3.2 自定义IP核向导界面

阿莫论坛发帖达芬奇专用11394.png

图 8.3.3 IP设置选项

此时弹出确认工程路径的界面,点击“OK”按钮完成工程的创建。
工程创建完成后,运行创建和封装IP向导。点击菜单栏的“Tools”,选择“Create and Package New IP”,在弹出的界面中,点击“Next”。如图 8.3.4和图 8.3.5所示:
阿莫论坛发帖达芬奇专用11632.png

图 8.3.4 选择创建和封装IP向导

阿莫论坛发帖达芬奇专用11697.png

图 8.3.5 封装IP向导界面

接下来选择封装IP或者创建一个带AXI4接口的IP核,我们这里选择创建一个带AXI接口的IP核,选中“Creat a new AXI4 peripheral”,并点击“Next”按钮。如图 8.3.6所示:
阿莫论坛发帖达芬奇专用11887.png

图 8.3.6 封装IP选项

接下来分别设置IP核名称(Name)、版本号(Version)、显示名(Display name)、描述(Description)和路径(IP location)。在Name一栏设置IP核的名称,本次实验的功能是控制LED呈现呼吸灯的效果,因此这里在Name一栏,将名称改为“breath_led_ip”,此时Display name一栏会自动更改为“breath_led_ip_v1.0”。其它的设置直接保持默认即可,点击“Next”按钮,如图 8.3.7所示:
阿莫论坛发帖达芬奇专用12204.png

图 8.3.7 IP参数设置

接下来对AXI接口进行设置。
阿莫论坛发帖达芬奇专用12279.png

图 8.3.8 AXI4接口设置

Name(名称):这里修改成S0_AXI。
Interface Tpye(接口类型):共三种接口类型可选,分别是Lite、Full和Stream。AXI4-Lite接口是简化版的AXI4接口,用于较少数据量的存储映射通信;AXI4-Full接口是高性能存储映射接口,用于较多数据量的存储映射通信;AXI4-Stream用于高速数据流传输,非存储映射接口。本次实验只需少量数据的通信,因此接口类型选择默认的Lite接口。
Interface Mode(接口模式):接口模式有Slave(从机)和Master(主机)两种模式可选,AXI协议是主机和从机通过“握手”的方式建立连接,这里选择默认的Slave接口模式。
Data Width(数据宽度):数据位宽保持默认,即32位位宽。
Memory Size(存储器大小): 在AXI4-Lite接口模式下,该选项不可设置。
Number of Registers(寄存器数量):用于配置LED呼吸灯寄存器的数量,这里保持默认。
点击“Next”按钮。
最后弹出封装接口的总结描述和下一步操作选项的界面。这里保持默认,即将IP添加至IP库中,点击“Finish”按钮完成IP核的创建和封装。如图 8.3.9所示:
阿莫论坛发帖达芬奇专用12895.png

图 8.3.9 创建和封装IP核总结界面

在IP Catalog界面中可以看到刚刚添加的IP核,位于User Repository一栏中的AXI Peripheral下,名称为“breath_led_ip_v1.0”,如图 8.3.10所示:
阿莫论坛发帖达芬奇专用13085.png

图 8.3.10 新添加的IP核

创建好IP核后,我们接下来对breath_led_ip_v1.0 IP核进行编辑。右击breath_led_ip_v1.0 IP核,选择“Edit in IP Packager”,在弹出的界面中点击“OK”,如图 8.3.11和图 8.3.12所示:
阿莫论坛发帖达芬奇专用13319.png

图 8.3.11 打开编辑IP核界面

阿莫论坛发帖达芬奇专用13383.png

图 8.3.12 设置工程名和路径

此时会打开一个新的工程,如图 8.3.13所示:
阿莫论坛发帖达芬奇专用13494.png

图 8.3.13 编辑IP核界面

双击breath_led_ip_v1_0,如图 8.3.14所示:
阿莫论坛发帖达芬奇专用13614.png

图 8.3.14 双击breath_led_ip_v1_0

打开breath_led_ip_v1_0.v文件后,接下来开始编辑代码,来添加控制LED呼吸灯所需要的参数和端口信号。在代码的第7行添加如下代码:
parameter  START_FREQ_STEP = 10'd100,
这个参数用于设置呼吸灯默认的呼吸频率,然后在代码的第18行添加如下代码:
  1. output      led,
复制代码

添加完成后的代码如图 8.3.15所示:
阿莫论坛发帖达芬奇专用13900.png

图 8.3.15 编辑breath_led_ip_v1_0.v文件

在代码例化breath_led_ip_v1_0_S0_AXI模块的地方,增加对参数START_FREQ_STEP和端口led的例化,代码如下:
  1. .START_FREQ_STEP(START_FREQ_STEP),
复制代码


  1. .led(led),
复制代码

代码添加后,按下键盘键Ctrl+S保存。如图 8.3.16所示:
阿莫论坛发帖达芬奇专用14156.png

图 8.3.16 添加对参数和端口的例化

双击breath_led_ip_v1_0下的breath_led_ip_v1_0_S0_AXI_inst,如图 8.3.17所示:
8317.png
8.3.17 双击breath_led_ip_v1_0_S0_AXI_inst



breath_led_ip_v1_0_S0_AXI模块实现了AXI4协议下的读写寄存器的功能,我们只需要对该模块稍作修改,即可实现控制LED呼吸灯的功能。向寄存器中写入数据和读出数据的部分代码如图 8.3.18和图 8.3.19所示:
阿莫论坛发帖达芬奇专用14565.png

图 8.3.18 写寄存器数据部分代码

8319.png
8.3.19 读寄存器数据部分代码



在创建和封装IP核向导中,我们总共定义了4个寄存器,代码中的slv_reg0至slv_reg3是寄存器地址0至寄存器地址3对应的数据,通过例化呼吸灯模块,将寄存器地址对应的数据和呼吸灯模块的控制端口相连接,即可实现对呼吸灯的控制。
我们接下来开始编辑代码,同样在代码的第7行添加如下代码:
  1. parameter START_FREQ_STEP   = 10'd100,
复制代码
  1. 在代码的第18行添加如下代码:
  2. output      led,
复制代码

添加完成后的代码如图 8.3.20所示:
阿莫论坛发帖达芬奇专用14957.png

图 8.3.20 编辑breath_led_ip_v1_0_S0_AXI.v文件

同时我们还需要在代码的第401行例化breath_led.v文件,代码如下:
  1. breath_led #(
  2.     .START_FREQ_STEP(START_FREQ_STEP)
  3. )
  4. u_breath_led(
  5.     .sys_clk          (S_AXI_ACLK),
  6.     .sys_rst_n        (S_AXI_ARESETN),
  7.     .sw_ctrl          (slv_reg0[0]),
  8.     .set_en           (slv_reg1[31]),
  9.     .set_freq_step    (slv_reg1[9:0]),
  10.     .led              (led)
  11. );
复制代码

代码中的slv_reg0和slv_reg1是寄存器地址0和寄存器地址1对应的数据,我们通过寄存器地址0对应的数据来控制呼吸灯的使能(sw_ctrl),寄存器地址1对应数据的最高位控制呼吸灯频率的设置有效信号(set_en),寄存器地址1对应数据的低10位控制呼吸灯频率的步长(set_freq_step)。
添加完代码后,按下键盘Ctrl+S保存代码,添加完成后的代码如图 8.3.21所示:
阿莫论坛发帖达芬奇专用15591.png

图 8.3.21 例化breath_led代码

此时工程中缺失breath_led.v文件,breath_led.v文件用于实现呼吸灯的功能,这个代码是在“呼吸灯实验”的基础上修改而来。
右击“Design Sources”,选择“Add Sources…”,在弹出的界面中选择“Add or create design source”,点击“Next”,如图 8.3.22和图 8.3.23所示:
阿莫论坛发帖达芬奇专用15882.png

图 8.3.22 添加设计文件

阿莫论坛发帖达芬奇专用15943.png

图 8.3.23 选择添加设计文件界面

点击“Create File”创建一个新的文件,如图 8.3.24所示
阿莫论坛发帖达芬奇专用16067.png

图 8.3.24 创建一个新的设计文件

在弹出的界面输入名称“breath_led”,路径为G:/vitis_pro/custom_ip/ip_repo/breath_led_ip_1.0/hdl,点击“OK”按钮,如图 8.3.25所示:
阿莫论坛发帖达芬奇专用16272.png

图 8.3.25 设置设计文件的名称与路径

点击“Finish”按钮完成创建,如图 8.3.26所示:
阿莫论坛发帖达芬奇专用16393.png

图 8.3.26 完成设计文件的添加

在弹出的模块定义界面中点击“OK”按钮,紧接着在弹出的确认按钮中点击“YES”。
双击u_breath_led(breath_led.v)文件,如图 8.3.27所示:
阿莫论坛发帖达芬奇专用16566.png

图 8.3.27 双击breath_led.v文件

打开breath_led.v文件后,开始编辑代码,代码如下:
  1. 1  module breath_led(
  2. 2      input          sys_clk        , //时钟信号
  3. 3      input          sys_rst_n      , //复位信号
  4. 4      input          sw_ctrl        , //呼吸灯开关控制信号 1:亮 0:灭
  5. 5      input          set_en         , //设置呼吸灯频率设置使能信号
  6. 6      input   [9:0]  set_freq_step  , //设置呼吸灯频率变化步长
  7. 7      
  8. 8      output         led              //LED
  9. 9  );
  10. 10
  11. 11 //*****************************************************
  12. 12 //**                  main code
  13. 13 //*****************************************************
  14. 14
  15. 15 //parameter define
  16. 16 parameter  START_FREQ_STEP = 10'd100; //设置频率步长初始值
  17. 17
  18. 18 //reg define
  19. 19 reg  [15:0]  period_cnt  ;      //周期计数器
  20. 20 reg  [9:0]   freq_step   ;      //呼吸灯频率间隔步长
  21. 21 reg  [15:0]  duty_cycle  ;      //设置高电平占空比的计数点
  22. 22 reg          inc_dec_flag;      //用于表示高电平占空比的计数值,是递增还是递减
  23. 23                                 //为1时表示占空比递减,为0时表示占空比递增
  24. 24 //wire define
  25. 25 wire         led_t       ;
  26. 26
  27. 27 //将周期信号计数值与占空比计数值进行比较,以输出驱动led的PWM信号
  28. 28 assign led_t = ( period_cnt <= duty_cycle ) ? 1'b1 : 1'b0 ;
  29. 29 assign led = led_t & sw_ctrl;
  30. 30
  31. 31 //周期信号计数器在0-50_000之间计数
  32. 32 always @ (posedge sys_clk) begin
  33. 33     if (!sys_rst_n)
  34. 34         period_cnt <= 16'd0;
  35. 35     else if(!sw_ctrl)
  36. 36         period_cnt <= 16'd0;
  37. 37     else if( period_cnt == 16'd50_000 )
  38. 38         period_cnt <= 16'd0;
  39. 39     else
  40. 40         period_cnt <= period_cnt + 16'd1;
  41. 41 end
  42. 42
  43. 43 //设置频率间隔
  44. 44 always @(posedge sys_clk) begin
  45. 45     if(!sys_rst_n)
  46. 46         freq_step <= START_FREQ_STEP;
  47. 47     else if(set_en) begin
  48. 48         if(set_freq_step == 0)
  49. 49             freq_step <= 10'd1;
  50. 50         else if(set_freq_step >= 10'd1_000)
  51. 51             freq_step <= 10'd1_000;
  52. 52         else   
  53. 53             freq_step <= set_freq_step;
  54. 54     end        
  55. 55 end
  56. 56
  57. 57 //设定高电平占空比的计数值
  58. 58 always @(posedge sys_clk) begin
  59. 59     if (sys_rst_n == 1'b0) begin
  60. 60         duty_cycle <= 16'd0;
  61. 61         inc_dec_flag <= 1'b0;
  62. 62     end     
  63. 63     else if(!sw_ctrl) begin          //呼吸灯开关关闭时,信号清零
  64. 64         duty_cycle <= 16'd0;
  65. 65         inc_dec_flag <= 1'b0;
  66. 66     end   
  67. 67     //每次计数完了一个周期,就调节占空比计数值
  68. 68     else if( period_cnt == 16'd50_000 ) begin
  69. 69         if( inc_dec_flag ) begin  //占空比递减
  70. 70             if( duty_cycle == 16'd0 )     
  71. 71                 inc_dec_flag <= 1'b0;
  72. 72             else if(duty_cycle < freq_step)
  73. 73                 duty_cycle <= 16'd0;
  74. 74             else   
  75. 75                 duty_cycle <= duty_cycle - freq_step;
  76. 76         end
  77. 77         else begin  //占空比递增
  78. 78             if( duty_cycle >= 16'd50_000 )  
  79. 79                 inc_dec_flag <= 1'b1;
  80. 80             else
  81. 81                 duty_cycle <= duty_cycle + freq_step;
  82. 82         end
  83. 83     end
  84. 84     else  //未计数完一个周期时,占空比保持不变
  85. 85         duty_cycle <= duty_cycle ;
  86. 86 end
  87. 87   
  88. 88 endmodule
复制代码

模块实现了呼吸灯的功能。呼吸灯的使能由输入的端口信号sw_ctrl控制,呼吸灯的呼吸频率由输入的端口信号set_en和set_freq_step控制。由代码的第43行至第55行代码可知,输入的set_freq_step范围是1~1000。
保存代码,并验证代码是否有语法错误。在左侧Flow Navigator导航栏中找到SYNTHESIS,点击该选项中的“Run Synthesis”,如图 8.3.28所示:
阿莫论坛发帖达芬奇专用19671.png

图 8.3.28 编译代码

在弹出的窗口中点击“OK”按钮,等待代码编译完成。
接下来开始设置IP封装,将界面切换至Package IP,如果不小心关闭的话,可以通过IP-XACT界面下的component.xml重新打开,如图 8.3.29所示:
阿莫论坛发帖达芬奇专用19865.png

图 8.3.29 打开Package IP界面

重新打开封装界面,如下图所示:
阿莫论坛发帖达芬奇专用19950.png

图 8.3.30 Package IP界面

Identification这一栏的选项直接保持默认,需要注意的是,我们可以点击图 8.3.31中Categories选项下的“+”按钮来修改IP的分类,这里不做修改。
阿莫论坛发帖达芬奇专用110126.png

图 8.3.31 修改IP核分类

点击“Compatibility”,修改该IP核支持的器件。点击“Family”一栏下的“+”图标,选择“Add Family Explicitly…”,如图 8.3.32所示:
阿莫论坛发帖达芬奇专用110302.png

图 8.3.32 “Compatibility界面”

这里勾选“artix7(artix-7)”,表示该IP核支持artix7器件。而Life-cycle表明该IP核当前的产品生命周期,这里选择“Pre-Production”。
阿莫论坛发帖达芬奇专用110462.png

图 8.3.33 选择支持的器件

点击“File Groups”,然后点击界面上的“Merge Changes from Gile Groups Wizard”,如图 8.3.34所示:
阿莫论坛发帖达芬奇专用110625.png

图 8.3.34 File Groups界面

此时可以在Verilog Synthesis一栏中查看工程中的三个模块。
点击“Customization Parameters”,点击界面上的“Merge Changes from Customization Parameters Wizard”,如图 8.3.35所示:
阿莫论坛发帖达芬奇专用111070.png

图 8.3.35 Customization Parameters界面

此时多了Hidden Parameters一栏,展开这个界面,可以看到程序中自定义的参数START_FREQ_STEP,右击这个参数,选择“Edit Parameter…”,弹出编辑参数的界面,如图 8.3.36所示:

图 8.3.36 打开编辑参数界面

在弹出的页面中勾选“Visible in Customization GUI”,将此参数显示在GUI参数界面中;
Format格式改为“long”;
勾选“Specify Range”来设定此参数的范围。将Type改为“Range of integers”,Minimum的值改为“1”,Maximum的值改为“1000”,将Default Value的值改为“100”,点击“OK”按钮,如图 8.3.37所示:
阿莫论坛发帖达芬奇专用111365.png

图 8.3.37 参数设置

点击“Customization GUI”,可以在“Layout”界面拖动Page 0下的参数来调整参数在GUI显示的位置,如图 8.3.38所示:
阿莫论坛发帖达芬奇专用111523.png

图 8.3.38 拖动参数

点击“Review and Package”,然后点击“IP has been modified”更新总结界面,最后点击“Re-Package IP”,如图 8.3.39所示:
阿莫论坛发帖达芬奇专用111695.png

图 8.3.39 Review and Package界面

接下来会弹出一个是否关闭工程的询问界面,点击“YES”关闭工程,如图 8.3.40所示:
阿莫论坛发帖达芬奇专用111840.png

图 8.3.40 关闭工程询问界面

IP核封装完成后,在IP核所在路径(...\custom_ip\ip_repo\breath_led_ip_1.0\drivers\breath_led_ip_v1_0\src)目录下,软件会自动生成.c和.h文件,方便在Vitis软件中对IP核进行操作,如图 8.3.41所示:
阿莫论坛发帖达芬奇专用112068.png

图 8.3.41 软件生成的文件

在Manage IP工程界面下,点击菜单栏的“File”,选择“Close Project”关闭工程,如图 8.3.42所示:
阿莫论坛发帖达芬奇专用112218.png

图 8.3.42 关闭工程

接下来在弹出的确认关闭界面选择“OK”确认关闭工程。
创建Vivado工程
刚刚我们创建了一个自定义的IP核,接下来我们来创建Vivado工程,我们先打开《Hello World》实验的Vivado工程,打开后依次点击菜单栏的“File->Project->Save As...”,工程名为“user_led”,路径为G:/vitis_pro/custom_ip目录下,如图 8.3.43所示。
阿莫论坛发帖达芬奇专用112499.png

图 8.3.43 创建工程

在开始下一个步骤之前,先把我们刚自定义的IP核添加至本工程的IP库中,点击菜单栏的“Tools”,选择“Setting”,如图 8.3.44所示:
阿莫论坛发帖达芬奇专用112656.png

图 8.3.44 打开设置界面

点击“IP”一栏下的“Repository”,然后点击“+”来添加自定义的IP核,如图 8.3.45所示:
阿莫论坛发帖达芬奇专用112795.png

图 8.3.45 IP库添加界面

接下来会弹出添加自定义IP核的路径,选择“../custom_ip/ip_repo/breath_led_ip_1.0”,点击“Select”,在弹出的界面中可以看到识别到的IP核,点击“OK”按钮添加IP核,如图 8.3.46所示:
阿莫论坛发帖达芬奇专用112999.png

图 8.3.46 添加IP核

最后点击“OK”按钮,完成IP核的添加,如图 8.3.47所示:
阿莫论坛发帖达芬奇专用113116.png

图 8.3.47 添加IP核完成

使用IP Integrator创建Processing System。
在左侧导航栏Flow Navigator中,单击IP Integrator下的Open Block Design。
接下来添加Breath LED IP核,点击“+”图标,在搜索框中输入“led”,如图 8.3.48所示:
阿莫论坛发帖达芬奇专用113350.png

图 8.3.48 添加Breath LED IP核

双击“breath_led_ip_v1.0”,添加此IP核。添加完成后,可以双击led IP核来设置参数,如图 8.3.49所示:
阿莫论坛发帖达芬奇专用113511.png

图 8.3.49 Breath led IP核配置

从上图可以看到我们自定义的参数(Start Freq Step)和其它四个参数,这里不作修改,点击“Cancel”按钮。
接下来点击“Run Connection Automation”来自动连线,连线完成后如图 8.3.50所示:
阿莫论坛发帖达芬奇专用113722.png

图 8.3.50 添加Breath LED IP核并连线

此时原理图中还没有LED的引脚,右击breath_led_ip_0的led引脚,选择“Make External”,如图 8.3.51所示:
阿莫论坛发帖达芬奇专用113890.png

图 8.3.51 添加LED引脚

将引出的led_0改为led,如图 8.3.52所示:
阿莫论坛发帖达芬奇专用114003.png

图 8.3.52 修改引脚名称

点击“Regenerate Layout”图标,最终原理图界面如图 8.3.53所示:
阿莫论坛发帖达芬奇专用114131.png

图 8.3.53 最终布局视图

到这里我们的Block Design就设计完成了,在Diagram窗口空白处右击,然后选择“Validate Design”验证设计。验证完成后弹出对话框提示“Validation Successful”表明设计无误,点击“OK”确认。最后按快捷键“Ctrl+S”保存设计。
接下来在Source窗口中右键点击Block Design设计文件“system.bd”,然后依次执行“Generate Output Products”和“Create HDL Wrapper”。
接下来我们双击“source”目录下的“system_wrapper.xdc”文件夹,添加管脚约束文件。管脚约束如下:
  1. create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
  2. set_property PACKAGE_PIN R4 [get_ports sys_clk]
  3. set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
  4. set_property IOSTANDARD LVCMOS33 [get_ports sys_rst_n]
  5. set_property PACKAGE_PIN U2 [get_ports sys_rst_n]

  6. set_property IOSTANDARD LVCMOS33 [get_ports UART_rxd]
  7. set_property IOSTANDARD LVCMOS33 [get_ports UART_txd]
  8. set_property PACKAGE_PIN U5 [get_ports UART_rxd]
  9. set_property PACKAGE_PIN T6 [get_ports UART_txd]

  10. set_property IOSTANDARD LVCMOS33 [get_ports led]
  11. set_property PACKAGE_PIN R2 [get_ports led]
复制代码

管脚约束添加完成后按快捷键Ctrl+S保存管脚约束。
最后在左侧Flow Navigator导航栏中找到PROGRAM AND DEBUG,点击该选项中的“Generate Bitstream”,对设计进行综合、实现、并生成Bitstream文件。
在生成Bitstream之后,在菜单栏中依次点击“File->Export->Export hardware”导出硬件,并在弹出的对话框中,勾选“Include bitstream”,在导出路径最后添加“/vitis”。然后在菜单栏依次点击“Tools->Launch Vitis”,启动Vitis软件。
阿莫论坛发帖达芬奇专用115337.png

图 8.3.54 导出硬件路径

8.4软件设计
打开Vitis开发环境后,在菜单栏中依次点击“File->New->Application Project”,新建一个Vitis应用工程。在弹出的界面中工程名命名为“user_led”,点击“NEXT”,选择“Empty Application”,点击“Finish”按钮完成Vitis应用工程的创建。
新建源文件。在user_led/src目录上右键,点击“New->Source File”,如图 8.4.1所示:
阿莫论坛发帖达芬奇专用115636.png

图 8.4.1 新建源文件

在弹出的对话框中Source file一栏我们输入文件名“main.c”,然后点击“Finish”。
新建源文件之后,在左侧user_led/src目录下可以看到main.c文件,同时在主页面已经打开了该文件的文本编辑框。我们在新建的main.c文件中输入以下代码:
  1. 1  #include "stdio.h"
  2. 2  #include "xparameters.h"
  3. 3  #include "xil_printf.h"
  4. 4  #include "breath_led_ip.h"
  5. 5  #include "xil_io.h"
  6. 6  #include "sleep.h"
  7. 7  
  8. 8  #define  LED_IP_BASEADDR   XPAR_BREATH_LED_IP_0_S0_AXI_BASEADDR  //LED IP基地址
  9. 9  #define  LED_IP_REG0       BREATH_LED_IP_S0_AXI_SLV_REG0_OFFSET  //LED IP寄存器地址0
  10. 10 #define  LED_IP_REG1       BREATH_LED_IP_S0_AXI_SLV_REG1_OFFSET  //LED IP寄存器地址1
  11. 11
  12. 12 //main函数
  13. 13 int main()
  14. 14 {
  15. 15    int freq_flag;      //定义频率状态,用于循环改变呼吸灯的呼吸频率
  16. 16    int led_state;      //定义LED灯的状态
  17. 17
  18. 18  xil_printf("LED User IP Test!\n");
  19. 19  while(1){
  20. 20      //根据freq_flag的标志位,切换呼吸灯的频率
  21. 21      if(freq_flag == 0){
  22. 22       BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR,LED_IP_REG1,0x800000ef);
  23. 23          freq_flag = 1;
  24. 24      }
  25. 25      else{
  26. 26       BREATH_LED_IP_mWriteReg(LED_IP_BASEADDR,LED_IP_REG1,0x8000002f);
  27. 27          freq_flag = 0;
  28. 28      }
  29. 29      //获取LED当前开关状态   1:打开  0:关闭
  30. 30      led_state = BREATH_LED_IP_mReadReg(LED_IP_BASEADDR,LED_IP_REG0);
  31. 31      //如果开关关闭,打开呼吸灯
  32. 32      if(led_state == 0){
  33. 33       BREATH_LED_IP_mWriteReg (LED_IP_BASEADDR, LED_IP_REG0, 1);
  34. 34          xil_printf("Breath LED ON\n");
  35. 35      }
  36. 36      sleep(5);
  37. 37      //获取LED当前开关状态   1:打开  0:关闭
  38. 38      led_state = BREATH_LED_IP_mReadReg(LED_IP_BASEADDR,LED_IP_REG0);
  39. 39      //如果开关打开,关闭呼吸灯
  40. 40      if(led_state == 1){
  41. 41       BREATH_LED_IP_mWriteReg (LED_IP_BASEADDR, LED_IP_REG0, 0);
  42. 42          xil_printf("Breath LED OFF\n");
  43. 43      }
  44. 44      sleep(1);
  45. 45  }
  46. 46 }
  47. 47
复制代码

在代码的第8行至第10行,我们对Breath LED IP基地址、寄存器地址0和寄存器地址1进行了宏定义。按住Ctrl键不放,将鼠标移动到这些参数上,单击鼠标左键,会自动跳转到定义这些参数的地方。其中BREATH LED IP寄存器地址0和寄存器地址1位于breath_led_ip.h文件内,这个文件是系统自动为我们生成的。
程序中的main函数实现了每6秒钟(点亮5秒+关闭1秒)打开和关闭LED呼吸灯的开关,并切换LED灯呼吸频率的功能。我们通过BREATH_LED_IP_mReadReg()函数来读取寄存器地址的数据,通过BREATH_LED_IP_mWriteReg()函数来写入寄存器地址的数据,这两个函数同样位于breath_led_ip.h文件中。
在硬件设计的自定义IP核部分中,我们例化breath_led代码的时候,将寄存器0的数据(slv_reg0)连接至呼吸灯的开关控制信号(sw_ctrl),寄存器1的数据高位(slv_reg1[31])连接至呼吸灯频率设置使能信号(set_en),寄存器1的数据低位(slv_reg1[9:0])连接至呼吸灯频率间隔设置(set_freq_step)。因此,在Vitis应用程序中,可以很方便的通过Breath LED IP寄存器地址0和寄存器地址1来控制LED呼吸灯的开关和频率。
值得一提的是,自定义的IP核在导出至Vitis后,对应IP核的库函数也会导入进来,如图 8.4.2所示:
阿莫论坛发帖达芬奇专用117973.png

图 8.4.2 Breath LED IP库函数

8.5下载验证
首先我们将下载器与达芬奇开发板上的JTAG接口连接,下载器另外一端与电脑连接。然后使用USB连接线将USB_UART接口与电脑连接,用于串口通信。最后连接开发板的电源,并打开电源开关。
打开Vitis的Terminal,设置并连接串口后,开始下载程序。
程序下载完成后,在下方的Vitis Terminal中可以看到应用程序打印的信息,如图 8.5.1所示:
阿莫论坛发帖达芬奇专用118252.png

图 8.5.1 Vitis Terminal窗口打印字符

此时观察开发板可以发现,开发板上的LED0(LED)每6秒钟LED灯的呼吸频率切换一次,在此切换频率之前,LED灯会熄灭一秒钟。如图 8.5.2所示:
阿莫论坛发帖达芬奇专用118452.png

图 8.5.2 开发板实验现象

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 09:55

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表