日韩在线不卡免费视频一区,日韩欧美精品一区二区三区经典,日产精品码2码三码四码区,人妻无码一区二区三区免费,日本feerbbwdh少妇丰满

ZYNQ-實現(xiàn)GPIO的中斷控制

學(xué)習(xí)內(nèi)容

實現(xiàn)對GPIO的中斷控制程序,實現(xiàn)按鍵按下使得led燈閃亮一次,并結(jié)合前文的IIC工程,實現(xiàn)按鍵控制iic的數(shù)據(jù)采集。

開發(fā)環(huán)境

vivado 18.3 SDK PYNQ-Z2

中斷初始化的設(shè)置

對于熟悉ARM和32開發(fā)的人來說,中斷的概念對其并不陌生。下面我給出按鍵在32開發(fā)時候的初始化的流程:按鍵中斷編程步驟分析:

  1. 使能相應(yīng)的時鐘
  2. 配置GPIO管腳為中斷功能
  3. 設(shè)置中斷優(yōu)先級
  4. 使能相應(yīng)的中斷
  5. 實現(xiàn)中斷服務(wù)程序

然后我給出ZYNQ的中斷初始化的設(shè)置流程:

  1. 初始化CPU異常功能
  2. 初始化中斷控制器
  3. 向CPU注冊異常處理回調(diào)函數(shù)
  4. 向中斷控制器中對應(yīng)的中斷ID和中斷控制器相連接
  5. 設(shè)置中斷的類型
  6. 設(shè)置中斷的回調(diào)函數(shù)(用戶自己設(shè)置)
  7. 使能對應(yīng)引腳的中斷
  8. 使能中斷控制器
  9. 使能異常處理功能

對比純arm開發(fā)和zynq的開發(fā),我們可以大致看出,兩者在中斷初始化的過程中有很多相似的地方。因為zynq的功能比較多,比較復(fù)雜,在開發(fā)的時的配置過程也相對麻煩。

對應(yīng)初始化過程中的每一步,我們可以找到對應(yīng)的函數(shù)進行調(diào)用,具體過程如下:

硬件平臺搭建

新建工程初始化我們需要用到了GPIO的資源引腳,具體的工程可以參考ZYNQ-利用PS引腳實現(xiàn)EMIO GPIO的驅(qū)動這里只給出搭建后的結(jié)果:(這里只進行設(shè)計了gpio可以實現(xiàn)對應(yīng)按鍵控制燈閃爍)

也可以同時把iic的模塊進行設(shè)計,用于按鍵實現(xiàn)采集控制

綜合生成bit流文件后,進行導(dǎo)出hardware,launch SDK

SDK軟件部分

新建工程后,在main中添加中斷初始化代碼:

#define SCUGIC_0_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define GPIO_INTR_ID 52
#define SW_BANK_ID 2
static XScuGic GicPs;
static XScuGic_Config *XScuGic_Cfg;

int setupinterrupt(){
	int status;
	//初始化異常處理
	Xil_ExceptionInit();
	//初始化中斷控制器
	XScuGic_Cfg = XScuGic_LookupConfig(SCUGIC_0_ID);
	status = XScuGic_CfgInitialize(&GicPs,XScuGic_Cfg,XScuGic_Cfg->CpuBaseAddress);
	if( status != XST_SUCCESS){
			return XST_FAILURE;
	}
	//CPU中斷異常注冊
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&GicPs);
	//鏈接中斷信號
	status = XScuGic_Connect(&GicPs,GPIO_INTR_ID,(Xil_InterruptHandler)XGpioPs_IntrHandler,&GpioPs);
	if( status != XST_SUCCESS){
				return XST_FAILURE;
	}
	//中斷類型設(shè)置
	XGpioPs_SetIntrType(&GpioPs,SW_BANK_ID,0xffffffff,0xffffffff,0x00);
	//設(shè)置中斷回調(diào)函數(shù)
	XGpioPs_SetCallbackHandler(&GpioPs,(void *) &GpioPs, IntrHandler);
	//打開gpio中斷
	XGpioPs_IntrEnable(&GpioPs,SW_BANK_ID,1<<(BTN1-54));
	XScuGic_Enable(&GicPs,GPIO_INTR_ID);
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
	return XST_SUCCESS;
}

對于部分參數(shù)的查找進行簡單說明,具體函數(shù)的使用,可以參考system.mss中進行查找:==GPIO_INTR_ID== :中斷配置時,要對中斷ID進行設(shè)置,否則對應(yīng)不上配置的中斷

==SW_BANK_ID== :因為我們BANK0和BANK1對應(yīng)的是MIO的管腳是54個,我們聲明的管腳在BANK 2,所以我們就設(shè)置的BANK ID為2

按鍵控制led

#include 
#include "platform.h"
#include "xil_printf.h"
#include "xgpiops.h"
#include "xparameters.h"
#include "xscugic.h"

#define GPIO_ID XPAR_PS7_GPIO_0_DEVICE_ID
#define SCUGIC_0_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define GPIO_INTR_ID 52
#define SW_BANK_ID 2
#define LED0 54
#define LED1 55
#define BTN1 56
static XGpioPs GpioPs;
static XGpioPs_Config *XGpioPs_Cfg;
static XScuGic GicPs;
static XScuGic_Config *XScuGic_Cfg;
int initGpio();
int setupinterrupt();
void IntrHandler(void *CallBack,u32 Bank,u32 status);
int main()
{
	init_platform();
    initGpio();
    print("Hello World\n\r");
    setupinterrupt();
    while(1)
    {
    	XGpioPs_WritePin(&GpioPs,LED0,0);
    	XGpioPs_WritePin(&GpioPs,LED1,0);

    	usleep(1000);

    }
    cleanup_platform();
    return0;
}
int initGpio(){
	int status;
	XGpioPs_Cfg = XGpioPs_LookupConfig(GPIO_ID);
	status = XGpioPs_CfgInitialize(&GpioPs,XGpioPs_Cfg,XGpioPs_Cfg->BaseAddr);
	if( status != XST_SUCCESS){
		return XST_FAILURE;
	}
	XGpioPs_SetDirectionPin(&GpioPs,LED0,0x01);
	XGpioPs_SetOutputEnablePin(&GpioPs,LED0,0x01);
	XGpioPs_SetDirectionPin(&GpioPs,LED1,0x01);
	XGpioPs_SetOutputEnablePin(&GpioPs,LED1,0x01);
	XGpioPs_SetDirectionPin(&GpioPs,BTN1,0x00);
	XGpioPs_SetOutputEnablePin(&GpioPs,BTN1,0x00);
}
int setupinterrupt(){
	int status;
	//初始化異常處理
	Xil_ExceptionInit();
	//初始化中斷控制器
	XScuGic_Cfg = XScuGic_LookupConfig(SCUGIC_0_ID);
	status = XScuGic_CfgInitialize(&GicPs,XScuGic_Cfg,XScuGic_Cfg->CpuBaseAddress);
	if( status != XST_SUCCESS){
			return XST_FAILURE;
	}
	//CPU中斷異常注冊
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&GicPs);
	//鏈接中斷信號
	status = XScuGic_Connect(&GicPs,GPIO_INTR_ID,(Xil_InterruptHandler)XGpioPs_IntrHandler,&GpioPs);
	if( status != XST_SUCCESS){
				return XST_FAILURE;
	}
	//中斷類型設(shè)置
	XGpioPs_SetIntrType(&GpioPs,SW_BANK_ID,0xffffffff,0xffffffff,0x00);
	//設(shè)置中斷回調(diào)函數(shù)
	XGpioPs_SetCallbackHandler(&GpioPs,(void *) &GpioPs, IntrHandler);
	//打開gpio中斷
	XGpioPs_IntrEnable(&GpioPs,SW_BANK_ID,1<<(BTN1-54));
	XScuGic_Enable(&GicPs,GPIO_INTR_ID);
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
	return XST_SUCCESS;
}
void IntrHandler(void *CallBack,u32 Bank,u32 status){
	XGpioPs *GPIO_ptr;
	u32 read_val;
	GPIO_ptr = (XGpioPs *)CallBack;
	if(XGpioPs_ReadPin(GPIO_ptr,BTN1) == 1)
	{
		XGpioPs_WritePin(GPIO_ptr,LED0,1);
		XGpioPs_WritePin(GPIO_ptr,LED1,1);
		printf("%d\n",XGpioPs_ReadPin(&GpioPs,BTN1));
		usleep(1000000);
	}
}

按鍵控制數(shù)據(jù)采集

/*
 * helloworld.c: simple test application
 *
 * This application configures UART 16550 to baud rate 9600.
 * PS7 UART (Zynq) is not initialized by this application, since
 * bootrom/bsp configures it to baud rate 115200
 *
 * ------------------------------------------------
 * | UART TYPE   BAUD RATE                        |
 * ------------------------------------------------
 *   uartns550   9600
 *   uartlite    Configurable only in HW design
 *   ps7_uart    115200 (configured by bootrom/bsp)
 */

#include 
#include "platform.h"
#include "xil_printf.h"
#include "xgpiops.h"
#include "xiicps.h"
#include "xparameters.h"
#include "xscugic.h"

#define GPIO_ID XPAR_PS7_GPIO_0_DEVICE_ID
#define SCUGIC_0_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define I2C_0_DEVICE_ID XPAR_PS7_I2C_0_DEVICE_ID
#define I2C_0_CLK 100000
#define IIC_0_SALV_ADDR 0x23 //定義器件在IIC總線中的從地址,根據(jù)ALT  ADDRESS地址引腳不同修改
                              //ALT  ADDRESS引腳接地時地址為0x23
#define GPIO_INTR_ID 52
#define SW_BANK_ID 2
#define LED0 54
#define LED1 55
#define BTN1 56
//聲明結(jié)構(gòu)體
static XGpioPs GpioPs;
static XGpioPs_Config *XGpioPs_Cfg;
static XScuGic GicPs;
static XScuGic_Config *XScuGic_Cfg;
// XIicPs* iicps;
static XIicPs iicps;
static XIicPs_Config * iicpscfgtr;
int status;
	double out=0;
	unsigned short tmp;
    unsignedchar Cmdon = 0x01;
	unsignedchar Cmdlight = 0x10;
	char temp[2];
int initGpio();
int setupinterrupt();
//初始化 iic
int InitIic(XIicPs *iips,XIicPs_Config *iiccfg);
void IntrHandler(void *CallBack,u32 Bank,u32 status);
int main()
{

	init_platform();
    initGpio();
    setupinterrupt();
    status=InitIic(&iicps,iicpscfgtr);
	if(status !=XST_SUCCESS){
		return XST_FAILURE;
	}
	//初始化
	status = XIicPs_MasterSendPolled(&iicps,&Cmdon,1,IIC_0_SALV_ADDR);
	if(status !=XST_SUCCESS){
		return XST_FAILURE;
	}
    usleep(10000);//延時10ms
    printf("init iic successful!\n");
    while(1)
    {
    	XGpioPs_WritePin(&GpioPs,LED0,0);
    	XGpioPs_WritePin(&GpioPs,LED1,0);

    	usleep(1000);

    }
    cleanup_platform();
    return0;
}
int initGpio(){
	int status;
	XGpioPs_Cfg = XGpioPs_LookupConfig(GPIO_ID);
	status = XGpioPs_CfgInitialize(&GpioPs,XGpioPs_Cfg,XGpioPs_Cfg->BaseAddr);
	if( status != XST_SUCCESS){
		return XST_FAILURE;
	}
	XGpioPs_SetDirectionPin(&GpioPs,LED0,0x01);
	XGpioPs_SetOutputEnablePin(&GpioPs,LED0,0x01);
	XGpioPs_SetDirectionPin(&GpioPs,LED1,0x01);
	XGpioPs_SetOutputEnablePin(&GpioPs,LED1,0x01);
	XGpioPs_SetDirectionPin(&GpioPs,BTN1,0x00);
	XGpioPs_SetOutputEnablePin(&GpioPs,BTN1,0x00);
}

int InitIic(XIicPs *iips,XIicPs_Config * iiccfg){
	int status;
	iiccfg = XIicPs_LookupConfig(I2C_0_DEVICE_ID);
	status = XIicPs_CfgInitialize(iips,iiccfg,iiccfg->BaseAddress);
	if(status !=XST_SUCCESS){
		return XST_FAILURE;
	}
	status = XIicPs_SelfTest(iips);
			if (status != XST_SUCCESS) {
				return XST_FAILURE;
			}
	status = XIicPs_SetSClk(iips,I2C_0_CLK);
	if(status !=XST_SUCCESS){
		return XST_FAILURE;
	}
	return0;
}
int setupinterrupt(){
	int status;
	//初始化異常處理
	Xil_ExceptionInit();
	//初始化中斷控制器
	XScuGic_Cfg = XScuGic_LookupConfig(SCUGIC_0_ID);
	status = XScuGic_CfgInitialize(&GicPs,XScuGic_Cfg,XScuGic_Cfg->CpuBaseAddress);
	if( status != XST_SUCCESS){
			return XST_FAILURE;
	}
	//CPU中斷異常注冊
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&GicPs);
	//鏈接中斷信號
	status = XScuGic_Connect(&GicPs,GPIO_INTR_ID,(Xil_InterruptHandler)XGpioPs_IntrHandler,&GpioPs);
	if( status != XST_SUCCESS){
				return XST_FAILURE;
	}
	//中斷類型設(shè)置
	XGpioPs_SetIntrType(&GpioPs,SW_BANK_ID,0xffffffff,0xffffffff,0x00);
	//設(shè)置中斷回調(diào)函數(shù)
	XGpioPs_SetCallbackHandler(&GpioPs,(void *) &GpioPs, IntrHandler);
	//打開gpio中斷
	XGpioPs_IntrEnable(&GpioPs,SW_BANK_ID,1<<(BTN1-54));
	XScuGic_Enable(&GicPs,GPIO_INTR_ID);
	Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ);
	return XST_SUCCESS;
}
void IntrHandler(void *CallBack,u32 Bank,u32 status){
	XGpioPs *GPIO_ptr;
	u32 read_val;
	GPIO_ptr = (XGpioPs *)CallBack;
	if(XGpioPs_ReadPin(GPIO_ptr,BTN1) == 1)
	{
				XGpioPs_WritePin(&GpioPs,LED0,1);
				status = XIicPs_MasterSendPolled(&iicps,&Cmdon,1,IIC_0_SALV_ADDR);
			    if(status !=XST_SUCCESS){
				   return XST_FAILURE;
			    }
				status = XIicPs_MasterSendPolled(&iicps,&Cmdlight,1,IIC_0_SALV_ADDR);
				if(status !=XST_SUCCESS){
							return XST_FAILURE;
			    }
				usleep(180000);//延時180ms
				status = XIicPs_MasterRecvPolled(&iicps,&temp,2,IIC_0_SALV_ADDR);

				//串口檢測結(jié)果
				tmp = (temp[0]<<8)| temp[1];
				out = tmp/1.2;
				printf("light intensity : %.1f lx\n",out);
				usleep(1000000);
	}
}

運行效果

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 1
收藏 2
關(guān)注 20
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧