ZYNQ UARTLITE学习小结

本文分享了作者在ZYNQ中使用PS调用UARTLITE IP核的经验教训,包括调试技巧、轮询模式及中断模式的应用,并提供了具体的代码示例。

经过一天的踩坑和学习,大概理解了ZYNQ 中PS调用UARTLITE的IP核的用法。
记录一下坑点

  1. 最好用xil_printf打印,用printf打印有时候打印不出来。调试的时候都没有打印,弄的我怀疑人生。
  2. 轮询模式和中断模式的应用中,假如发送开启了中断模式,那么接收也必须开启中断模式,接收不能用轮询的模式。
    基本上都是参考xilinx的例程来的,只是在调试的过程中,尝试了一下发送中断,接收轮询的方式,结果踩到坑里,很久也没出来。
    轮询模式代码如下:
	Status = XUartLite_Initialize(UartLiteInstPtr, UartLiteDeviceId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	Status = XUartLite_SelfTest(UartLiteInstPtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		SendBuffer[Index] = Index;
		RecvBuffer[Index] = 0;
	}

	XUartLite_Send(UartLiteInstPtr, SendBuffer, TEST_BUFFER_SIZE);


	usleep(1000);
	xil_printf("So%d,%d ",TotalSentCount,cnttest);
	cnttest=0;
	usleep(1000);
	while (1) {
		ReceivedCount += XUartLite_Recv(UartLiteInstPtr,
							   RecvBuffer + ReceivedCount,
							   TEST_BUFFER_SIZE - ReceivedCount);
		if (ReceivedCount == TEST_BUFFER_SIZE) {
			for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
				if(RecvBuffer[Index] == SendBuffer[Index]) {
					if(Index == TEST_BUFFER_SIZE-1)
						xil_printf("rcv successful,%d\r\n ",ReceivedCount);
				}
				else
					xil_printf("rcv[%d] fail\r\n",Index);
			}
			ReceivedCount = 0;
		}
	}

中断模式的代码如下:

Status = XUartLite_Initialize(UartLiteInstPtr, UartLiteDeviceId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	Status = XUartLite_SelfTest(UartLiteInstPtr);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	Status = UartLiteSetupIntrSystem(IntcInstancePtr,
					 UartLiteInstPtr,
					 UartLiteIntrId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	XUartLite_SetSendHandler(UartLiteInstPtr, UartLiteSendHandler,
							 UartLiteInstPtr);
	XUartLite_SetRecvHandler(UartLiteInstPtr, UartLiteRecvHandler,
							 UartLiteInstPtr);
	XUartLite_EnableInterrupt(UartLiteInstPtr);


	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		SendBuffer[Index] = Index;
		RecvBuffer[Index] = 0;
	}

	XUartLite_Recv(UartLiteInstPtr, RecvBuffer, TEST_BUFFER_SIZE*2);
	XUartLite_Send(UartLiteInstPtr, SendBuffer, TEST_BUFFER_SIZE);

	while ((TotalSentCount != TEST_BUFFER_SIZE)) {
	}
	usleep(1000);
	xil_printf("So%d,%d ",TotalSentCount,cnttest);
	cnttest=0;
	usleep(1000);
	while (1) {

		sleep(1);
		xil_printf("R%d,%d\r\n ",ReceivedCount,cnttest);
		if (ReceivedCount == TEST_BUFFER_SIZE*2) {
			XUartLite_Recv(UartLiteInstPtr, RecvBuffer, TEST_BUFFER_SIZE*2);
			ReceivedCount = 0;
		}
	}
<think>好的,我现在需要帮助用户在Zynq7020上配置和使用UART0替代UART1。用户之前可能遇到了只能使用UART1的问题,现在想切换到UART0。让我先回顾一下之前的对话和提供的引用资料,确保理解用户的需求和现有信息。 首先,用户之前的提问是关于Zynq7020只能使用UART1的情况,而我的回答详细说明了UART1的配置和使用限制。现在用户想了解如何配置和使用UART0,可能是因为他们需要另一个UART接口,或者UART1被占用了。 接下来,查看用户提供的引用内容: 引用[1]提到,在Vivado中通过axi_uartlite扩展的串口波特率需要在生成比特流前设置好,无法动态更改。这提醒我在配置UART0时需要注意硬件设置,特别是波特率的固定性。 引用[2]和[3]讨论了在Linux下配置双串口(UART0和UART1),其中UART1被用作控制台,而UART0需要用户自行开发应用程序来使用。这涉及到Petalinux的配置和启动参数的设置,特别是console参数指定了控制台使用的串口。 用户现在的问题是如何在Zynq7020上使用UART0,可能之前只能使用UART1。因此,我需要考虑以下几个方面: 1. **硬件配置(Vivado)**:确保UART0在Zynq PS配置中启用,并正确分配到MIO引脚。可能需要检查MIO引脚分配是否冲突,以及是否启用了UART0外设。 2. **软件配置(Petalinux/Linux)**:调整设备树(Device Tree)以启用UART0,可能需要修改内核启动参数(bootargs)来将控制台从UART1切换到UART0,或者保持UART1作为控制台而单独启用UART0作为普通串口。 3. **驱动和应用程序**:确保Linux内核中已包含UART0的驱动,并了解如何在用户空间访问UART0设备(如/dev/ttyPS0)。 用户之前的问题中可能已经配置了UART1作为控制台,现在需要启用UART0。根据引用[2]和[3],在Petalinux中配置双串口需要生成BOOT.BIN和image.ub,并设置启动参数。例如,启动参数中的console=ttyPS0,115200指定了控制台使用UART0,而用户可能需要将控制台保留在UART1,单独启用UART0,或者将控制台切换到UART0并释放UART1。 另外,需要注意UART0和UART1的MIO引脚分配是否冲突,确保在Vivado中正确分配引脚。例如,UART0默认可能使用MIO引脚的不同位置,需要根据硬件设计进行调整。 可能的步骤包括: - Vivado中启用UART0并分配引脚。 - 生成新的硬件描述文件(XSA)。 - 在Petalinux中更新硬件描述,配置设备树以启用UART0。 - 调整启动参数,决定哪个UART作为控制台。 - 编译并部署到SD卡,测试UART0的功能。 同时,用户可能需要编写应用程序来访问UART0,例如使用Linux下的串口编程(open, read, write等函数)或者使用现有的工具如minicom。 需要验证的问题包括:UART0的引脚是否正确连接,设备树节点是否启用,驱动是否加载,权限是否正确(/dev/ttyPS0的访问权限),以及是否有其他服务占用了该串口。 总结来说,用户需要从硬件配置到软件驱动的完整流程来启用UART0,并可能调整控制台设置,确保UART0可用。同时,引用中提到波特率在axi_uartlite中需要预先设置,因此如果是通过PL扩展的UART,需要注意这一点,但如果是PS的UART0,则可能支持动态调整波特率。</think>### Zynq7020 UART0 配置与使用指南 #### 一、硬件配置(Vivado 环境) 1. **启用 UART0** - 在 Vivado 的 Zynq PS 配置界面中,确保 **UART0** 已启用(路径:`Processing System → Peripheral I/O Pins → UART 0`)。 - **MIO 引脚分配**:UART0 默认使用 MIO2(TX)和 MIO3(RX),需确认引脚未被其他功能占用(如 SPI、I2C)[^1]。 ![Zynq UART0 MIO 配置示例](https://example.com/zynq-uart0-mio.png) 2. **时钟与波特率设置** - UART0 的输入时钟与 UART1 共享 PS 内部时钟(默认 100 MHz),波特率计算公式为: $$ \text{分频值} = \frac{\text{PS\_CLK}}{\text{16 × 目标波特率}} $$ 例如,115200 波特率对应分频值约为 54。 #### 二、软件配置(Petalinux 与 Linux 环境) 1. **设备树配置** - 在 Petalinux 中更新设备树,确保 UART0 节点已启用: ```c &uart0 { status = "okay"; }; ``` - 若需 **禁用 UART1 控制台**,需修改 `bootargs` 参数(在 `system-user.dtsi` 中): ```c chosen { bootargs = "console=ttyPS0,115200 root=/dev/mmcblk0p2 rw earlyprintk"; }; ``` 2. **内核驱动验证** - 启动后执行 `dmesg | grep tty`,确认 UART0 设备 `/dev/ttyPS0` 已识别: ``` [ 0.000000] console [ttyPS0] enabled [ 1.234567] xuartps e0000000.serial: ttyPS0 at MMIO 0xe0000000 (irq = 24) is a xuartps ``` #### 三、UART0 使用示例 1. **Linux 用户空间访问** - 使用 `stty` 设置波特率: ```bash stty -F /dev/ttyPS0 115200 ``` - 通过 `echo` 和 `cat` 测试收发: ```bash echo "Hello UART0" > /dev/ttyPS0 # 发送数据 cat < /dev/ttyPS0 # 接收数据 ``` 2. **Python 串口通信** ```python import serial port = serial.Serial("/dev/ttyPS0", baudrate=115200, timeout=1) port.write(b"Test UART0\n") response = port.readline() print(response.decode()) ``` #### 四、常见问题与解决方法 1. **UART0 无法识别** - **检查引脚冲突**:确认 MIO2/MIO3 未被其他外设(如 SPI)占用[^1]。 - **验证设备树状态**:确保 `status = "okay"` 且无语法错误。 2. **波特率不匹配** - **硬件与软件一致性**:Vivado 中 UART0 的时钟分频需与 Linux 驱动设置的波特率一致(引用[1]中提及的 PL 扩展 UART 需固定波特率,但 PS 的 UART0 支持动态调整)。 3. **权限问题** - 执行 `chmod 666 /dev/ttyPS0` 或添加用户到 `dialout` 组以解决 `/dev/ttyPS0: Permission denied` 错误。 #### 五、典型应用场景 - **双串口通信**:UART0 作为数据通道,UART1 保留为系统控制台[^2]。 - **工业控制**:通过 UART0 连接 RS485 模块与 PLC 设备。 --- ### 相关问题 1. 如何在 Petalinux 中同时启用 UART0 和 UART1 作为独立串口? 2. UART0 的 MIO 引脚与其他外设冲突时如何重新分配? 3. 如何通过 DMA 提升 Zynq7020 UART0 的数据吞吐量?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值