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

本文档详细介绍了如何在ZYNQ7020芯片上创建和编辑自定义IP核,实现通过AXI总线由PS控制PL的PWM功能,以控制三色灯D34实现动态占空比的呼吸灯效果。步骤包括新建Vivado工程,添加ZYNQ核,创建和编辑AXI PWM IP,分配管脚,以及在SDK中编写应用代码控制PWM输出。最终通过生成BOOT.bin文件并烧录到开发板,成功实现了PWM呼吸灯功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

 

 

 

### 如何在ZYNQ平台上的Linux系统中配置和使用PWM #### 1. PWM模块简介 ZYNQ 平台集成了丰富的外设接口,其中包括AXI Timer IP,该IP不仅提供定时功能还支持PWM信号生成[^1]。通过合理配置,可以在PL(可编程逻辑)部分实现PWM控制,并且可以通过PS(处理系统)中的Linux操作系统对其进行管理。 #### 2. 硬件设计准备 为了使能PWM功能,在硬件层面需利用Vivado工具完成如下工作: - 创建一个新的项目并导入ZYNQ芯片型号; - 添加AXI_Timer IP到Block Design中作为PWM控制器; - 设置好相应的参数如频率、分辨率等; - 将GPIO引脚连接至LED或其他负载用于输出PWM波形; - 完成Bitstream文件编译后导出HDF(Hardware Definition File),以便后续加载入SDK(Software Development Kit)[^2]。 #### 3. Linux内核配置与驱动编写 当上述硬件准备工作完成后,则进入软件开发环节: ##### a. 修改设备树(Device Tree) 由于ZYNQ采用的是DeviceTree机制来描述硬件资源分配情况,因此需要编辑对应的.dtsi文件以声明新加入的PWM节点及其属性设置。具体操作包括但不限于指定兼容字符串(compatible property),定义寄存器基地址(reg property)以及中断线路(interrupts property)等重要信息。 ##### b. 编写Platform Device Driver 对于基于ARM架构运行的Linux系统而言,所有的外围组件都视为platform device类型。这意味着每当启动过程中遇到此类实体时都会自动触发关联driver实例化过程。为此目的而专门撰写的C源码应当遵循标准框架结构,即包含probe函数负责初始化流程,remove方法用来清理释放占用资源等等[^3]。 ```c static int __init pwm_driver_init(void){ printk(KERN_INFO "PWM driver initialized\n"); platform_driver_register(&pwm_platform_driver); } module_init(pwm_driver_init); static void __exit pwm_driver_exit(void){ platform_driver_unregister(&pwm_platform_driver); printk(KERN_INFO "PWM driver removed\n"); } module_exit(pwm_driver_exit); ``` ##### c. 用户空间API调用 最终应用程序可通过sysfs接口或者字符设备方式访问底层PWM服务。前者允许直接读取/修改特定路径下的文件从而达到调整占空比(duty cycle)的目的;后者则提供了更加灵活多样的交互模式供开发者选择适合自己的方案实施细粒度调控策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllenSun-1990

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值