Xilinx ZYNQ开发GPIO的三种方式:MIO、EMIO、AXI_GPIO

前言:
zynq 7000有三种gpio:mio,emio,axi_gpio
mio是固定管脚的,属于ps,使用时不消耗pl资源;emio通过pl扩展,使用时需要分配管脚,使用时消耗pl管脚资源;axi_gpio是封装好的ip核,ps通过m_axi_gpio接口控制pl部分实现io,使用时消耗管脚资源和逻辑资源。
使用的板子是zc702。
1.mio方式
zynq7000 系列芯片有 54 个 mio(multiuse i/o), 它们分配在 gpio 的 bank0 和bank1 隶属于 ps 部分, 这些 io 与 ps 直接相连。 不需要添加引脚约束, mio 信号对 pl部分是透明的, 不可见。 所以对 mio 的操作可以看作是纯 ps 的操作。
新建vivado工程,添加zynq cpu核,双击,配置好时钟和内存类型,确认勾选mio:
如系列(三)文章所述,生成bit stream,然后launch sdk。
在sdk中新建工程,源文件如下:
#include xgpiops.h
#include sleep.h
int main()
{
static xgpiops psgpioinstanceptr;
xgpiops_config* gpioconfigptr;
int ipinnumber= 8; //ds12连接的是mio8
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的第8位输出
while(1)
{
xgpiops_writepin(&psgpioinstanceptr, ipinnumber, 1);//点亮mio的第8位输出1
usleep(500000); //延时
xgpiops_writepin(&psgpioinstanceptr, ipinnumber, 0);//熄灭mio的第8位输出0
usleep(500000); //延时
}
/****************************************************************
while(1)
{
xgpiops_writereg(0xe000a000,0x00000000, 0xff7fffff&0xffff0080);
usleep(500000); //延时
xgpiops_writereg(0xe000a000,0x00000000, 0xff7fffff&0xffff0000);
usleep(500000); //延时
} *
*****************************************************************/
return 0;
}
下载到板子上,ds12就开始闪烁了。
2.emio方式
emio 分配在 bank2 和 bank3 和 pl部分相连。emio 有 64 个引脚可供我们使用 。当 mio 不够用时, ps 可以通过驱动 emio 控制 pl 部分的引脚 。
vivado工程里zynq cpu核配置,确保emio勾选,这里我设置了位宽为4,后面为其分配了四个管脚:
在diagram里面将gpio_0的引脚引出来,生成顶层文件后查看这个引脚的名字,因为我修改了名字,这里叫emio_0_tri_io
管脚约束文件:
#gpio pmod1
set_property package_pin e15 [get_ports {emio_0_tri_io[0]}]
set_property iostandard lvcmos25 [get_ports {emio_0_tri_io[0]}]
set_property package_pin d15 [get_ports {emio_0_tri_io[1]}]
set_property iostandard lvcmos25 [get_ports {emio_0_tri_io[1]}]
set_property package_pin w17 [get_ports {emio_0_tri_io[2]}]
set_property iostandard lvcmos25 [get_ports {emio_0_tri_io[2]}]
set_property package_pin w5 [get_ports {emio_0_tri_io[3]}]
set_property iostandard lvcmos25 [get_ports {emio_0_tri_io[3]}]
sdk部分:mio号是0~53,emio从54开始
#include xgpiops.h
#include sleep.h
int main()
{
static xgpiops psgpioinstanceptr;
xgpiops_config* gpioconfigptr;
int xstatus;
//-- emio的初始化
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);
//--emio的输入输出操作
xgpiops_setdirectionpin(&psgpioinstanceptr, 54,1);
xgpiops_setdirectionpin(&psgpioinstanceptr, 55,1);
xgpiops_setdirectionpin(&psgpioinstanceptr, 56,1);
xgpiops_setdirectionpin(&psgpioinstanceptr, 57,1);
//使能emio输出
xgpiops_setoutputenablepin(&psgpioinstanceptr, 54,1);
xgpiops_setoutputenablepin(&psgpioinstanceptr, 55,1);
xgpiops_setoutputenablepin(&psgpioinstanceptr, 56,1);
xgpiops_setoutputenablepin(&psgpioinstanceptr, 57,1);
while(1)
{
xgpiops_writepin(&psgpioinstanceptr, 54, 1);//emio的第0位输出1
usleep(200000); //延时
xgpiops_writepin(&psgpioinstanceptr, 54, 0);//emio的第0位输出0
usleep(200000); //延时
xgpiops_writepin(&psgpioinstanceptr, 55, 1);//emio的第1位输出1
usleep(200000); //延时
xgpiops_writepin(&psgpioinstanceptr, 55, 0);//emio的第1位输出0
usleep(200000); //延时
xgpiops_writepin(&psgpioinstanceptr, 56, 1);//emio的第2位输出1
usleep(200000); //延时
xgpiops_writepin(&psgpioinstanceptr, 56, 0);//emio的第2位输出0
usleep(200000); //延时
xgpiops_writepin(&psgpioinstanceptr, 57, 1);//emio的第3位输出1
usleep(200000); //延时
xgpiops_writepin(&psgpioinstanceptr, 57, 0);//emio的第3位输出0
usleep(200000); //延时
}
return 0;
}
下载到板子里,pmod1的4个led灯交替闪烁。
3.axi_gpio方式
vivado工程里,zynq cpu核配置:
勾选m_axi_gpio 接口:
勾选复位信号:
给pl的时钟信号:
加入axi_gpio ip,这里设置位宽为4,后面将控制4个led灯:
自动连接后如下图:
管脚约束如下:
#gpio pmod1
set_property package_pin e15 [get_ports {gpio_sw_tri_o[0]}]
set_property iostandard lvcmos25 [get_ports {gpio_sw_tri_o[0]}]
set_property package_pin d15 [get_ports {gpio_sw_tri_o[1]}]
set_property iostandard lvcmos25 [get_ports {gpio_sw_tri_o[1]}]
set_property package_pin w17 [get_ports {gpio_sw_tri_o[2]}]
set_property iostandard lvcmos25 [get_ports {gpio_sw_tri_o[2]}]
set_property package_pin w5 [get_ports {gpio_sw_tri_o[3]}]
set_property iostandard lvcmos25 [get_ports {gpio_sw_tri_o[3]}]
sdk部分如下:
#include
#include platform.h
#include xparameters.h
#include xgpio.h
int main() {
xgpio gpio_led;
int status;
int i,x,y;
init_platform();
status = xgpio_initialize(&gpio_led, 0);
if(status == 0){
printf(success /r/n);
}
xgpio_setdatadirection(&gpio_led,1,0);//设置通道1为输出
while (1){
for (i = 0; i xgpio_discretewrite(&gpio_led, 1, 0x01 for(x =1000; x > 0; x-- ){
for (y = 100000; y > 0; y--);
}
}
}
cleanup_platform();
return 0;
}
可以看到,与emio一样需要分配管脚,但是axi_gpio使用的头文件是#include xgpio.h,而emio是#include xgpiops.h。
下载完成后,pmod1 的四个led灯依次闪烁。
总结:
mio和emio使用ps的gpio,,mio固定管脚,emio手动分配管脚;ip方式手动分配管脚,综合后需要消耗pl的逻辑资源。


飞凌嵌入式访问TI美国总部,深化交流与合作
华为p10上市时间:或将于2月26日发布,华为P10Plus同步现身!满满的黑科技
对于工程师来说code只要能用,就是好code吗
科大胜英的高精度智能压力传感器
如何才能守护好虚拟化的5G网络安全
Xilinx ZYNQ开发GPIO的三种方式:MIO、EMIO、AXI_GPIO
了解UEFI固件更新及其在确保计算系统安全方面的重要作用
云端智能机器人适合5G时代 能提高人类生产生活和娱乐的质量
华为mate10什么时候上市?华为mate10最新消息:华为mate10抢发全面屏,下半年即将登场
德州仪器推出支援65V暂态保护最小型2.5A电源模组
天数智芯携众多应用场景以及最新产品亮相2022世界人工智能大会
VCA610扩展增益范围和改进噪声性能的电路
中科新松将与行业合作伙伴在机器人领域开展深度合作
三星QLED 8K电视 为“宅家”生活提供更多乐趣
全球汽车芯片短缺将在下半年缓解,不会对丰田和本田造成重大影响
多维科技基于隧道磁电阻技术推出大量程TMR线性磁场传感器芯片
FPGA芯片外围电路设计规范和配置过程
利用电流检测放大器AD8210和差动放大器AD8274实现高电压、高精度电流检测和输出电平转换
基于PWM技术的数控恒流源电路设计
全新荣耀智慧屏X1 75英寸正式在京东开售