草庐IT

ZYNQ7020:PS控制PL动态调整PWM占空比

AllenSun-1990 2023-05-15 原文

ZYNQ7020芯片要发挥双处理器的协同作用,就要PS通过AXI总线来动态控制PL。要实现这个功能,就要创建一个IP核,PS端通过对寄存器地址的读写来实现对PL的控制。本实验采用米尔科技的Z-TURN(MYS-7Z020)开发板,控制三色灯 D34实现PS端占空比动态可调的PWM呼吸灯。

1 新建一个 Vivado 工程,命名为custom_pwm_ip,芯片选择:

 2 添加 PS 的 IP 核并配置
点击这个 Add IP 添加 IP 核

输入 zynq,然后双击添加 zynq 核

双击 ZYNQ 核导入配置文件
 

这里导入的是custom_pwm_ip.tcl配置文件,可使用官方提供的axi_gpio.tcl 配置文件(重命名即可)。
 

3 创建自定义 IP
1) 点击菜单“Tools->Create and Package IP...”

2) 选择“Next”
 

3) 选择创建一个新的 AXI4 设备
 

4) 名称填写“ax_pwm” ,描述填写“alinx pwm”,然后选择一个合适的位置用来放 IP(默认位置即可,名称和描述可以根据自己的需要来改写,这里直接使用了alinx的项目命名)


 5) 下面参数可以指定接口类型、寄存器数量等,这里不需要修改,使用 AXI Lite Slave 接口, 4
个寄存器。

6) 点击“Finish”完成 IP 的创建
 7) 在“IP Catalog”中可以看到刚才创建的 IP

 

8) 这个时候的 IP 只有简单的寄存器读写功能,我们需要修改 IP,选择 IP,右键“Edit in IP
Packager
 

9) 这是弹出一个对话框,可以填写工程名称和路径,这里默认,点击“OK”
 

10) Vivado 打开了一个新的工程
 11) 添加 PWM 功能的核心代码

12) 添加代码时选择复制代码到 IP 目录
 13) 修改“ax_pwm_v1_0.v”,添加一个 pwm 输出端口

14) 修改“ax_pwm_v1_0.v”,在例化“ax_pwm_V1_0_S00_AXI” ,中添加 pwm 端口的例化
 

15) 修改“ax_pwm_v1_0_s00_AXI.v”文件,添加 pwm 端口,这个文件是实现 AXI4 Lite Slave 的
核心代码
 

16) 修改“ax_pwm_v1_0_s00_AXI.v”文件,例化 pwm 核心功能代码,将寄存器 slv_reg0 和 slv_reg1用于 pwm 模块的参数控制。
 

17) 双击“component.xml”文件
 

18) 在“File Groups”选项中点击“Merge changers from File Groups Wizard”
 

19) 在“Customization Parameters”选项中点击“Merge changes form Customization Parameters
Wizard
 

20) 点击“Re-Package IP”完成 IP 的修改
 

4 添加自定义 IP 到工程
 1) 搜索“pwm”,添加“ax_pwm_v1.0

 

2) 点击“Run Connection Automation”
 

3) 导出 pwm 端口
 

最后的Diagram如下图所示: 4) 保存设计,并 Generate Output Products

5) 添加 xdc 文件分配管脚,把 pwm_0 输出端口分配给三色灯的一个Pin脚,做一个呼吸灯

(三色灯 D34对应的三个Pin脚:R14、Y16、Y17)

set_property IOSTANDARD LVCMOS33 [get_ports pwm_0]
set_property PACKAGE_PIN Y16 [get_ports pwm_0]

 

6) 编译生成 bit 文件,导出硬件
 

5 启动 SDK, 新建 fsbl
 点击菜单栏上的 File->Launch SDK->OK 启动 SDK

 

点击 File->Application Project 新建工程
 

输入工程名为 fsbl
 

选择 Zynq FSBL
 

生成的 fsbl 如下图所示
 

6 新建一个 custom_pwm_ip 工程
点击 File->Application Project 新建工程
 

输入工程名 custom_pwm_ip(注意:Board Support Package选择:Use existing fsbl_bsp)


 

 选择 hello_world 工程模板

新建 custom_pwm_ip工程完成后, 如下图所示
 

先看看 APP 的目录下的资源,可以找到一个 ax_pwm.h 的文件,这个文件里包含
里对自定义 IP 寄存器的读写宏定义
 在 bsp 里找到“xparameters.h”文件,这个非常重要的文件,里面找到了自定 IP 的寄存器
基地址,可以找到自定义 IP 的基地址。
 

有个寄存器读写宏和自定义 IP 的基地址,我们开始编写代码,测试自定义 IP,我们先通过
写寄存器 AX_PWM_S00_AXI_SLV_REG0_OFFSET,控制 PWM 输出频率,然后通过写寄存器
AX_PWM_S00_AXI_SLV_REG1_OFFSET 控制 PWM 输出的占空比。

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "ax_pwm.h"
#include "xil_io.h"
#include "xparameters.h"
#include "sleep.h"

unsigned int duty;

int main()
{
    init_platform();

    print("Hello World\n\r");

	//pwm out period = frequency(pwm_out) * (2^N) / frequency(clk);
	AX_PWM_mWriteReg(XPAR_AX_PWM_0_S00_AXI_BASEADDR, AX_PWM_S00_AXI_SLV_REG0_OFFSET, 17179);//200hz
	//duty = (2^N) * (1 - (duty cycle)) - 1
	while (1) {
		for (duty = 0x8fffffff; duty < 0xffffffff; duty = duty + 100000) {
			AX_PWM_mWriteReg(XPAR_AX_PWM_0_S00_AXI_BASEADDR, AX_PWM_S00_AXI_SLV_REG1_OFFSET, duty);
			usleep(100);
		}
	}

    cleanup_platform();
    return 0;
}

 7 生成 BOOT.bin 文件
右击 custom_pwm_ip ->Create boot Image

 

点击 Create Image, 生成 BOOT.bin 启动文件
 

将这个 BOOT.bin 文件拷贝到 TF 卡
开发板打到 SD 卡启动模式, JP2 闭合、 JP1 断开
程序运行后可以看到三色灯 D34 会不停闪烁
 

 按开发板的 RESET 复位按键可以看到串口打印 Hello World

 

 

 

 

有关ZYNQ7020:PS控制PL动态调整PWM占空比的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  5. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

  6. ruby - 在 Ruby 中动态创建数组 - 2

    有没有办法在Ruby中动态创建数组?例如,假设我想遍历用户输入的书籍数组:books=gets.chomp用户输入:"TheGreatGatsby,CrimeandPunishment,Dracula,Fahrenheit451,PrideandPrejudice,SenseandSensibility,Slaughterhouse-Five,TheAdventuresofHuckleberryFinn"我把它变成一个数组:books_array=books.split(",")现在,对于用户输入的每一本书,我想用Ruby创建一个数组。伪代码来做到这一点:x=0books_array.

  7. ruby - 是否可以将 IRB 提示配置为动态更改? - 2

    我想在IRB中浏览文件系统并让提示更改以反射(reflect)当前工作目录,但我不知道如何在每个命令后进行提示更新。最终,我想在日常工作中更多地使用IRB,让bash溜走。我在我的.irbrc中试过这个:require'fileutils'includeFileUtilsIRB.conf[:PROMPT][:CUSTOM]={:PROMPT_N=>"\e[1m:\e[m",:PROMPT_I=>"\e[1m#{pwd}>\e[m",:PROMPT_S=>"FOO",:PROMPT_C=>"\e[1m#{pwd}>\e[m",:RETURN=>""}IRB.conf[:PROMPT_MO

  8. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  9. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

  10. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

随机推荐