ZYNQ PL 添加IP 串口UART AXI UART16550


源代码下载

开发环境、硬件

vivado2018.3

正点原子领航者v2开发板
7020
在这里插入图片描述
使用管脚:COM2 对应PL的K14 M15

FPGA部分

open block design
添加PS部分
在这里插入图片描述
双击进行配置
在这里插入图片描述
配置PS串口
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
设置ddr内存
在这里插入图片描述
设置时钟,FCLK就是PL时钟
在这里插入图片描述
设置中断用于PL串口
在这里插入图片描述
添加uart IP核
在这里插入图片描述
Run Block Automation
在这里插入图片描述
Run Connection Automation
在这里插入图片描述
连接中断到IRQ_F2P(按照红线来)
在这里插入图片描述
uart ip点开加号,引出两个端口
在这里插入图片描述
搞好后是这个样子
在这里插入图片描述
编写XDC约束

set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
set_property -dict {PACKAGE_PIN K14 IOSTANDARD LVCMOS33} [get_ports sin_0]
set_property -dict {PACKAGE_PIN M15 IOSTANDARD LVCMOS33} [get_ports sout_0]

生成HDL Wrapper
在这里插入图片描述
然后生成Bit Stream
export->HARDWARE
在这里插入图片描述

SDK部分

新建一个project
查看其中后缀bsp的文件夹,system.mss为我们提供了范例
在这里插入图片描述
此处做修改
在这里插入图片描述
在串口中断函数中做修改,xuartns550_intr_example.c

/******************************************************************************
*
* Copyright (C) 2002 - 2015 Xilinx, Inc.  All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/******************************************************************************/
/**
*
* @file xuartns550_intr_example.c
*
* This file contains a design example using the UART 16450/16550 driver
* (XUartNs550) and hardware device using interrupt mode.
*
* @note
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who  Date     Changes
* ----- ---- -------- ----------------------------------------------------------
* 1.00b jhl  02/13/02 First release
* 1.00b sv   06/08/05 Minor changes to comply to Doxygen and coding guidelines
* 1.01a sv   05/08/06 Minor changes for supporting Test App Interrupt examples
* 2.00a ktn  10/20/09 Updated to use HAL processor APIs and minor modifications
*		      as per coding guidelines.
* 2.01a ssb  01/11/01 Updated the example to be used with the SCUGIC in
*		      Zynq.
* 3.2   adk  15/10/14 Clear the global counters.If multiple instance of ip is
*		      present in the h/w design without clearing these counters
*		      will result undefined behaviour for the second ip
* 		      instance while running the peripheral tests.
* 3.4   ms   01/23/17 Added xil_printf statement in main function to
*                     ensure that "Successfully ran" and "Failed" strings
*                     are available in all examples. This is a fix for
*                     CR-965028.
* </pre>
******************************************************************************/

/***************************** Include Files **********************************/

#include "xparameters.h"
#include "xuartns550.h"
#include "xil_exception.h"

#ifdef XPAR_INTC_0_DEVICE_ID
#include "xintc.h"
#include <stdio.h>
#else
#include "xscugic.h"
#include "xil_printf.h"
#endif
#include "sleep.h"

/************************** Constant Definitions ******************************/

/*
 * The following constants map to the XPAR parameters created in the
 * xparameters.h file. They are defined here such that a user can easily
 * change all the needed parameters in one place.
 */
#ifndef TESTAPP_GEN
#define UART_DEVICE_ID		XPAR_UARTNS550_0_DEVICE_ID
#define UART_IRPT_INTR		XPAR_FABRIC_AXI_UART16550_0_IP2INTC_IRPT_INTR

#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC_DEVICE_ID		XPAR_INTC_0_DEVICE_ID
#else
#define INTC_DEVICE_ID		XPAR_SCUGIC_SINGLE_DEVICE_ID
#endif /* XPAR_INTC_0_DEVICE_ID */
#endif /* TESTAPP_GEN */

/*
 * The following constant controls the length of the buffers to be sent
 * and received with the UART.
 */
#define TEST_BUFFER_SIZE	10


/**************************** Type Definitions ********************************/

#ifdef XPAR_INTC_0_DEVICE_ID
#define INTC		XIntc
#define INTC_HANDLER	XIntc_InterruptHandler
#else
#define INTC		XScuGic
#define INTC_HANDLER	XScuGic_InterruptHandler
#endif /* XPAR_INTC_0_DEVICE_ID */

/************************** Function Prototypes *******************************/

int UartNs550IntrExample(INTC *IntcInstancePtr,
			XUartNs550 *UartInstancePtr,
			u16 UartDeviceId,
			u16 UartIntrId);

void UartNs550IntrHandler(void *CallBackRef, u32 Event, unsigned int EventData);


static int UartNs550SetupIntrSystem(INTC *IntcInstancePtr,
				XUartNs550 *UartInstancePtr,
				u16 UartIntrId);

static void UartNs550DisableIntrSystem(INTC *IntcInstancePtr, u16 UartIntrId);

/************************** Variable Definitions ******************************/

#ifndef TESTAPP_GEN
XUartNs550 UartNs550Instance;	/* Instance of the UART Device */
INTC IntcInstance;		/* Instance of the Interrupt Controller */
#endif

/*
 * The following buffers are used in this example to send and receive data
 * with the UART.
 */
u8 SendBuffer[TEST_BUFFER_SIZE];	/* Buffer for Transmitting Data */
u8 RecvBuffer[1];	/* Buffer for Receiving Data */

/******************************************************************************/
/**
*
* Main function to call the UartNs550 interrupt example.
*
* @param	None.
*
* @return	XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note		None.
*
*******************************************************************************/
#ifndef TESTAPP_GEN
int main(void)
{
	u16 Options;

	/*
	 * Initialize the UART driver so that it's ready to use.
	 */
	XUartNs550_Initialize(&UartNs550Instance, UART_DEVICE_ID);

	/*
	 * Perform a self-test to ensure that the hardware was built correctly.
	 */
	XUartNs550_SelfTest(&UartNs550Instance);

	/*
	 * Connect the UART to the interrupt subsystem such that interrupts can
	 * occur. This function is application specific.
	 */
	UartNs550SetupIntrSystem(&IntcInstance, &UartNs550Instance, UART_IRPT_INTR);

	/*
	 * Setup the handlers for the UART that will be called from the
	 * interrupt context when data has been sent and received, specify a
	 * pointer to the UART driver instance as the callback reference so
	 * the handlers are able to access the instance data.
	 */
	XUartNs550_SetHandler(&UartNs550Instance, UartNs550IntrHandler, &UartNs550Instance);

	Options = XUN_OPTION_DATA_INTR | XUN_OPTION_FIFOS_ENABLE |XUN_OPTION_RESET_TX_FIFO;

	XUartNs550_SetOptions(&UartNs550Instance, Options);

	while (1)  {
		print("running\r\n");
		sleep(1);
	}
//	/*
//	 * Disable the UartNs550 interrupt.
//	 */
//	UartNs550DisableIntrSystem(IntcInstancePtr, UartIntrId);
}
#endif

/*****************************************************************************/
/**
*
* This function is the handler which performs processing to handle data events
* from the UartNs550.  It is called from an interrupt context such that the
* amount of processing performed should be minimized.
*
* This handler provides an example of how to handle data for the UART and
* is application specific.
*
* @param	CallBackRef contains a callback reference from the driver,
*		in thiscase it is the instance pointer for the UART driver.
* @param	Event contains the specific kind of event that has occurred.
* @param	EventData contains the number of bytes sent or received for sent
*		and receive events.
*
* @return	None.
*
* @note		None.
*
*******************************************************************************/
void UartNs550IntrHandler(void *CallBackRef, u32 Event, unsigned int EventData)
{
	u8 Errors;
	XUartNs550 *UartNs550Ptr = (XUartNs550 *)CallBackRef;

	/*
	 * All of the data has been sent.
	 */
	if (Event == XUN_EVENT_SENT_DATA) {
		xil_printf("send \r\n");
	}

	/*
	 * All of the data has been received.
	 */
	if (Event == XUN_EVENT_RECV_DATA) {
		XUartNs550_Recv(&UartNs550Instance, RecvBuffer, 1);			//重新接收一下
		XUartNs550_Send(&UartNs550Instance, RecvBuffer, 1);
		xil_printf("r:%s \r\n",RecvBuffer);
	}

	/*
	 * Data was received, but not the expected number of bytes, a
	 * timeout just indicates the data stopped for 4 character times.
	 */
	if (Event == XUN_EVENT_RECV_TIMEOUT) {
		xil_printf("timeout \r\n");
	}

}

/******************************************************************************/
/**
*
* This function setups the interrupt system such that interrupts can occur
* for the UART.  This function is application specific since the actual
* system may or may not have an interrupt controller.  The UART could be
* directly connected to a processor without an interrupt controller.  The
* user should modify this function to fit the application.
*
* @param	IntcInstancePtr is a pointer to the instance of the Interrupt
*		Controller.
* @param	UartInstancePtr is a pointer to the instance of the UART.
* @param	UartIntrId is the interrupt Id and is typically
*		XPAR_<INTC_instance>_<UARTNS550_instance>_VEC_ID value from
*		xparameters.h.
*
* @return	XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* @note		None.
*
*******************************************************************************/
static int UartNs550SetupIntrSystem(INTC *IntcInstancePtr,
					XUartNs550 *UartInstancePtr,
					u16 UartIntrId)
{
	int Status;
#ifdef XPAR_INTC_0_DEVICE_ID
#ifndef TESTAPP_GEN
	/*
	 * Initialize the interrupt controller driver so that it is ready
	 * to use.
	 */
	Status = XIntc_Initialize(IntcInstancePtr, INTC_DEVICE_ID);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
#endif /* TESTAPP_GEN */

	/*
	 * 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 = XIntc_Connect(IntcInstancePtr, UartIntrId,
			   (XInterruptHandler)XUartNs550_InterruptHandler,
			   (void *)UartInstancePtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

#ifndef TESTAPP_GEN
	/*
	 * Start the interrupt controller such that interrupts are enabled for
	 * all devices that cause interrupts, specific real mode so that
	 * the UART can cause interrupts thru the interrupt controller.
	 */
	Status = XIntc_Start(IntcInstancePtr, XIN_REAL_MODE);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
#endif /* TESTAPP_GEN */

	/*
	 * Enable the interrupt for the UartNs550.
	 */
	XIntc_Enable(IntcInstancePtr, UartIntrId);

#else
#ifndef TESTAPP_GEN
	XScuGic_Config *IntcConfig;

	/*
	 * Initialize the interrupt controller driver so that it is ready to
	 * use.
	 */
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}

	Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
					IntcConfig->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
#endif /* TESTAPP_GEN */

	XScuGic_SetPriorityTriggerType(IntcInstancePtr, UartIntrId,
					0xA0, 0x3);

	/*
	 * Connect the interrupt handler that will be called when an
	 * interrupt occurs for the device.
	 */
	Status = XScuGic_Connect(IntcInstancePtr, UartIntrId,
				 (Xil_ExceptionHandler)XUartNs550_InterruptHandler,
				 UartInstancePtr);
	if (Status != XST_SUCCESS) {
		return Status;
	}

	/*
	 * Enable the interrupt for the Timer device.
	 */
	XScuGic_Enable(IntcInstancePtr, UartIntrId);
#endif /* XPAR_INTC_0_DEVICE_ID */

#ifndef TESTAPP_GEN

	/*
	 * Initialize the exception table.
	 */
	Xil_ExceptionInit();

	/*
	 * Register the interrupt controller handler with the exception table.
	 */
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			 (Xil_ExceptionHandler)INTC_HANDLER,
			 IntcInstancePtr);

	/*
	 * Enable exceptions.
	 */
	Xil_ExceptionEnable();

#endif /* TESTAPP_GEN */

	return XST_SUCCESS;
}


/*****************************************************************************/
/**
*
* This function disables the interrupts that occur for the UartNs550 device.
*
* @param	IntcInstancePtr is the pointer to the instance of the Interrupt
*		Controller.
* @param	UartIntrId is the interrupt Id and is typically
*		XPAR_<INTC_instance>_<UARTNS550_instance>_VEC_ID
*		value from xparameters.h.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
static void UartNs550DisableIntrSystem(INTC *IntcInstancePtr, u16 UartIntrId)
{

	/*
	 * Disconnect and disable the interrupt for the UartNs550 device.
	 */
#ifdef XPAR_INTC_0_DEVICE_ID
	XIntc_Disconnect(IntcInstancePtr, UartIntrId);
#else
	XScuGic_Disable(IntcInstancePtr, UartIntrId);
	XScuGic_Disconnect(IntcInstancePtr, UartIntrId);

#endif


}

实现效果:发给com2的内容直接从com2返回,并打印到ps端串口
在这里插入图片描述

PL串口相关寄存器

在xparameters.h中
在这里插入图片描述


/* Definitions for driver UARTNS550 */
#define XPAR_XUARTNS550_NUM_INSTANCES 1U
#define XPAR_XUARTNS550_CLOCK_HZ 50000000U

/* Definitions for peripheral AXI_UART16550_0 */
#define XPAR_AXI_UART16550_0_DEVICE_ID 0U
#define XPAR_AXI_UART16550_0_BASEADDR 0x43C00000U
#define XPAR_AXI_UART16550_0_HIGHADDR 0x43C0FFFFU
#define XPAR_AXI_UART16550_0_CLOCK_FREQ_HZ 50000000U


/******************************************************************/

/* Canonical definitions for peripheral AXI_UART16550_0 */
#define XPAR_UARTNS550_0_DEVICE_ID 0U
#define XPAR_UARTNS550_0_BASEADDR 0x43C00000U
#define XPAR_UARTNS550_0_HIGHADDR 0x43C0FFFFU
#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_AXI_UART16550_0_CLOCK_FREQ_HZ

//中断寄存器
/* Definitions for Fabric interrupts connected to ps7_scugic_0 */
#define XPAR_FABRIC_AXI_UART16550_0_IP2INTC_IRPT_INTR 61U

/******************************************************************/

/* Canonical definitions for Fabric interrupts connected to ps7_scugic_0 */
#define XPAR_FABRIC_UARTNS550_0_VEC_ID XPAR_FABRIC_AXI_UART16550_0_IP2INTC_IRPT_INTR

/******************************************************************/

主要的库函数均在这些文件之中 pluartbsp/ps7_cortexa9_0/libsrc/uartns550_v3_5之下
在这里插入图片描述
主要调用的函数

	u16 Options;

	/*
	 * Initialize the UART driver so that it's ready to use.
	 * 初始化自定义串口
	 */
	XUartNs550_Initialize(&UartNs550Instance, UART_DEVICE_ID);

	/*
	 * Perform a self-test to ensure that the hardware was built correctly.
	 * 自定义串口自检
	 */
	XUartNs550_SelfTest(&UartNs550Instance);

	/*
	 * Connect the UART to the interrupt subsystem such that interrupts can
	 * occur. This function is application specific.
	 * 初始化自定义串口中断
	 */
	UartNs550SetupIntrSystem(&IntcInstance, &UartNs550Instance, UART_IRPT_INTR);

	/*
	 * Setup the handlers for the UART that will be called from the
	 * interrupt context when data has been sent and received, specify a
	 * pointer to the UART driver instance as the callback reference so
	 * the handlers are able to access the instance data.
	 * 注册中断回调函数
	 */
	XUartNs550_SetHandler(&UartNs550Instance, UartNs550IntrHandler, &UartNs550Instance);

	Options = XUN_OPTION_DATA_INTR | XUN_OPTION_FIFOS_ENABLE |XUN_OPTION_RESET_TX_FIFO;
	/*
	 *配置串口选项
	 */
	XUartNs550_SetOptions(&UartNs550Instance, Options);

options在xuartns550.h中定义

/** @name Configuration options
 * @{
 */
/**
 * These constants specify the options that may be set or retrieved
 * with the driver, each is a unique bit mask such that multiple options
 * may be specified.  These constants indicate the function of the option
 * when in the active state.
 */
#define XUN_OPTION_RXLINE_INTR		0x0800 /**< Enable status interrupt */
#define XUN_OPTION_SET_BREAK		0x0400 /**< Set a break condition */
#define XUN_OPTION_LOOPBACK		0x0200 /**< Enable local loopback */
#define XUN_OPTION_DATA_INTR		0x0100 /**< Enable data interrupts */
#define XUN_OPTION_MODEM_INTR		0x0080 /**< Enable modem interrupts */
#define XUN_OPTION_FIFOS_ENABLE		0x0040 /**< Enable FIFOs */
#define XUN_OPTION_RESET_TX_FIFO	0x0020 /**< Reset the transmit FIFO */
#define XUN_OPTION_RESET_RX_FIFO	0x0010 /**< Reset the receive FIFO */
#define XUN_OPTION_ASSERT_OUT2		0x0008 /**< Assert out2 signal */
#define XUN_OPTION_ASSERT_OUT1		0x0004 /**< Assert out1 signal */
#define XUN_OPTION_ASSERT_RTS		0x0002 /**< Assert RTS signal */
#define XUN_OPTION_ASSERT_DTR		0x0001 /**< Assert DTR signal */
/*@}*/
  • 7
    点赞
  • 78
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
ZYNQ16550串口是一种串行通信接口,常用于嵌入式系统中。根据引用\[1\]和引用\[2\]的描述,配置ZYNQ16550串口的步骤如下: 1. 在Vivado中,使用黑金例程中的ps_axi_led例程添加PL侧的16550IP核。 2. 添加16550IP核和Constant IP核,并进行连接。其中,Constant IP核的freeze输出默认为0,rin和ctsn输出默认为1。将16550的sin和sout引出,并添加管脚约束。 3. 根据实际情况修改PL侧的映射地址。 4. 导出硬件并启动SDK。 5. 在SDK中导入例程,并进行测试。 另外,根据引用\[2\]的描述,还可以通过Open Block Design添加PS部分,并进行配置。配置PS串口、DDR内存、时钟和中断用于PL串口添加UART IP核,并进行连接。最后,编写XDC约束来设置引脚映射。 以上是配置ZYNQ16550串口的一般步骤,具体的配置细节和操作可以根据实际情况进行调整。 #### 引用[.reference_title] - *1* [在ZYNQPL添加串口IP16550](https://blog.csdn.net/BenRenYiGuaShi/article/details/122857529)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [ZYNQ PL 添加IP 串口UART AXI UART16550](https://blog.csdn.net/baidu_41704597/article/details/122028399)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值