Zynq |
您所在的位置:网站首页 › ps中的扩展在哪个地方设置 › Zynq |
目录 1、MIO 配置以及寄存器 2、工程中的配置 3、使用 MIO-GPIO 3.1、GPIO 硬件描述 3.2、GPIO 寄存器描述 3.2.1、MASK_0_LSW、MASK_0_MSW 3.2.2、Data_0 3.2.3、Data_0_RO 3.2.4、DIRECTION_0 3.2.5、OP_ENABLE_0 3.2.6、INT_ 3.3、代码 1、MIO 配置以及寄存器 Zynq 7020 的 PS 端(ARM 端)的外设 IO(也叫 IOP)分为 MIO 和 EMIO,他们有什么区别呢? 首先他们都是 PS 端的 IO 资源,MIO 有 54 个 Pin 脚,分为两个 Bank(Bank0、Bank1)是 PS 直接的管脚连接,可以接诸如 UART、SPI、IIC、GPIO 等具体的外设引脚; EMIO 也是 PS 的资源,它接到了 PL 端,由 PL 端输出信号; 这里,我们可以简单的理解为,MIO 是可以通过 Pinmux 配置而直接连接到 PS 端外设的管脚,而 EMIO 是连接到 PL 端用于扩展的引脚; 外设的 MIO/EMIO 的链接如下所示: 这里,我们暂时只关心 MIO(后续看 EMIO),MIO 分为了两个 Bank(Bank0、Bank1),这两个 Bank 分别叫做 Bank 500 和 Bank 501,他们可以配置为不同的电压等级; 注意,这个是电压等级的 Bank,与后面的 GPIO bank 作区分; Bank 500:MIO[15:0] Bank 501:MIO[16:53] 提供 54 个 MIO 资源; 根据管脚复用的配置以及外设相关的资源,整个可实现的配置如下所示 MIO 的管脚复用配置逻辑如下所示: 每一路的 MIO(从 MIO[0] ~ MIO[53])都有一个这样的逐级配置,L3 的 MUX 结果可以作为 L2 MUX 的输入......最后配置出来成为最后的管脚; 举个例子,直接看寄存器; MIO 配置的寄存器位于系统控制寄存器 slcr: 在 slcr 中: 很多类似这样的寄存器:slcr.MIO_PIN_[PIN_MUN] 其中的 PIN_MUN 就是每个 MIO 的编号,从 0 到 53,一共 54 个; 每一个的寄存器内容大致一样,我们随便抓一个看:MIO_PIN_00: 可以看到,每个 MIO 都可以配置是否上拉,电平标准(同一个 Bank 500 或者 Bank 501 电平标准必须一致),还有就是 Level 0 ~ Level 3 的 MUX,这个就是对应的上面那个 4 级 MUX 图的; DisableRcvr:HSTL 的配置,是 High Speed Transceiver Logic 的简写,这个域是配置 MIO 的 HSTL 的; PULLUP:配置 Piin 脚是否带上拉; IO TYPE:配置 IO 的电平标准; Speed:配置速度; L3_SEL:配置管脚复用 L3 逻辑,参考管脚复用的 MIO Signal Routing 那个图; L2_SEL:配置管脚复用 L2 逻辑,参考管脚复用的 MIO Signal Routing 那个图; L1_SEL:配置管脚复用 L1 逻辑,参考管脚复用的 MIO Signal Routing 那个图; L0_SEL:配置管脚复用 L0 逻辑,参考管脚复用的 MIO Signal Routing 那个图; TRI_ENABLE:用于配置 MIO 是否三态; 注意:这个是 slcr 寄存器的配置,关于所有 slcr 寄存器的配置,都需要往 slcr.SLCR_UNLOCK 寄存器(0xF8000008)写入 0xDF0D,来解锁 slcr 寄存器的写权限; 具体工程中,我们使用 Vivado 进行配置,首先创建 Block Design 来生成一个 PS: 双击这个大的 ZYNQ 图标,进入配置界面: 选择红色部分,并配置每个 IO 的管脚复用,并选择好他的电平标准(绿色); 配置时钟,板载 33.333333 MHZ,使用 6:2:1 时钟比例(参考 ZYNQ 时钟子系统) 配置完毕,并导出硬件,Launch SDK; 3、使用 MIO-GPIO 硬件原理图中 PS 端的 LED 连接如下: 分别使用了 MIO0_LED 和 MIO13_LED,都属于 Bank 500(V3.3),此刻,我们如果想点个灯,那么需要将其配置为输出,并置 0 即可导通; 3.1、GPIO 硬件描述UG585 的 Chapter 14 就是 PS 的 GPIO 的使用说明(这里包含了 MIO 和 EMIO,这一章,我们看 MIO) 它支持 MIO 和 EMIO 的配置,MIO 分为 2 个 IO Bank (0~1),EMIO 也分为 2 个 IO Bank(2~3): GPIO 支持中断输入和正常的写和读:INT 开头的,是中断配置: 针对每一个pin,它都有如下寄存器: 注意:如果 MIO 的 TRI_ENABLE 这个被设置为 1,那么输出就为 3 态了; 3.2、GPIO 寄存器描述每个 GPIO Bank 提供了一组寄存器用来描述他的行为,一共 4组,我们以 GPIO Bank 0 为例: GPIO Bank 0 一共有 32bits 根信号; 3.2.1、MASK_0_LSW、MASK_0_MSWZynq 针对 GPIO 的操作,增加了一组方式,以避免对 32bit 寄存器进行读改写的操作,它的方式是将(以 GPIO Bank0 为例)的 32bit 的信号(对应 32 个 IO)分为两组,每组代表 16 bits 的 IO 信号,用两个寄存器描述: 高 16 位使用叫 MASK_0_MSW 的寄存器描述:低位 16 位使用叫 MASK_0_LSW 的寄存器描述: 他们分别有两个域,一个 Mask 域,一个 Data 域,Zynq 使用 MASK + DATA 的方式,来避免对 GPIO 寄存器的读改写;用法是: 往 Mask 中写入 1 的位置,不会被对应的 Data 中的写入改变;换句话来说,16 bit 信号中,可以选择哪些信号被 Mask,Mask 中被写入了 1 的信号,即便是 在 Data 域写入任何值, GPIO 的电平状态都不会被改变;举个栗子: 往 MIO[0] 写 1,那么就可以配置寄存器 MASK_0_LSW 寄存器的值为:0xFFF70001; 意思是,除了 MIO GPIO0 以外的其他的 1~15 都被 Mask,你往里面写什么,都无效; 3.2.2、Data_0 当然,你也可以使用读改写的方式来对 IO 进行配置,直接配置 Data_0 寄存器就可以(以 GPIO Bank0 为例): 3.2.3、Data_0_RO 当然,也可以读 GPIO 的电平值,通过直接读取 Data_0_RO 寄存器(以 GPIO Bank0 为例): 3.2.4、DIRECTION_0 GPIO 呢,当然要配置它的方向,即,输入还是输出(以 GPIO Bank0 为例): 3.2.5、OP_ENABLE_0 如果 GPIO 配置为输出了后,要真的输出信号,要配置这个输出使能寄存器(以 GPIO Bank0 为例): 3.2.6、INT_ 这个是 IO 输入中断相关的配置以后用到中断在仔细介绍; 3.3、代码 Xilinx SDK 关于 GPIO 的操作,有专门的 API 接口(其实就是按照前面的寄存器配置逻辑来配置),按照具体的硬件原理图的 LED(MIO_0 和 MIO_13),代码如下: XGpioPs Gpio; #define STEPH_MIO_0 0 #define STEPH_MIO_1 13 #define MIO_OUTPUT 1 #define MIO_INPUT 0 #define MIO_OUTPUT_EN 1 #define MIO_OUTPUT_DIS 0 uint32_t Steph_LEDInit(void) { XGpioPs_Config *ConfigPtr = NULL; int Status = XST_SUCCESS; ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID); if(!ConfigPtr) { xil_printf("XGpioPs_LookupConfig Error.\r\n"); return XST_FAILURE; } Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr); if (Status != XST_SUCCESS) { xil_printf("XGpioPs_CfgInitialize Error.\r\n"); return XST_FAILURE; } XGpioPs_SetDirectionPin(&Gpio, STEPH_MIO_0, MIO_OUTPUT); XGpioPs_SetDirectionPin(&Gpio, STEPH_MIO_1, MIO_OUTPUT); XGpioPs_SetOutputEnablePin(&Gpio, STEPH_MIO_0, MIO_OUTPUT_EN); XGpioPs_SetOutputEnablePin(&Gpio, STEPH_MIO_1, MIO_OUTPUT_EN); xil_printf("Steph_LED Initialize Finished...\r\n"); return Status; } void LED_ON(uint32_t led_pin) { XGpioPs_WritePin(&Gpio, led_pin, 0x0); } void LED_OFF(uint32_t led_pin) { XGpioPs_WritePin(&Gpio, led_pin, 0x1); }相关代码和工程在 gitee 持续更新: https://gitee.com/stephenzhou-tech/Zynq7020_PS |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |