学习内容 前面简单学习了关于gpio的操作,本次将使用pl 端调用 axi gpio ip 核, 并通过 axi4-lite 接口实现 ps 与 pl 中 axi gpio 模块的通信。
开发环境 vivado 18.3sdkpynq-z2
axi_gpio简介
axi gpio ip 核为 axi 接口提供了一个通用的输入/输出接口。与 ps 端的 gpio 不同, axi gpio 是一个软核( soft ip),即 zynq 芯片在出厂时并不存在这样的一个硬件电路, 而是由用户通过配置 pl 端的逻辑资源来实现的一个功能模块。而 ps 端的 gpio 是一个硬核( hard ip) ,它是一个生产时在硅片中实现的功能电路。我们之前驱动的mio接口,他属于ps端口的一个搭载好的硬件资源,而对于axi_gpio这样一个ip核来说他就相当于与在pl的逻辑端口实现了一个软核ip的gpio接口。axi 接口作为 zynq ps 和 pl 之间的桥梁, 能够使两者协同工作,进而形成一个完整的、 高度集成的系统。axi gpio 可以配置成单通道或者双通道, 每个通道的位宽可以单独设置。另外通过打开或者关闭三态缓冲器, axi gpio 的端口还可以被动态地配置成输入或者输出接口。其顶层模块的框图如下所示:
模块的左侧实现了一个 32 位的 axi4-lite 从接口, 用于主机访问 axi gpio 内部各通道的寄存器。当右侧接口输入的信号发生变化时,模块还能向主机产生中断信号。不过只有在配置 ip核时选择“ 使能中断” , 才会启用模块的中断控制功能。
我们可以在xilinx的一个说明书(ug144)中详细的看到关于axi_gpio ip的具体的寄存器,对于不同功能的配置我们只需要像在arm开发中进行寄存器的配置即可,但寄存器的操作过于繁琐,在一般的开发过程中我们通常进行的都是库函数的使用调用。
在文档中我们可以看到ip的以下特点,基本包含了硬件gpio的所有功能。设置输入输出模式,设置中断等。
引脚说明表如下,在这个表中,大致分为了两类,第一类s_axi接口的相关引脚,用于配置挂载到axi总线,s_axi_*这是一组信号接口,用于进行数据的交互和配置;第二类是和gpio有关的信号接口,这里的ip中有两组gpio,每组输出三个信号经过一个三态缓存器实现三态输出。为了实现中断功能,这里的ip2intc_irpt是中断的敏感信号。
编程指南 同样在ug144中我们可以找到对于axi_gpio ip在应用开发的时候的一个编程指南
设置带中断的input 将端口配置为输入,将相应的位写入gpiox_tri寄存器,值为1。 通过设置ip中断使能中相应的位使能通道中断注册;也可以通过设置全局中断的第31位来启用全局中断注册为1。 当接收到中断时,读取gpiox_data寄存器中相应的位。通过写入值为1的对应位来清除ip中断状态寄存器中的状态。 这里的编程指南描述的是寄存器的配置流程,在我们的实际应用中简单来说就是调用库函数配置端口为输入,然后进行中断功能的注册(类似前文的gpio的按键中断)。
配置为普通的input 将端口配置为输入,将相应的位写入gpiox_tri寄存器,值为1。 读取gpiox_data寄存器中相应的位。 配置为普通的output 通过在gpiox_tri寄存器中写入值为0的对应位,将端口配置为输出。 将相应的位写入gpiox_data寄存器。 工程系统框图 实现功能为使用emio的引脚驱动led,使用axi_gpio的ip进行按键控制,当我们按键按下时,我们的led进行一次反转。
硬件平台搭建 同样重复前面的步骤,打开vivado工具的block design 添加zynq的ip核,完成基础配置。
然后打开mio configuration,对emio引脚的led进行配置
因为这里我们要使用axi_gpio的中断功能,所以我们打开中断界面进行配置,开启中断后,勾选pl到ps的中断功能。这里的中断标号有16个,对应原则是[15:0]对应的是[91:84]:[68:61],这里我们只使用了一个中断,所以我们的中断标号是61。
配置完成后添加axi_gpio的ip核。配置使能中断,gpio的位宽选择为1即可。
完成配置后得到下图点击运行自动连接,可以进行帮助我们进行对应端口的自动连接:
自动连接完成后如图所示:
这里工具帮助我们完成了大部分的连接,但是没有帮助我们进行中断功能的连线,我们需要手动进行连接。
手动连接完成:
完成设计后,我们进行generate output product 然后生成hdl封装。接着就对应引脚进行引脚约束即可(pynq的粉色开发板可以直接引用这个约束):
set_property -dict { package_pin r14 iostandard lvcmos33 } [get_ports { gpio_0_tri_io[0] }]; #io_l6n_t0_vref_34 sch=led[0]set_property -dict { package_pin d19 iostandard lvcmos33 } [get_ports { axi_gpio0_tri_io[0] }]; #io_l4p_t0_35 sch=btn[0] 完成约束后进行综合布局布线,等待生成bit流文件。bit文件生成后在file处,点击导出硬件资源(包含bit流文件),接着launch sdk。
软件部分编写 这里引用的axi gpio的资源对应的是gpio的部分,配置相应的功能函数可以参考相应的文件和对应的例程。
首先给出我本次的工程代码,在后面进行简要的说明:
#include #include platform.h#include xil_printf.h#include xgpiops.h#include xgpio.h#include xparameters.h#include xparameters_ps.h#include xscugic.h#include sleep.h//设置设备id和io编号#define gpio_id xpar_xgpiops_0_device_id //ps gpio的器件id#define axi_gpio_id xpar_gpio_0_device_id//axigpio的器件id#define scugic_id xpar_ps7_scugic_0_device_id//中断的id//axi gpio的中断号#define axi_gpio_intr_id xpar_fabric_gpio_0_vec_id#define led0 54//axi gpio通道1#define axi_gpio_channel 1//定义调用gpiops的结构体xgpiops gpiops;xgpiops_config *gpio_cfg;//定义调用中断的结构体xscugic gpio_gic;xscugic_config *gpio_gic_cfg;//定义调用gpio的结构体xgpio axi_gpio;//变量声明u32 key_value=0;//函数声明void init_gpio();void intrhandler();int main(){u32 led_status=0; init_platform(); init_gpio(); init_interrupt(); print(axi_gpio test); while(1) { if(key_value==1){ //清除中断状态 if(xgpio_discreteread(&axi_gpio, axi_gpio_channel)==1){ led_status=~led_status; } xgpio_interruptclear(&axi_gpio, 0x0000001); key_value=0; xgpiops_writepin(&gpiops,led0,led_status); usleep(200000); //打开中断使能 xgpio_interruptenable(&axi_gpio, 0x0000001);//使能中断 } } cleanup_platform(); return 0;}//初始化gpiovoid init_gpio(){//查找设备id,gpio初始化操作gpio_cfg=xgpiops_lookupconfig(gpio_id);xgpiops_cfginitialize(&gpiops,gpio_cfg,gpio_cfg->baseaddr);//设置gpio为输出,开启使能xgpiops_setdirectionpin(&gpiops,led0,1);xgpiops_setoutputenablepin(&gpiops,led0,1);//对pl端的gpio进行初始化xgpio_initialize(&axi_gpio,axi_gpio_id);//对axi设置方向xgpio_setdatadirection(&axi_gpio,axi_gpio_channel,0x0000001);//设置为输入}void init_interrupt(){//初始化gicgpio_gic_cfg = xscugic_lookupconfig(scugic_id);xscugic_cfginitialize(&gpio_gic,gpio_gic_cfg,gpio_gic_cfg->cpubaseaddress);//初始化异常处理xil_exceptioninit();//cpu中断异常注册xil_exceptionregisterhandler(xil_exception_id_int,(xil_exceptionhandler)xscugic_interrupthandler,&gpio_gic);//使能处理器中断xil_exceptionenablemask(xil_exception_irq);//链接中断信号xscugic_connect(&gpio_gic,axi_gpio_intr_id,(xil_interrupthandler)intrhandler,&axi_gpio);//使能中断xscugic_enable(&gpio_gic,axi_gpio_intr_id);//0xa0中断优先级xscugic_setprioritytriggertype(&gpio_gic,axi_gpio_intr_id,0xa0, 0x3);//axi gpio使能中断xgpio_interruptglobalenable(&axi_gpio);//打开全局中断xgpio_interruptenable(&axi_gpio, 0x0000001);//使能中断}void intrhandler(){printf(interrupt~~);key_value=1;//关闭中断使能xgpio_interruptdisable(&axi_gpio, 0x0000000);} 部分代码讲解 代码很类似上次的gpio的中断功能的代码,这里只是更改了部分函数对axi gpio的ip进行ip的配置,实现带中断的输入功能的key。axi的初始化只需要一行代码即可完成,然后根据编程指南设置下方向即可完成输入的配置xgpio_initialize(&axi_gpio,axi_gpio_id);//对pl端的gpio进行初始化xgpio_setdatadirection(&axi_gpio,axi_gpio_channel,0x0000001);//对axi设置方向设置为输入对于这里的axi_gpio中断的标号就是我们前面提到的61,在这里我们可以进行define一下,方便我们进行引用。#define axi_gpio_intr_id xpar_fabric_gpio_0_vec_id//axi gpio的中断号在sdk中寻一下这个参数的数据也可以验证我们的标号数值:
对于axi _gpio,我们配置的时候可以看到,每个ip核有两路gpio,这里我们只用了通道1,所以我们的通道编号定义为1 #define axi_gpio_channel 1//axi gpio通道1在配置axi gpio的中断功能时,用的了xscugic_setprioritytriggertype(&gpio_gic,axi_gpio_intr_id,0xa0, 0x3);在寻到该函数定义时候,可以简要了解下参数的配置功能。
0xa0配置了中断优先级,这里我们不进行中断优先级的配置,所以引用的是示例里面的默认值,中断编号就是我们axi gpio的编号,0x03这个值用于配置中断的方式。这里我们的中断有高电平触发和边沿触发模式。我们设置边沿触发后,在我们按下按键会满足两次边沿触发的条件(这里我感觉注释和实际操作不相符),然后回看我们的编程指南,在中断配置时候是也是要求我们:当接收到中断时,读取gpiox_data寄存器中相应的位。通过写入值为1的对应位来清除ip中断状态寄存器中的状态。所以我们就引用了xgpio_discreteread(&axi_gpio, axi_gpio_channel) 对中断的状态进行读取。对应编程指南代码编写如下:
//清除中断状态 if(xgpio_discreteread(&axi_gpio, axi_gpio_channel)==1){ led_status=~led_status; } xgpio_interruptclear(&axi_gpio, 0x0000001); 完成代码编写后下载到我们的pynq的开发板即可完成本次实验。
智能交通有了5G以后有什么不一样的发展趋势
如何通过控制寄存器来点亮LED灯
使用CAN收发器增强您的应用设计
10-6-华为云OBS大数据存算分离方案,助力企业顺利实现数字化转型!
小米9发布让人觉得小米变了,雷军变了
AXI_GPIO简介与使用指南
人形机器人的伺服电机技术探讨
迅为2K1000核心板在能源管理系统产品方案
通过LD和PV阵列优化LPWT系统
美国首个大型海上风电场Vineyard Wind开工建设
研究者提出了一种在氢键铁电体中获得超高压电系数的新思路
英飞凌650V CoolSiC™ MOSFET系列为更多应用带来最佳可靠性和性能水平
服装行业的新型智能科技,智能体感试衣镜已问世
NXP扩展高速CAN收发器产品系列--全新的TJA1042型
中小型集装箱配电系统设计方案
2025年混合动力汽车将占到锂离子电池市场的90%
台铃发布新型无线充电专利技术,InnoGaN正式进军电动车领域
2023华南慕尼黑电子展 & AUTO TECH国际汽车技术展
英特尔放弃10nm工艺,AMD锐龙5代迎强劲对手
机械人必备的图纸技术要求大全