introducir
Use el núcleo blando microblaze para construir un procesador e implementar interrupciones.
Microblaze_0 es el núcleo microbalze, que está conectado a una memoria local de 128 Kb, un núcleo mdm depurado usando JTAG, un administrador de interrupciones axi_intc, periféricos uatr y periféricos GPIO.
La implementación de la interrupción GPIO se realiza mediante vio IP core, y el VIO de 16 bits está conectado a GPIO como entrada para simular la entrada clave.
La interrupción de UART se puede realizar conectando un asistente de depuración de puerto serie externo o directamente usando el terminal SDK.
El núcleo concat IP sintetiza múltiples fuentes de interrupción en un bus y lo proporciona al administrador de interrupciones.
Resultados experimentales
La sección de depuración de jtag repite la palabra de saludo
GPIO_o capturada por ILA para realizar la conversión de 0000 a FFFF
GPIO_t es 0xffff, lo que indica que se ingresan los 16 gpio. En cuanto a por qué GPIO_o realiza la conversión de datos, esto se debe a que la señal en este momento no ha sido convertida por la puerta tri-state, y los 16 gpio se ingresan después del tri-state conversión de puerta
Use vio para cambiar la entrada de GPIO, de modo que el controlador GPIO genere una interrupción. En este momento, el programa ingresa a la función de procesamiento de interrupción GPIO e imprime "interrupción gpio" en el terminal de depuración. Use el asistente de depuración del puerto serie para ingresar un número hexadecimal, y verá lo
mismo El valor de retorno del número, que es el valor devuelto al llamar a la interrupción, el asistente de depuración del puerto serie envió tres valores de 8 bits y se generaron cuatro interrupciones, las tres primeras interrupciones estaban recibiendo interrupciones , y el último estaba enviando interrupciones
programa c
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
#include "xuartlite.h"
#include "xuartlite_l.h"
#include "xintc.h"
#include "xil_io.h"
#include "sleep.h"
#define GPIO_EXAMPLE_DEVICE_ID XPAR_GPIO_0_DEVICE_ID
#define UART_DEVICE_ID XPAR_UARTLITE_0_DEVICE_ID //串口器件ID
#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID //中断控制器ID
#define AXI_GPIO_INTR_ID XPAR_INTC_0_GPIO_0_VEC_ID //AXI GPIO中断ID
#define UART_INTR_ID XPAR_INTC_0_UARTLITE_0_VEC_ID //串口中断ID
#define EXCEPTION_ID XIL_EXCEPTION_ID_INT //中断异常ID
#define RX_NOEMPTY XUL_SR_RX_FIFO_VALID_DATA // 接收 FIFO 非空
static XGpio Gpio; /* The Instance of the GPIO Driver */
static XIntc Intc; //中断控制器实例
static XUartLite Uart; //串口实例
void GpioHandler(void *CallbackRef);
void uart_handler(void *CallbackRef);
int main()
{
init_platform();
print("Hello World\n\r");
//设备初始化
XGpio_Initialize(&Gpio, GPIO_EXAMPLE_DEVICE_ID);
XGpio_SetDataDirection(&Gpio, 1, 0xffff);
XUartLite_Initialize(&Uart , UART_DEVICE_ID);
//初始化中断控制器
XIntc_Initialize(&Intc, INTC_DEVICE_ID);
//关联中断ID和中断服务函数
//中断服务函数是需要我们自己编写的, 用于响应和处理 AXI GPIO 中断的函数
XIntc_Connect(&Intc,AXI_GPIO_INTR_ID,(Xil_ExceptionHandler)GpioHandler,&Gpio );
XIntc_Connect(&Intc, UART_INTR_ID,(XInterruptHandler)uart_handler,&Uart);
//外设中断 使能
//使能GPIO中断
XGpio_InterruptEnable(&Gpio, 1);
//使能GPIO全局中断
XGpio_InterruptGlobalEnable(&Gpio);
//使能串口中断
XUartLite_EnableInterrupt(&Uart);
//启用外设对应的中断向量
XIntc_Enable(&Intc,AXI_GPIO_INTR_ID);
XIntc_Enable(&Intc,UART_INTR_ID);
//启动中断控制器
XIntc_Start(&Intc, XIN_REAL_MODE);
//设置并打开中断异常处理
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(EXCEPTION_ID,
(Xil_ExceptionHandler)XIntc_InterruptHandler,&Intc);
Xil_ExceptionEnable();
for(;1;){
Xil_Out32(0x40000000 , 0xffff);
sleep(1);
Xil_Out32(0x40000000 , 0x0000);
sleep(1);
print("Hello\n\r");
xil_printf("word\n\r");
sleep(1);
}
cleanup_platform();
return 0;
}
void GpioHandler(void *CallbackRef){
XGpio *GpioPtr = (XGpio *)CallbackRef;
print("gpio interrupt\n\r");
XGpio_InterruptDisable(GpioPtr, 1); //关闭中断
XGpio_InterruptClear(GpioPtr, 1); //清除中断
XGpio_InterruptEnable(GpioPtr, 1); //使能中断
}
void uart_handler(void *CallbackRef)//中断处理函数
{
u8 Read_data;
u32 isr_status;
XUartLite *InstancePtr= (XUartLite *)CallbackRef;
//读取状态寄存器
isr_status = XUartLite_ReadReg(InstancePtr->RegBaseAddress ,
XUL_STATUS_REG_OFFSET);
if(isr_status & RX_NOEMPTY){
//接收 FIFO 中有数据
//读取数据
Read_data=XUartLite_ReadReg(InstancePtr->RegBaseAddress ,
XUL_RX_FIFO_OFFSET);
//发送数据
XUartLite_WriteReg(InstancePtr->RegBaseAddress ,
XUL_TX_FIFO_OFFSET, Read_data);
xil_printf("%x\n",Read_data);
print("\n\r");
}
print("uart interrupt\n\r");
}