ZYNQ GPIO应用
来源:互联网 发布:杀破狼 js微盘下载 编辑:程序博客网 时间:2024/06/01 08:23
总结一下zynq的GPIO应用
zynq的GPIO分为PS部分的MIO和PS-PL配合使用的EMIO(用PL端的IO扩展GPIO),由PS调度。这里描述一下这个EMIO的应用。
IP的方式扩展IO
在vivado下配置AXI接口的GPIO
这里例化了两组GPIO,一组作为 LED的输出IO,一组作为按键的输入IO,采用中断方式检测电平变化
#include <stdio.h>#include <xgpio.h>#include "platform.h"#include "xil_printf.h"#include "xscugic.h"#include "xscutimer.h"#include "./inc/gpio.h"static XGpio led_out_4b;static XGpio BTNInst; static XScuGic INTCInst; int XGpio_InterruptInitialize(void){ int status; printf("LED 4bit Init.............\r\n"); status = XGpio_Initialize(&led_out_4b,XPAR_AXI_GPIO_0_DEVICE_ID); //Init LED GPIO if(status != XST_SUCCESS) return XST_FAILURE; XGpio_SetDataDirection(&led_out_4b,1,0x00); //Set GPIO as output status = XGpio_Initialize(&BTNInst, BTNS_DEVICE_ID); if(status != XST_SUCCESS) return XST_FAILURE; XGpio_SetDataDirection(&BTNInst, 1, 0xFF); printf("EXIT InterruptInitialize......\r\n"); status = IntcInitFunction(EXIT_INTC_DEVICE_ID, &BTNInst); if(status != XST_SUCCESS) return XST_FAILURE; return XST_SUCCESS; }//---------------------------------------------------- // INTERRUPT SETUP FUNCTIONS //---------------------------------------------------- int IntcInitFunction(u16 DeviceId, XGpio *GpioInstancePtr){ XScuGic_Config *IntcConfig; int status; // Interrupt controller initialization IntcConfig = XScuGic_LookupConfig(DeviceId); status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress); if(status != XST_SUCCESS) return XST_FAILURE; // Register GIC interrupt handler Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, &INTCInst); Xil_ExceptionEnable(); // Register GPIO interrupt handler status = XScuGic_Connect(&INTCInst, INTC_GPIO_INTERRUPT_ID, (Xil_ExceptionHandler)BTN_Intr_Handler, (void *)GpioInstancePtr); if(status != XST_SUCCESS) return XST_FAILURE; // Enable GPIO interrupts XGpio_InterruptEnable(GpioInstancePtr, 1); XGpio_InterruptGlobalEnable(GpioInstancePtr); // Enable GPIO interrupts in the controller XScuGic_Enable(&INTCInst, INTC_GPIO_INTERRUPT_ID); return XST_SUCCESS; } void BTN_Intr_Handler(void *InstancePtr) { u8 btn_value = 0; unsigned char led_val = 0; // Ignore additional button presses if ((XGpio_InterruptGetStatus(&BTNInst) & BTN_INT) != BTN_INT) { printf("Other interrupt......\r\n"); return; // Disable GPIO interrupts XGpio_InterruptDisable(&BTNInst, BTN_INT); } btn_value = ~ XGpio_DiscreteRead(&BTNInst, 1)&0x0f; printf("key value 0x%x......\r\n",btn_value); switch (btn_value){ case 0x01: led_val = 0x01; break; case 0x02: led_val = 0x02; break; case 0x04: led_val = 0x04; break; case 0x08: led_val = 0x08; break; default:break; } XGpio_DiscreteWrite(&led_out_4b,1,~led_val); // Acknowledge GPIO interrupts (void)XGpio_InterruptClear(&BTNInst, BTN_INT); // Enable GPIO interrupts XGpio_InterruptEnable(&BTNInst, BTN_INT); }
上面代码初始化EMIO和按键中断的初始化和中断处理函数
直接扩展EMIO,由ZYNQ处理器引出到PL端配置IO
硬件连接
CPU GPIO定制配置
由硬件导入到SDK中会生成相应的驱动API,
使用刚才例化的GPIO做了一个IIC(源码借鉴某位大神,尊重原著,略有修改)
初始化IO和调用API接口如下代码:
#include <stdio.h>#include "platform.h"#include "xil_printf.h"#include "sleep.h" #include "xgpiops.h"#include "./inc/i2c.h"static XGpioPs psGpioInstancePtr;int EMIO_I2C_init(void) { XGpioPs_Config *GpioConfigPtr; int xStatus; 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("EMIO INIT FAILED \n\r"); XGpioPs_SetDirectionPin(&psGpioInstancePtr, SCL_PIN,DIRECTION_OUTPUT); XGpioPs_SetDirectionPin(&psGpioInstancePtr, SDA_PIN,DIRECTION_OUTPUT); XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, SCL_PIN,1); XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, SDA_PIN,1); return xStatus; } void CLOCK_HIGH(void) { XGpioPs_WritePin(&psGpioInstancePtr,SCL_PIN, 1);} void CLOCK_LOW(void) { XGpioPs_WritePin(&psGpioInstancePtr,SCL_PIN, 0);} int GET_DATA(void) { return XGpioPs_ReadPin(&psGpioInstancePtr,SDA_PIN);} void DATA_INPUT(void) { XGpioPs_SetDirectionPin(&psGpioInstancePtr, SDA_PIN,DIRECTION_INPUT);//} void DATA_OUTPUT(void) { XGpioPs_SetDirectionPin(&psGpioInstancePtr, SDA_PIN,DIRECTION_OUTPUT);//} void DATA_HIGH(void) { XGpioPs_WritePin(&psGpioInstancePtr,SDA_PIN, 1);} void DATA_LOW(void) { XGpioPs_WritePin(&psGpioInstancePtr,SDA_PIN,0);} void I2C_start(void) { CLOCK_HIGH(); DATA_HIGH(); I2C_DELAY; DATA_LOW(); I2C_DELAY; CLOCK_LOW(); I2C_DELAY; } void I2C_end(void) { DATA_LOW(); I2C_DELAY; CLOCK_HIGH(); I2C_DELAY; DATA_HIGH(); I2C_DELAY; } int I2C_sendbyte( unsigned char value ) { unsigned char tmp = value; unsigned char i=0,ack; for(i=0; i<8; i++) { if(tmp & 0x80 ) DATA_HIGH(); else DATA_LOW(); I2C_DELAY; CLOCK_HIGH(); I2C_DELAY; CLOCK_LOW(); I2C_DELAY; tmp<<=1; } DATA_HIGH(); DATA_INPUT(); I2C_DELAY; CLOCK_HIGH(); ack = GET_DATA(); I2C_DELAY; CLOCK_LOW(); I2C_DELAY; DATA_OUTPUT(); if(ack==1) { return -1; } return 0; } unsigned char I2C_readbyte( unsigned char addr) { unsigned char i=0,data=0; DATA_HIGH(); DATA_INPUT(); for(i=0; i<8; i++) { CLOCK_HIGH(); I2C_DELAY; data <<= 1; if(GET_DATA()) data |= 1; I2C_DELAY; CLOCK_LOW(); I2C_DELAY; } DATA_OUTPUT(); DATA_HIGH(); I2C_DELAY; CLOCK_HIGH(); I2C_DELAY; CLOCK_LOW(); I2C_DELAY; DATA_HIGH(); return data; } int I2C_readdata(unsigned char id, unsigned char addr, unsigned char *value) { // 两相写 I2C_start(); if(I2C_sendbyte(id<<1) != 0) { goto error; } if(I2C_sendbyte(addr) != 0) { goto error; } // 两相读 I2C_start(); if(I2C_sendbyte((id<<1)|0x1) != 0) { goto error; } *value = I2C_readbyte(addr); I2C_end(); return 0; error: I2C_end(); return -1; } int I2C_writedata(unsigned char id, unsigned char addr,unsigned char value) { I2C_start(); if(I2C_sendbyte(id<<1) != 0) { goto error; } if(I2C_sendbyte(addr) != 0) { goto error; } if(I2C_sendbyte(value)!= 0) { goto error; } I2C_end(); return 0; error: I2C_end(); return -1; } void i2c_test(void){ u8 data = 0xAA; EMIO_I2C_init(); usleep(500*1000); if (I2C_writedata(I2C_DEVICE_ADDR,0x00,data) != 0) printf("IIC write error!!!!!!!!!!!!!\r\n"); else printf("IIC write addr 0x00 data is 0x%X \r\n",data); usleep(50000); //写到读之间延时一段时间 data = 0; if(I2C_readdata(I2C_DEVICE_ADDR,0x00,&data) != 0) printf("IIC read error!!!!!!!!!!!!!\r\n"); else printf("IIC read addr 0x00 data is 0x%X \r\n",data);}
这里可以测试GPIO的应用,包括按键触发中断,根据按键的状态点灯;EMIO模拟IIC接口读写EEPROM测试。
阅读全文
0 0
- ZYNQ GPIO应用
- zynq正确使用GPIO
- Linux Zynq GPIO中断
- zynq gpio管脚配置
- zynq学习03 zynq中三种实现GPIO的方式
- zynq学习05 Zynq 7000 emio的gpio操作
- zynq中三种实现GPIO的方式
- zynq中各种GPIO方式的区别
- zynq平台实现linux gpio驱动
- Zynq Qspi控制器应用笔记
- Zynq Fatfs文件系统应用笔记
- Zynq的LWIP裸奔应用
- Zynq 的AXI4 总线应用
- Zynq 7000从零开始之三 -- mio的gpio操作
- Zynq 7000从零开始之四 -- emio的gpio操作
- ZYNQ 的三种GPIO :MIO EMIO AXI_GPIO 小节
- ZYNQ 的三种GPIO :MIO EMIO AXI_GPIO 小节
- Zynq-Linux移植学习笔记之12-gpio驱动配置
- Java资料集锦
- C语言实验——整除
- Mysql事物四种隔离级别
- WPF应用程序内嵌网页
- 不用ajax,采用隐藏iframe实现表单异步提交
- ZYNQ GPIO应用
- hdu5685
- 2016 ACM-ICPC 亚洲区域赛北京站E题 What a Ridiculous Election (BFS预处理)
- Angular Material Menu 组件
- JAVA类加载和反射介绍
- HDU 4465 Candy 纯数学
- 图片缩放库--PhotoView的基本使用
- [JavaScript][AJAX][JQuery]利用回调接口封装AJAX类|原生JavaScript的AJAX写法优化
- 关于html二三事