[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_SDK入门篇连载-18 PL AXI-GPIO实验

文档创建者:FPGA课程
浏览次数:161
最后更新:2024-09-27
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-SOC » 1_SDK应用方案(仅旗舰型号) » 1-SDK基础入门方案
本帖最后由 FPGA课程 于 2024-9-27 16:24 编辑

​ 软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!



1概述
本文介绍VIVADO自带IP AXI-GPIO扩展PS IO的使用。我们在前面的文章中通过EMIO实现过扩展PS的IO,通过EMIO的方式实际上IO控制器还是用PS的。那么AXI-GPIO更多是使用FPGA资源实现的IO的扩展。并且很多应用中,我们会把AXI-GPIO的控制信号用于FPGA内部逻辑和PS之间的数据交互,比如通过AXI-GPIO输出复位信号,或者通过AXI-GPIO的输入中断,扩展出更多中断。
在本文的demo中,我们将实现通过AXI-GPIO扩展2个IO实现LED驱动,以及2个IO实现按键输入,并且通过按键输入产生2个GPIO中断。
本文实验目的:
1:通过阅读pg144-axi-gpio.pdf熟悉AXI-GPIO的硬件资源(配套工程的soc_prj/06_doc路径)
2:通过VIVADO搭建AXI-GPIO的SOC工程,通过按键模拟输入、LED模拟输出
3:使用VITIS-SDK编写AXI-GPIO测试程序,完成GPIO输入、输入中断、输出测试
2系统框图
9d49cc572ba141538600e9ae4a2e22cd.jpg
3AXI-GPIO IP概述
AXI-GPIO IP通过AXI-Lite-slave连接到PS。具体2个通道,每个通道32个GPIO。在IP里面可以固定配置为输入或者输出,也可以通过软件控制寄存器配置为输入或者输出。并且支持中断输入,AXI-GPIO的构架如下图所示。
03c2084f7ff141d29fdc00512eb0949a.jpg
3.1特性
-支持axis4 - lite接口规范
-支持可配置的单或双GPIO通道
-支持GPIO引脚1 ~ 32位的通道宽度配置
-支持动态规划每个GPIO位作为输入或输出
-支持每个通道的单独配置
-支持所有寄存器的每个位的独立重置值
-支持可选的中断请求生成
3.2寄存器说明
1:数据寄存器GPIOx_DATA
有两个GPIO数据寄存器(GPIO_DATA和GPIO2_DATA),每个通道对应一个。通道1数据寄存器(GPIO_DATA)始终存在;通道2数据寄存器(GPIO2_DATA)只有当IP配置为双通道(Enable dual channel = 1)时才存在。
af6af6694ad34d3f80306bdf1d3f65b7.jpg
dd8e989a774640f2955e2dc56e4829f6.jpg
2:三态寄存器GPIOx_TRI
有两个AXI GPIO 3-state控制寄存器(GPIO_TRI和GPIO2_TRI),每个通道对应一个。通道2 3状态控制寄存器(GPIO2_TRI)只有在IP配置为双通道使能双通道= 1时才存在。
2bd1fc73761b456494b71b7b3c1d0eed.jpg
3:全局中断使能寄存器(GIER)
设置31bit位为1使能中断。
7837ffaf0ab348e8a81754800039f03b.jpg
81da43c5047943f3aca1eb44f4262bb4.jpg
4:IP-CORE中断使能寄存器(IPIER)
9ca6e0b9f6694b5cbfc626c8ed3e04e7.jpg
7b186030e6d9404985cbe7ac641ecade.jpg
5:IP状态寄存器(IPISR)
232dbf0ac8ac46c2ad99f2e065aa17ff.jpg
d16688899b7040b8a024ed000bab223a.jpg
4硬件电路分析
d98fab137273404898e9558af2daf4a2.jpg
这里使用按键输入BTN3和BTN4,配套工程的FPGA PIN脚定义路径为soc_prj/uisrc/04_pin/ fpga_pin.xdc。
5搭建SOC系统工程
详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建SOC工程的,请学习“01Vitis Soc开发入门”这篇文章。
5.1SOC系统工程
135013dcc84446cea35ddb211a2ed12e.jpg
1:中断设置
f6dabc057cca4ab880c261c4beabf477.jpg
2:设置GP Master接口
a4d7283360b94e2e8dec703322652261.jpg
3:设置复位输出
dc69592a0a2f4da19c4f83ad50dec4e4.jpg
4:设置PL时钟
95084024b77346bda3700803eeedf005.jpg
5:AXI-GPIO
输出输出各设置2bit,支持中断
f8e7373a5b08446e89f229de8cfbdf34.jpg
5.2设置AXI外设地址分配
从本节课开始,只要添加的AXI总线外设都要正确分配地址
806fedbfe81c4e0b8cfded2fe37ee928.jpg
5.3编译并导出平台文件
以下步骤简写,有不清楚的看第一篇文章。
1:单击Block文件à右键àGenerate the Output ProductsàGlobalàGenerate。
2:单击Block文件à右键à Create a HDL wrapper(生成HDL顶层文件)àLet vivado manager wrapper and auto-update(自动更新)。
3:添加配套工程路径下uisrc/04_pin/fpga_pin.xdc约束文件
4:生成Bit文件。
5:导出到硬件: FileàExport HardwareàInclude bitstream
6:导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:system_wrapper.xsa的文件。根据硬件平台文件system_wrapper.xsa来创建需要Platform平台。
18cf199ed9d9440daa18b28808afa446.jpg
6搭建Vitis-sdk工程
创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。
6.1创建SDK Platform工程
9572545cb56048f797b9ec0a699bf700.jpg
右击soc_base编译,编译的时间可能会有点长
6.2创建APP工程
6a32ebf67c114e69a9dc21fef1da8983.jpg
7程序分析
在前面文章文章中,我们已经使用过PS的中断,比如GPIO中断、定时器中断、看门狗中断、I2C中断等等。其中关于sys_intr.c中的函数都做了详细介绍。所以本文开始不再介绍sys_intr.c中的函数。
7.1axi_gpio_test.c测试程序
  1. #include "sys_intr.h"
  2. #include "axi_gpio_intr.h"
  3. #include "sleep.h"

  4. void init_intr_sys(void)
  5. {

  6.         Gpiopl_init(&Gpio, AXI_GPIO_DEV_ID);//初始化GPIO

  7.         Init_Intr_System(&Intc); //初始化系统中断

  8.         Gpiopl_Setup_Intr_System(&Intc, &Gpio, GPIO_INTR_ID); //设置GPIO中断

  9.         Setup_Intr_Exception(&Intc);
  10. }

  11. int main(void)
  12. {
  13.         init_intr_sys();

  14.         while(1)
  15.         {
  16.                 if(gpio_intr_flag) //判断中断是否发生,当中断发生后,读取中断,并且打印产生中断的按键号
  17.                 {
  18.                         gpio_intr_flag = 0; //清除中断标志
  19.                         XGpio_DiscreteWrite(&Gpio,2,gpio_val); //用按键的输入去点亮LED
  20.                         printf("SW=%d int\n\r", gpio_val);
  21.                 }

  22.         }
  23.         return XST_SUCCESS;
  24. }
复制代码

7.2axi_gpio_intr.c程序
  1. #include "axi_gpio_intr.h"

  2. volatile u32 gpio_intr_flag;
  3. volatile u32 gpio_val;

  4. //中断回调函数
  5. void GpioplIntrHandler(void *Callback)
  6. {
  7.         XGpio *GpioPtr = (XGpio *)Callback;
  8.         u32 IrqStatus;

  9.         IrqStatus = XGpio_InterruptGetStatus(GpioPtr); //获取中断状态

  10.         if((IrqStatus & 0x01) == 0x01)
  11.         {
  12.                 gpio_val = XGpio_DiscreteRead(GpioPtr, 1); //GPIO中断需要读按键状态知道哪一个按键产生了中断
  13.                 gpio_intr_flag = 1; //设置中断标志
  14.         }

  15.         XGpio_InterruptClear(GpioPtr, IrqStatus); //清除中断

  16. }

  17. //设置中断
  18. void Gpiopl_Setup_Intr_System(XScuGic *GicInstancePtr, XGpio *InstancePtr, u16 IntrId)
  19. {
  20.         XScuGic_Connect(GicInstancePtr, IntrId, //设置中断回调函数
  21.                         (Xil_ExceptionHandler)GpioplIntrHandler,
  22.                         (void *)InstancePtr);

  23.         XScuGic_Enable(GicInstancePtr, IntrId);//使能中断号指定的中断

  24.             XGpio_InterruptEnable(InstancePtr, 0x01);//使能中断

  25.             XGpio_InterruptGlobalEnable(InstancePtr); //使能全局中断

  26. }

  27. int Gpiopl_init(XGpio *InstancePtr, u32 DeviceId)
  28. {

  29.         int Status;
  30.         /* Initialize AXI GPIO */
  31.         Status = XGpio_Initialize(InstancePtr, DeviceId);
  32.         if (Status != XST_SUCCESS) {
  33.                 xil_printf("AXI GPIO config failed!\r\n");
  34.                 return XST_FAILURE;
  35.         }

  36.         XGpio_SetDataDirection(InstancePtr, 1, 0x3);//设置GPIO通道1用于输入

  37.         XGpio_SetDataDirection(InstancePtr, 2, 0x0); //设置GPIO通道2用于输出


  38.     return 1;
  39. }
复制代码

在初始化函数中,设置channel1 的2个IO为输入,channel2 的2个IO为输出
7ac1021b62784b2ea95032624992db6a.jpg
在Gpiopl_Setup_Intr_System(XScuGic *GicInstancePtr, XGpio *InstancePtr, u16 IntrId)函数中主要是对,AXI-GPIO的全局中断使能寄存器GIER和IPIER中断使能寄存器进行设置
74a62a99749342c6a59ab61421577043.jpg
当GPIO的电平状态发生改变就会触发中断,回调函数中,首先读取AXI-GPIO的状态寄存器,然后判断是否是channel1产生的中断。之后读取GPIO的按键输入状态,设置中断触发变量为1。最后清除中断。
97c0294ff3534ac68f1216ad75680e56.jpg
8方案演示
8.1硬件准备
本实验需要用到 JTAG 下载器、USB 转串口外设,另外需要把核心板上的 2P 模式开关设置到 JTAG 模式,即 ON ON(注意新版本的 MLK_H3_CZ08-7100-MZ7100FC),支持 JTAG 模式,对于老版本的核心板,JTAG 调试的时候 一定要拔掉 TF 卡,并且设置模式开关为 OFF OFF)

375dd162f58f4ac4a0c4ca55e8ef8519.jpg
8.2实验结果
除了通过串口观察按键中断的结果,而且可以通过LED观察。每次按下按键产生一个中断,每次松开按键也会产生一个中断。总之,只要按键的状态发生改变就会产生中断。
8b7ff7f26d524990a72aaf0f360b4b7b.jpg














您需要登录后才可以回帖 登录 | 立即注册

本版积分规则