第六章 ZYNQ-MIZ701 GPIO使用之MIO
6.0 本章难度系数★★☆☆☆☆☆
6.1 GPIO简介
Zynq7000系列芯片有54个MIO(multiuse I/O),它们分配在 GPIO 的Bank0 和Bank1隶属于PS部分,这些IO与PS直接相连。不需要添加引脚约束,MIO信号对PL部分是透明的,不可见。所以对MIO的操作可以看作是纯PS的操作。
GPIO的控制和状态寄存器基地址为:0xE000_A000,我们SDK下软件操作底层都是对于内存地址空间的操作。
Bank0:MI0[31:0]
Bank1:MI0[52:53]
Bank2:EMI0[31:0]
Bank3:EMI0[63:32]
6.1.1 GPIO的控制寄存器地址空间
我们在SDK下操作的时候底层都是对这些寄存器的操作,具体的相关参数请参考技术手册ug585-Zynq-7000-TRM.pdf
6.1.2MIO内部构造分析
DATA_RO: 此寄存器使能软件观察PIN脚,当GPIO被配置成输出的时候,这个寄存器的值会反应输出的PIN脚情况。
DATA:此寄存器控制输出到GPIO的值,读这个寄存器的值可以读到最后一次写入该寄存器的值。
MASK_DATA_LSW:位操作寄存器,写入GPIO 低16bit 其他没有改变的位置保存原先的状态
MASK_DATA_MSW:位操作寄存器,写入GPIO 高16bit 其他没有改变的位置保存原先的状态
DIRM:此寄存器控制输出的开关,当DIRM[x]==0时候,禁止输出
OEN: 输出使能,当OEN[x]==0 的时候输出关闭,PIN脚处于三态
因此,如果要读IO状态就得读DATA_RO的值,如果是对某一位进行操作就是写MASK_DATA_LSW/MASK_DATA_MSW
具体的相关参数请参考技术手册ug585-Zynq-7000-TRM.pdf
6.1.3 EMIO的特性
与MIO大部分类似但是一下几点需要注意下
• EMIO在PL部分,输入与OEN寄存器无关,当DIRM设置为0的时候设置为输入可以读DATA_RO寄存器获取数据。
• 输出不能设置成三态,当DIRM设置为1的时候为输出,写入DATA寄存器或者MASK_DATA_LSW/MASK_DATA_MSW寄存器
• EMIOGPIOTN[x]=DIRM[x] & OEN[x],实现输出的控制。
具体的相关参数请参考技术手册ug585-Zynq-7000-TRM.pdf
6.2 电路分析及实验预期
在MiZ702的开发板上有一个MIO是与开发板上的一个LD9相连的,这个MIO就是MIO7。实验通过操作该MIO来实现LD9的闪烁。
6.3 ZYNQ核的添加及配置
Step1:新建一个名为为Miz701_sys的工程
Step2:选择RTL Project 勾选Do not specify source at this time
Step3:选择芯片xc7z010clg400-1。
Step4:单击Finish
6.4使用IP Integrator创建硬件系统
Step1:单击Create Block Design
Step2:输入system
Step3:单击下图中添加IP按钮
Step4:搜素单词z选择ZYNQ7 Processing System,然后双击
Step5:添加进来了ZYNQ CPU IP,双击ZYNQ7 Processing System。
Step6: 修改时钟输入为50MHZ,可以看到ARM时钟为650MHZ DDR为525MHZ(1050MHZ),并且修改FCLK_CLK0 为100MHZ。
Step7: 修改MIO的配置 修改IO电压,增加ENT0 和UART1接口,在这个实验中将会使用到MIO7确保勾选(默认勾选)单击OK退出.
Step8:修改内存型号为MT41K256M16RE-125 M。
Step9:单机Run Block Automation 进行自动连线,VIVADO软件会根据信号的命名规则智能连线。
Step10:勾选如下,直接单机OK
Step11:在你点击了OK后,你会发现DDR以及FICED_IO自劢的延伸出来,然后把时钟FCLK_CLK0和M_AXI_GPI0_ACLK连接。方法:当把鼠标靠近的时候会自动连接。
Step12:为了让以太网PHY RTL8211E-VL可以工作,必须让其复位PIN脚设置为1,只要简单添加一个常量IP并且映射到PL部分的PIN脚(复位脚在FPGA 部分(PL)),和添加CPU方法一样
Step13:双击设置常量为1
Step14:右击PIN脚选择Make External
Step15:取个有意义的名字如下图,只要单击相应的模块就可以在右手边修改
Step16: 右击 system.bd, 单击Generate Output Products
Step17:支部操作会产生执行、仿真、综合的文件,可以看出来最后的硬件设计步骤还是回到了我们前面的FPGA开发上来了。
Step18:右击system.bd 选择 Create HDL Wrapper 这步的作用是产生顶层的HDL文件
Step19:选择Leave Let Vivado manager wrapper and auto-update 然后单击OK
Step20:单机Add Sources。
Step21:选择Add or create constraints
Step22:选择Create File
Step23:输入zynq_pin。
Step24:如图,单击Finish
Step25:双击打开zynq_pin.xdc文件,添加PIN脚约束
Step26:执行->产生bit文件
6.5导出SOC硬件到SDK
Step1:File->Export->Export Hardware
Step2:勾选Include bitstream 直接单击OK
Step3:File->Launch SDK加载到SDK
Step4:单击OK
6.6 新建LED_Flash SDK工程
Step1:在SDK界面中,新建一个名为LED_Flash的工程,单击Next。
Step2:建立一个空的工程
Step3:新建一个C的源文件
Step4:取名为LED_Flash.c
Step5:取名为LED_Flash.c
接下来就向LED_Flash.c中添加内容了,之前讲过,其中MIO7接到了LD9这个灯上,接下来我们利用程序让他闪起来。
#include "sleep.h" int main() { static XGpioPs psGpioInstancePtr; XGpioPs_Config* GpioConfigPtr; int iPinNumber= 7; //LD9连接的是MIO7 u32 uPinDirection = 0x1; //1表示输出,0表示输入 int xStatus; //--MIO的初始化 GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID); if(GpioConfigPtr == NULL) return XST_FAILURE; xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr, GpioConfigPtr->BaseAddr); if(XST_SUCCESS != xStatus) print(" PS GPIO INIT FAILED \n\r"); //--MIO的输入输出操作 XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection);//配置MIO输出方向 XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);//配置MIO的第7位输出 while(1) { XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//点亮MIO的第7位输出1 sleep(1); //延时 XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄灭MIO的第7位输出0 sleep(1); //延时 } return 0; } |
6.7 程序分析
具体内容请对照注释说明,这里想说明的是iPinNumber这个参数,应为我们要操作的是MIO7,所以这里所以这里的iPinNumber等于7,在后一章的EMIO中也有这个参数,具体怎么算请参看下一节内容,这里就做个铺垫吧。
6.8 IO寄存器直接输出
实际上以上代码的销量是非常低的,因为封装好的函数,里面有很多调用开销,还有很多自动化的代码,特别是当要求IO输出速度很高的时候,差距会很明显。笔者这里把IO部分的函数做一点小的改动,改为直接控制寄存器地址空间。
while(1) { //XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//点亮MIO的第7位输出1 Value = ~((u32)1 << (iPinNumber + 16U)) & ((1 << iPinNumber) | 0xFFFF0000U); Xil_Out32(0xE000A000,Value);//直接寄存器操作 sleep(1); //延时 Value = ~((u32)1 << (iPinNumber + 16U)) & ((0 << iPinNumber) | 0xFFFF0000U); Xil_Out32(0xE000A000,Value);// //XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄灭MIO的第7位输出0 sleep(1); //延时 } |
这个地址0xE000A000是不是很熟悉呢?没错这就是前面笔者贴出的一张表格,而且正是位控制 寄存器MASK_DATA_0_LSW
6.9电平翻转速度库函数和寄存器对比
库函数测试函数
XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 1);//点亮MIO的第7位输出1 XGpioPs_WritePin(&psGpioInstancePtr, iPinNumber, 0);//熄灭MIO的第7位输出0 |
寄存器测试函数
while(1) { Value = ~((u32)1 << (iPinNumber + 16U)) & ((1 << iPinNumber) | 0xFFFF0000U); Xil_Out32(0xE000A000,Value);//直接寄存器操作 Value = ~((u32)1 << (iPinNumber + 16U)) & ((0 << iPinNumber) | 0xFFFF0000U); Xil_Out32(0xE000A000,Value);// } |
库函数测试函数出来的频率
寄存器测试函数出来的频率(由于示波器带宽太低,波形已经变形)
6.10 本章小结
本章讲解了ZYNQ芯片的GPIO的一些知识,然后通过使用SDK进行编程点亮一个LED。同时分析了程序的代码。测试结果说明了,库函数使用方便,但是效率地下,寄存器效率高,但是使用不方便。因此在设计系统的时候如何优化是需要综合考虑的。
第六章 ZYNQ-MIZ701 GPIO使用之MIO的更多相关文章
- 精通Web Analytics 2.0 (8) 第六章:使用定性数据解答”为什么“的谜团
精通Web Analytics 2.0 : 用户中心科学与在线统计艺术 第六章:使用定性数据解答"为什么"的谜团 当我走进一家超市,我不希望员工会认出我或重新为我布置商店. 然而, ...
- 《Entity Framework 6 Recipes》中文翻译系列 (30) ------ 第六章 继承与建模高级应用之多对多关联
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第六章 继承与建模高级应用 现在,你应该对实体框架中基本的建模有了一定的了解,本章 ...
- 《Entity Framework 6 Recipes》中文翻译系列 (37) ------ 第六章 继承与建模高级应用之独立关联与外键关联
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-13 在基类中应用条件 问题 你想从一个已存在的模型中的实体派生一个新的实体, ...
- KnockoutJS 3.X API 第六章 组件(5) 高级应用组件加载器
无论何时使用组件绑定或自定义元素注入组件,Knockout都将使用一个或多个组件装载器获取该组件的模板和视图模型. 组件加载器的任务是异步提供任何给定组件名称的模板/视图模型对. 本节目录 默认组件加 ...
- Java语言程序设计(基础篇) 第六章 方法
第六章 方法 6.2 定义方法 1.方法的定义由方法名称.参数.返回值类型以及方法体组成. 2.定义在方法头中的变量称为形式参数(formal parameter)或者简称为形参(parameter) ...
- 读《编写可维护的JavaScript》第六章总结
第六章 避免使用全局变量 JavaScript执行环境在很多方面都有其独特之处,全局变量就是其中之一.“全局变量”是一个神秘的对象,它表示了脚本的最外层上下文. 在浏览器中,windows对象往往重载 ...
- 第六章第一个linux个程序:统计单词个数
第六章第一个linux个程序:统计单词个数 从本章就开始激动人心的时刻——实战,去慢慢揭开linux神秘的面纱.本章的实例是统计一片文章或者一段文字中的单词个数. 第 1 步:建立 Linu x 驱 ...
- Getting Started With Hazelcast 读书笔记(第五章,第六章)
第五章 监听 本章应该是Hazelcast的核心机制了,Hazelcast通过注册各种监听器获悉集群中其他应用对数据的修改,成员的加入,退出等. 分为3个层次. 1.EntryListener(对数据 ...
- 第十六章 综合实例——《跟我学Shiro》
简单的实体关系图 简单数据字典 用户(sys_user) 名称 类型 长度 描述 id bigint 编号 主键 username varchar 100 用户名 password varchar 1 ...
- 第六章 prototype和constructor
首先我们看下面一段代码(第六章 01.htm) function myfun() //定义一个函数myfun { }; console.log(typeof (myfun.prototype)); c ...
随机推荐
- Vue图片浏览组件v-viewer,支持旋转、缩放、翻转等操作
v-viewer 用于图片浏览的Vue组件,支持旋转.缩放.翻转等操作,基于viewer.js. 从0.x迁移 你需要做的唯一改动就是手动引入样式文件: 1 import 'viewerjs/dist ...
- Tecplot中如何计算Ma数(马赫数)【转载】
转载自:http://blog.163.com/wanglei2146073@126/blog/static/90689607201282555055144/ fluent是我们常用的CFD软件,但由 ...
- Maven:element '******' cannot have character [children]
此错误是由于XML文件的解析不正确造成的,因为在一个/某些标签之间存在奇怪和隐藏的字符. 这些字符可能来自网络上的复制粘贴.要解决此问题,请删除标签>标记定义之间的所有空格和换行符,然后将它们放 ...
- Mybatis 传入多个参数查询数据 (3种方法)
第一种方案 DAO层的函数方法 public User selectUser(String name,String area); 对应的Mapper.xml <select id="s ...
- java课后实验性问题4
课后作业一: 使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数.请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象? 设计思路:定义类的构造函数时使静态变量i进行i++,即每构 ...
- unigui图形验证码
unigui图形验证码 procedure TMainForm.UniButton1Click(Sender: TObject); var url: SockString; serial: TynSe ...
- 组件 computed 与 vuex 中 getters 的使用,及 mapGetters 的使用,对象上追加属性,合并对象
vue 是响应式的数据,这一点相当的方便我们的操作,但有些错误的操作方法会 vue 的响应无效 除此之外我们还要了解 vue.set() 和 Object.assgin() 的使用 vue.set() ...
- sed中使用变量及变量中存在特殊字符‘/’处理
sed中使用变量,普通的处理方式无法解析变量 如当前file文件中存在字符串pedis,现将其替换为redis [root@localhost work]# cat file pedis 如下两种替换 ...
- APP_DEBUG改成false上线之后发现:“页面错误!请稍后再试~
TP框架 页面错误!请稍后再试 把APP_DEBUG改成false上线之后发现:"页面错误!请稍后再试-". 问题一般是出在,display() 指定某个具体的模板文件后win ...
- react hook的todolist
感觉好长时间没写博客一样,app.js代码 import React from 'react'; import { useState } from 'react'; function App() { ...