Serial communication of uart0 on pynq-z2

pynq-z2 is a PFGA development board, that is the pink board, which is quite expensive. Now let's talk about how to use the uart0 serial port on it.
Equipment needed:
pynq-z2, USB cable that can transmit data, computer with vivado software

1. Create a new vivado project, create a new Block Design and then add IP cores such as ZYNQ and GPIO. After automatic connection, you can get the schematic diagram as shown in the figure:
Insert picture description here

  1. Complete the top-level packaging, then comprehensively realize the generation of bitstream files, export the xsa file, and the hardware part is ready

xsa file:

set_property PACKAGE_PIN R14 [get_ports {led_0[0]}]
set_property PACKAGE_PIN P14 [get_ports {led_0[1]}]
set_property PACKAGE_PIN N16 [get_ports {led_0[2]}]
set_property PACKAGE_PIN M14 [get_ports {led_0[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_0[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_0[3]}]

  1. Create a new project and cpp file in vitis, create a BSP file at the same time, write serial communication code, including serial port initialization, serial port interrupt initialization and interrupt handling functions. Set the serial port baud rate to 115200, trigger when receiving a bit, and the interrupt mode is normal mode.
#include "xgpiops_hw.h"
#include <stdio.h>
#include "xil_printf.h"
#include "xuartps.h"
#include "xparameters.h"
#include "xscugic.h"
#include "xuartps_hw.h"

#define LED_BASE XPAR_GPIO_0_S00_AXI_BASEADDR
#define UART_Device_Id  XPAR_PS7_UART_0_DEVICE_ID
#define INTC_DEVICE_ID  XPAR_SCUGIC_SINGLE_DEVICE_ID
#define UART_INT_IRQ_ID     XPAR_XUARTPS_0_INTR
#define INTC        XScuGic

XUartPs UartPs;
INTC InterruptController;
void uart_init(XUartPs *UartInstPtr,u16 DeviceId)
{
    XUartPs_Config *Config;
    //根据ID查找配置信息
    Config = XUartPs_LookupConfig(DeviceId);
    //根据配置信息,初始化UART
    XUartPs_CfgInitialize(UartInstPtr, Config, Config->BaseAddress);
    //设置波特率
    XUartPs_SetBaudRate(UartInstPtr, 115200);
    //设置触发阈值
    XUartPs_SetFifoThreshold(UartInstPtr, 1);
    //改变模式为正常模式
    XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_NORMAL);
}
//中断处理函数
void UART_intr_handle(void *call_back_ref)
{
    XUartPs *uart_instance_ptr = (XUartPs *)call_back_ref;
    u32 rec_data = 0;
    u32 isr_status;
    //读取中断寄存器
    isr_status = XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress,XUARTPS_IMR_OFFSET);
    isr_status &= XUartPs_ReadReg(uart_instance_ptr->Config.BaseAddress,XUARTPS_ISR_OFFSET);

    //中断标志状态位,是否为RxFIFO触发
    if(isr_status & XUARTPS_IXR_RXOVR)
    {
        rec_data = XUartPs_RecvByte(XPAR_PS7_UART_0_BASEADDR);
        XUartPs_WriteReg(uart_instance_ptr->Config.BaseAddress,XUARTPS_ISR_OFFSET,XUARTPS_IXR_RXOVR);//清除中断
    }

    XUartPs_SendByte(XPAR_PS7_UART_0_BASEADDR,rec_data);//将接受到的数据返回
    XGpioPs_WriteReg(LED_BASE,0,rec_data&0x0f);//将接收到的数据后4位写入LED的状态
}

void uart_intr_int(INTC *IntcInstancePtr,XUartPs *UartInstancePtr,u16 UartIntrId)
{
    //UART控制器中断初始化
    XScuGic_Config *IntcConfig;
    IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
    XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
                        IntcConfig->CpuBaseAddress);
    Xil_ExceptionInit();
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                    (Xil_ExceptionHandler) XScuGic_InterruptHandler,
                    IntcInstancePtr);
    XScuGic_Connect(IntcInstancePtr, UartIntrId,
                      (Xil_ExceptionHandler) UART_intr_handle,
                      (void *) UartInstancePtr);
    XUartPs_SetInterruptMask(UartInstancePtr, XUARTPS_IXR_RXOVR);//设置触发leix
    XScuGic_Enable(IntcInstancePtr, UartIntrId);//使能中断设备
    Xil_ExceptionEnable();
}
int main()
{
    //初始化
    uart_init(&UartPs,UART_Device_Id);
    //UART控制器初始化
    uart_intr_int(&InterruptController, &UartPs,UART_INT_IRQ_ID);
    //收发数据
    print("Hello World\n\r");//打印hello World检测程序是否正常运行
    while(1)
    {}
    return 0;
}

In this way, the two-way transmission of the serial port is realized, and the data received by the serial port is used to control the status of the LED.For example, if the serial port sends 0x0a, the LED light will light up as 1010.

Guess you like

Origin blog.csdn.net/m0_48094455/article/details/108269221