3. UART串口通信
任务目标
在Zynq SoC上通过UART外设实现与PC的双向串口通信:PS端发送字符串,同时接收PC下发数据并原样回显。本案例以Zynq-7000系列(如XC7Z020)为硬件平台,使用Vivado SDK进行裸机开发。
硬件连接与依赖
- 硬件平台:Zynq-7000(如ZedBoard、ZC706或自制板卡),板上UART已连接至USB转串口芯片(如CP210x/FT232),通过Micro-USB线连接PC。
- 开发环境:Vivado 2018.3+(含SDK),需提前创建硬件工程并导出包含UART外设的硬件描述文件(.hdf)。
- 串口终端:PC端使用任意串口工具(如PuTTY、MobaXterm、串口助手),波特率设为115200,8位数据位、1位停止位、无校验、无流控。
核心实现
Zynq的UART控制器在PS端通过MIO引脚引出,SDK中BSP已自动生成UART驱动(uartps)。以下代码完成初始化、发送固定字符串、接收单字节并回显的完整功能:
#include <xparameters.h>
#include <xuartps.h>
#include <xil_printf.h>
#define UART_DEVICE_ID XPAR_XUARTPS_0_DEVICE_ID
#define BUFFER_SIZE 64
static XUartPs UartInst;
int UartInit(void) {
XUartPs_Config *Config;
int Status;
Config = XUartPs_LookupConfig(UART_DEVICE_ID);
if (Config == NULL) return XST_FAILURE;
Status = XUartPs_CfgInitialize(&UartInst, Config, Config->BaseAddress);
if (Status != XST_SUCCESS) return XST_FAILURE;
// 设置波特率115200,8N1
Status = XUartPs_SetBaudRate(&UartInst, 115200);
if (Status != XST_SUCCESS) return XST_FAILURE;
XUartPs_SetOperMode(&UartInst, XUARTPS_OPER_MODE_NORMAL);
return XST_SUCCESS;
}
int main(void) {
char RxBuffer[BUFFER_SIZE];
u32 ReceivedCount = 0;
int Status;
Status = UartInit();
if (Status != XST_SUCCESS) {
xil_printf("UART init failed!\r\n");
return -1;
}
xil_printf("UART ready. Type characters, they will be echoed back.\r\n");
while (1) {
// 非阻塞接收:读取当前FIFO中所有可用字节
ReceivedCount = XUartPs_Recv(&UartInst, (u8 *)RxBuffer, BUFFER_SIZE);
if (ReceivedCount > 0) {
// 原样回显接收到的数据
XUartPs_Send(&UartInst, (u8 *)RxBuffer, ReceivedCount);
}
}
return 0;
}
运行与验证
- 工程创建:在Vivado中完成Zynq PS配置(勾选UART1,MIO引脚默认分配),生成Bitstream并导出硬件到SDK。
- 编译下载:在SDK中新建Application Project,将上述代码替换默认的
helloworld.c,编译后下载到开发板运行(Program FPGA + Run)。 - 验证步骤:
- 打开串口终端,连接对应COM口,波特率115200。
- 观察终端是否打印
UART ready...提示信息——验证发送通路。 - 在终端中任意输入字符(如
Hello Zynq),观察是否原样回显——验证接收与发送双向通路。
- 通过标准:终端正确显示启动提示,且输入字符能逐字回显、无乱码、无丢失,即判定通信功能正常。
常见问题
- 无输出:检查串口终端波特率是否匹配;确认硬件连接正确;在SDK中确认BSP已包含
uartps驱动。 - 回显乱码:多为波特率不匹配或电源干扰,重新插拔USB转串口线并确认终端设置。
- 只能发不能收:检查代码中
XUartPs_Recv返回值判断逻辑,确保FIFO读取正确。