Microblaze realiza puerto serie e interrupción GPIO

introducir

Use el núcleo blando microblaze para construir un procesador e implementar interrupciones.
imagen
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
imagen
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
imagen

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
imagenimagenmismo 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 interrupcionesimagenimagen

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");
}

archivo fuente del proyecto git_hub

Nota: Para implementar el programa de interrupción anterior, la memoria local del procesador no puede ser la predeterminada de 8 kb, sino que se puede cambiar a 64 kb; de lo contrario, la memoria es demasiado pequeña para ejecutar el programa.

Supongo que te gusta

Origin blog.csdn.net/QUACK_G/article/details/126286727
Recomendado
Clasificación