ZYNQ+Vivado2015.2系列(十五)AXI Timer 用户定时器中断控制LED
2018-01-16 11:47
531 查看
前面的中断学习中我们学了按键,GPIO,Timer,是时候把它们整合到一起了。今天我们混合使用PS/PL部分的资源,建立一个比较大的系统。
板子:zc702。
实现功能如下:
1.通过串口打印信息询问你要按SW5还是SW7;
2.当正确的按键被按下,定时器启动,关闭led DS23;
3.当定时器溢出后触发中断,开启DS23,系统回到1。
我们用一个AXI GPIO连接到SW5,EMIO连接SW7,MIO连接DS23(固定连接),定时器也使用PL的AXI Timer。
AXI Timer的主要特性:
![](https://img-blog.csdn.net/20180116115945704?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ4NTQ4NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
硬件系统
1.添加zynq核,AXI GPIO,AXI Timer
2.打开zynq核的配置,使能UART 1,使能GPIO MIO,添加1 bit的EMIO GPIO,使能PL-PS中断IRQ_F2P
3.AXI GPIO宽度设为1
![](https://img-blog.csdn.net/20180116094154874?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ4NTQ4NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20180116094122871?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ4NTQ4NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
4.点击自动连接,所有都可以自动连接
5.将zynq的IRQ_F2P[0:0] 连接到AXI Timer的interrupt,点击zynq的GPIO_0 右键Make External ,点击输出的引脚可以修改信号名称
生成顶层文件:
![](https://img-blog.csdn.net/20180116094824724?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ4NTQ4NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
添加约束
连接到两个按键,AXI GPIO连接到SW5,EMIO 连接到SW7
![](https://img-blog.csdn.net/20180116095204985?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ4NTQ4NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
另外,LED DS 23连接在MIO 10:
![](https://img-<br/>4000<br/>blog.csdn.net/20180116100452819?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ4NTQ4NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](https://img-blog.csdn.net/20180116100502238?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDQ4NTQ4NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
生成比特文件,打开SDK。
软件部分
代码来自于Xilinx官方。
从main函数开始:
定义三个实例:
AXI GPIO实例:XGpio
AXI Timer实例:XTmrCtr
前面还定义了EMIO GPIO实例:XGpioPs
(EMIO Pin脚是54,DS 23 Pin脚是10)
AXI GPIO初始化:XGpio_Initialize
AXI GPIO设置数据方向:XGpio_SetDataDirection 1表示输入,这个IO是接SW5的
AXI Timer初始化:XTmrCtr_Initialize
设置AXI Timer中断处理器:XTmrCtr_SetHandler 这个处理器就是我们自定义的功能Timer_InterruptHandler(),中断发生之后去干嘛,这里我们实现的是点亮DS 23
设置AXI Timer初始值:XTmrCtr_SetResetValue
定时器功能设置:XTmrCtr_SetOptions
XTC_INT_MODE_OPTIONEnables
the timer counter interrupt output.
XTC_AUTO_RELOAD_OPTIONconfigures the timer counter to
reload from the compare value
PS的GPIO初始化:XGpioPs_LookupConfig XGpioPs_CfgInitialize
设置IO的数据方向:XGpioPs_SetDirectionPin //MIO上的DS23 1代表输出 | EMIO上的SW7 0代表输入
XGpioPs_SetOutputEnablePin ////1 for Enabling Output Enable 0 for Disabling Output Enable
GIC初始化:封装在ScuGicInterrupt_Init()函数
XScuGic_LookupConfig-->XScuGic_CfgInitialize
while循环:向控制台输入一个值,利用inbyte()接收,利用case选择是使用SW5还SW7触发定时器,触发后开启定时器,中断发生点亮DS 23。当标志位exit_flag不等于1持续这个操作,没有进入任何case分支,进入default,默认里面设置exit_flag=1,退出while,程序就结束了。
注:我在测试的时候,inbyte()会时不时抽风,需要重启应用程序,有待考究。
板子:zc702。
实现功能如下:
1.通过串口打印信息询问你要按SW5还是SW7;
2.当正确的按键被按下,定时器启动,关闭led DS23;
3.当定时器溢出后触发中断,开启DS23,系统回到1。
我们用一个AXI GPIO连接到SW5,EMIO连接SW7,MIO连接DS23(固定连接),定时器也使用PL的AXI Timer。
AXI Timer的主要特性:
硬件系统
1.添加zynq核,AXI GPIO,AXI Timer
2.打开zynq核的配置,使能UART 1,使能GPIO MIO,添加1 bit的EMIO GPIO,使能PL-PS中断IRQ_F2P
3.AXI GPIO宽度设为1
4.点击自动连接,所有都可以自动连接
5.将zynq的IRQ_F2P[0:0] 连接到AXI Timer的interrupt,点击zynq的GPIO_0 右键Make External ,点击输出的引脚可以修改信号名称
生成顶层文件:
添加约束
连接到两个按键,AXI GPIO连接到SW5,EMIO 连接到SW7
set_property PACKAGE_PIN G19 [get_ports {gpio_sw_tri_i[0]}] set_property IOSTANDARD LVCMOS25 [get_ports {gpio_sw_tri_i[0]}] set_property PACKAGE_PIN F19 [get_ports {gpio_0_tri_io[0]}] set_property IOSTANDARD LVCMOS25 [get_ports {gpio_0_tri_io[0]}]
另外,LED DS 23连接在MIO 10:
生成比特文件,打开SDK。
软件部分
代码来自于Xilinx官方。
#include <stdio.h> #include "platform.h" #include "xil_types.h" #include "xgpio.h" #include "xtmrctr.h" #include "xparameters.h" #include "xgpiops.h" #include "xil_io.h" #include "xil_exception.h" #include "xscugic.h" static XGpioPs psGpioInstancePtr; extern XGpioPs_Config XGpioPs_ConfigTable[XPAR_XGPIOPS_NUM_INSTANCES]; static int iPinNumber = 10; XScuGic InterruptController; /* Instance of the Interrupt Controller */ static XScuGic_Config *GicConfig;/* The configuration parameters of the controller */ static int InterruptFlag; //void print(char *str); extern char inbyte(void); void Timer_InterruptHandler(void *data, u8 TmrCtrNumber) { print(" Inside Timer ISR \n \r "); XTmrCtr_Stop(data,TmrCtrNumber); // PS GPIO Writting print("LED 'DS23' Turned ON \r\n"); XGpioPs_WritePin(&psGpioInstancePtr,iPinNumber,1); XTmrCtr_Reset(data,TmrCtrNumber); print(" Timer ISR Exit\n \n \r"); InterruptFlag = 1; } int SetUpInterruptSystem(XScuGic *XScuGicInstancePtr) { /* * Connect the interrupt controller interrupt handler to the hardware * interrupt handling logic in the ARM processor. */ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler) XScuGic_InterruptHandler, XScuGicInstancePtr); /* * Enable interrupts in the ARM */ Xil_ExceptionEnable(); return XST_SUCCESS; } int ScuGicInterrupt_Init(u16 DeviceId,XTmrCtr *TimerInstancePtr) { int Status; /* * Initialize the interrupt controller driver so that it is ready to * use. * */ GicConfig = XScuGic_LookupConfig(DeviceId); if (NULL == GicConfig) { return XST_FAILURE; } Status = XScuGic_CfgInitialize(&InterruptController, GicConfig, GicConfig->CpuBaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the Interrupt System * */ Status = SetUpInterruptSystem(&InterruptController); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect a device driver handler that will be called when an * interrupt for the device occurs, the device driver handler performs * the specific interrupt processing for the device */ Status = XScuGic_Connect(&InterruptController, XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR, (Xil_ExceptionHandler)XTmrCtr_InterruptHandler, (void *)TimerInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable the interrupt for the device and then cause (simulate) an * interrupt so the handlers will be called */ XScuGic_Enable(&InterruptController, XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR); return XST_SUCCESS; } int main() { static XGpio GPIOInstance_Ptr; XGpioPs_Config*GpioConfigPtr; XTmrCtr TimerInstancePtr; int xStatus; u32 Readstatus=0,OldReadStatus=0; int iPinNumberEMIO = 54; u32 uPinDirectionEMIO = 0x0; u32 uPinDirection = 0x1; int exit_flag,choice,internal_choice; init_platform(); xStatus = XGpio_Initialize(&GPIOInstance_Ptr,XPAR_AXI_GPIO_0_DEVICE_ID); if(XST_SUCCESS != xStatus) print("GPIO INIT FAILED\n\r"); XGpio_SetDataDirection(&GPIOInstance_Ptr, 1,1);//AXI GPIO 1表示输入 xStatus = XTmrCtr_Initialize(&TimerInstancePtr,XPAR_AXI_TIMER_0_DEVICE_ID); if(XST_SUCCESS != xStatus) print("TIMER INIT FAILED \n\r"); XTmrCtr_SetHandler(&TimerInstancePtr, Timer_InterruptHandler, &TimerInstancePtr); XTmrCtr_SetResetValue(&TimerInstancePtr, 0, //Change with generic value 0xff000000); XTmrCtr_SetOptions(&TimerInstancePtr, XPAR_AXI_TIMER_0_DEVICE_ID, (XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION ));//Setting timer Option (Interrupt Mode And Auto Reload ) 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"); XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumber,uPinDirection);//MIO上的DS23 1代表输出 XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumber,1);//1 for Enabling Output Enable XGpioPs_SetDirectionPin(&psGpioInstancePtr, iPinNumberEMIO,uPinDirectionEMIO); //EMIO上的SW7 0代表输入 XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, iPinNumberEMIO,0); //0 for Disabling Output Enable xStatus=ScuGicInterrupt_Init(XPAR_PS7_SCUGIC_0_DEVICE_ID,&TimerInstancePtr); if(XST_SUCCESS != xStatus) //User selection procedure to select and execute tests exit_flag = 0; while(exit_flag != 1) { print("------- Menu Starts -------\r\n"); print("Press '1' to use NORMAL GPIO as an input (SW5 switch)\r\n"); print("Press '2' to use EMIO as an input (SW7 switch)\r\n"); print("Press any other key to Exit\r\n"); choice = inbyte();//等待串口输入 printf("Selection : %c \r\n",choice); internal_choice = '1'; switch(choice) { // Use case for AXI GPIO case '1': exit_flag = 0; print("Press Switch 'SW5' push button on board \r\n"); print(" \r\n"); while(internal_choice != '0') { Readstatus = XGpio_DiscreteRead(&GPIOInstance_Ptr, 1); if(1== Readstatus && 0 == OldReadStatus ) { print("SW5 PUSH Button pressed \n\r"); print("LED 'DS23' Turned OFF \r\n"); XGpioPs_WritePin(&psGpioInstancePtr,iPinNumber,0); //Start Timer XTmrCtr_Start(&TimerInstancePtr,0); print("timer start \n\r"); //Wait For interrupt; print("Wait for the Timer interrupt to tigger \r\n"); print(" \r\n"); while(InterruptFlag != 1); InterruptFlag = 0; print("Press '0' to go to Main Menu \n\r "); print("Press any other key to remain in AXI GPIO Test \n\r "); internal_choice = inbyte(); printf("Select = %c \r\n",internal_choice); if(internal_choice != '0') { print("Press Switch 'SW5' push button on board \r\n"); } } OldReadStatus = Readstatus; } print(" \r\n"); print(" \r\n"); break; case '2' : //Use case for PS GPIO exit_flag = 0; print("Press Switch 'SW7' push button on board \r\n"); print(" \r\n"); while(internal_choice != '0') { Readstatus = XGpioPs_ReadPin(&psGpioInstancePtr, iPinNumberEMIO); if(1== Readstatus && 0 == OldReadStatus ) { print("SW7 PUSH Button pressed \n\r"); print("LED 'DS23' Turned OFF \r\n"); XGpioPs_WritePin(&psGpioInstancePtr,iPinNumber,0); //Start Timer XTmrCtr_Start(&TimerInstancePtr,0); print("timer start \n\r"); //Wait For interrupt; print("Wait for the Timer interrupt to tigger \r\n"); print(" \r\n"); while(InterruptFlag != 1); InterruptFlag = 0; print("Press '0' to go to Main Menu \n\r "); print("Press any other key to remain in EMIO Test \n\r "); internal_choice = inbyte(); printf("Select = %c \r\n",internal_choice); if(internal_choice != '0') { print("Press Switch 'SW7' push button on board \r\n"); } } OldReadStatus = Readstatus; } print(" \r\n"); print(" \r\n"); break; default : exit_flag = 1; break; } } print("BYE \r\n"); cleanup_platform(); return 0; }
从main函数开始:
定义三个实例:
AXI GPIO实例:XGpio
AXI Timer实例:XTmrCtr
前面还定义了EMIO GPIO实例:XGpioPs
(EMIO Pin脚是54,DS 23 Pin脚是10)
AXI GPIO初始化:XGpio_Initialize
AXI GPIO设置数据方向:XGpio_SetDataDirection 1表示输入,这个IO是接SW5的
AXI Timer初始化:XTmrCtr_Initialize
设置AXI Timer中断处理器:XTmrCtr_SetHandler 这个处理器就是我们自定义的功能Timer_InterruptHandler(),中断发生之后去干嘛,这里我们实现的是点亮DS 23
设置AXI Timer初始值:XTmrCtr_SetResetValue
定时器功能设置:XTmrCtr_SetOptions
XTC_INT_MODE_OPTIONEnables
the timer counter interrupt output.
XTC_AUTO_RELOAD_OPTIONconfigures the timer counter to
reload from the compare value
PS的GPIO初始化:XGpioPs_LookupConfig XGpioPs_CfgInitialize
设置IO的数据方向:XGpioPs_SetDirectionPin //MIO上的DS23 1代表输出 | EMIO上的SW7 0代表输入
XGpioPs_SetOutputEnablePin ////1 for Enabling Output Enable 0 for Disabling Output Enable
GIC初始化:封装在ScuGicInterrupt_Init()函数
XScuGic_LookupConfig-->XScuGic_CfgInitialize
while循环:向控制台输入一个值,利用inbyte()接收,利用case选择是使用SW5还SW7触发定时器,触发后开启定时器,中断发生点亮DS 23。当标志位exit_flag不等于1持续这个操作,没有进入任何case分支,进入default,默认里面设置exit_flag=1,退出while,程序就结束了。
注:我在测试的时候,inbyte()会时不时抽风,需要重启应用程序,有待考究。
相关文章推荐
- 用定时器T0的中断控制8位LED闪烁
- 定时器 T3定(8 位)通过中断方式控制 LED
- ZYNQ+Vivado2015.2系列(十四)按键中断控制LED亮灭
- 用定时器T0的中断控制8位LED闪烁
- Cubieboard上使用U-boot通过定时器中断控制LED
- 【NUCLEO_F767ZI开发板系列】四、外部中断控制LED
- Linux button按键驱动 多次中断控制相应LED灯亮灭闪
- 嵌入式bootloader开发之九----键盘中断控制LED灯(Tiny 6410)
- Wince外部中断控制LED详解---动态申请
- Tiny210 中断控制LED灯的亮和灭
- ARM裸机——FS2410按键控制LED(中断方式)
- CC2530学习笔记の外部中断——按键控制LED
- 树莓派 Learning 003 — GPIO 003 中断模式 — 按键控制LED
- CCS5.4+Proteus8的F28027实践课二、定时器0控制LED流水灯
- STM32F1x系列——定时器中断
- 6.0 外部中断控制LED灯
- vsftpd系列--3--实体用户访问控制
- 用定时器0控制切换流水灯顺序,用外部中断控制两种数码管显示方式
- 中断-按键控制LED灯
- arduino学习系列——按键控制LED灯