【FPGA-MicroBlaze】串口收发以及相关函数讲解

前言

工具:Vivado2018.3及其所对应的SDK版本

目前网上有许多MicroBlaze 的入门教程,比如下面的这个参考文章,用串口打印一个hello world。

【FPGA】Xilinx MicroBlaze软核使用第一节:Hello World!_fpga软核microblaze-CSDN博客

个人感觉这些文章的重合度极高,看多了也没有什么参考价值,且单单就串口打印而言,这个学会了也无法对我们实际工程产生多大的帮助。

个人工程

Vivado部分

在我的工程里,时钟的复位我用的是低电平复位,并且我没有将复位信号进行引出,而是用了一个常数进行代替,该常数固定输出1,不对整个模块进行复位。将模块建立完成之后,Creat HDL Wrapper,然后生成比特流文件,导出SDK即可。

关于XDC文件可以根据自己板卡的引脚进行约定即可,我的XDC文件是这样的

复制代码
set_property IOSTANDARD LVCMOS33 [get_ports clk_in]
set_property PACKAGE_PIN W19 [get_ports clk_in]

set_property IOSTANDARD LVCMOS33 [get_ports uart_rxd]
set_property PACKAGE_PIN N2 [get_ports uart_rxd]
set_property IOSTANDARD LVCMOS33 [get_ports uart_txd]
set_property PACKAGE_PIN N5 [get_ports uart_txd]

SDK部分

像大部分教程一样,建立一个Hello World工程,可以看到在system.mss中,有相关的几个例程可以进行参考。

直接选择这个工程进行导入,查看例程。

随后,对下述代码进行简单的分析。

将该代码贴上,并且把不必要的注释进行删除。

cpp 复制代码
#include "xparameters.h"
#include "xstatus.h"
#include "xuartlite.h"
#include "xil_printf.h"

#define TEST_BUFFER_SIZE 16    /* 定义TEST_BUFFER_SIZE 的值为16 */

int UartLitePolledExample(u16 DeviceId);    /* 定义函数 */

XUartLite UartLite;		/* Instance of the UartLite Device */

u8 SendBuffer[TEST_BUFFER_SIZE];	/* Buffer for Transmitting Data 发送数据的一个数组Buffer */
u8 RecvBuffer[TEST_BUFFER_SIZE];	/* Buffer for Receiving Data 接收数据的一个数组Buffer*/

/* 主函数的作用:将UartLitePolledExample(UARTLITE_DEVICE_ID) 的值返回给Status
 * 如果Status != XST_SUCCESS,则串口打印"Uartlite polled Example Failed\r\n"
 * 如果Status == XST_SUCCESS,则串口打印"Successfully ran Uartlite polled Example\r\n"
 */
int main(void)
{
	int Status;

	/*
	 * Run the UartLite polled example, specify the Device ID that is
	 * generated in xparameters.h
	 */
	Status = UartLitePolledExample(UARTLITE_DEVICE_ID);
	if (Status != XST_SUCCESS) {
		xil_printf("Uartlite polled Example Failed\r\n");
		return XST_FAILURE;
	}

	xil_printf("Successfully ran Uartlite polled Example\r\n");
	return XST_SUCCESS;

}


/* UartLitePolledExample函数的作用 */

int UartLitePolledExample(u16 DeviceId)
{
	int Status;
	unsigned int SentCount;    /* 定义SentCount为一个无符号数 */
	unsigned int ReceivedCount = 0;    /* 定义ReceivedCount为一个无符号数,且初值为0 */
	int Index;

	/*初始化串口,若失败则返回XST_FAILURE,若成功则函数继续向下进行判断
	 * Initialize the UartLite driver so that it is ready to use.
	 */
	Status = XUartLite_Initialize(&UartLite, DeviceId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*确定硬件平台已经成功建立
	 * Perform a self-test to ensure that the hardware was built correctly.
	 */
	Status = XUartLite_SelfTest(&UartLite);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*    for循环,SendBuffer[0] = 0,SendBuffer[1] = 1,...,SendBuffer[15] = 15;
     *        SendBuffer[0] = 0,SendBuffer[1] = 0,...,SendBuffer[15] = 0;
	 * Initialize the send buffer bytes with a pattern to send and the
	 * the receive buffer bytes to zero.
	 */
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		SendBuffer[Index] = Index;
		RecvBuffer[Index] = 0;
	}

	/*    用XUartLite_Send函数,将SendBuffer中的16个数据发送出去
	 * Send the buffer through the UartLite waiting til the data can be sent
	 * (block), if the specified number of bytes was not sent successfully,
	 * then an error occurred.
	 */
	SentCount = XUartLite_Send(&UartLite, SendBuffer, TEST_BUFFER_SIZE);
	if (SentCount != TEST_BUFFER_SIZE) {
		return XST_FAILURE;
	}

	/*    while(1)进行判断,判断接收到的数据个数是否等于XUartLite_Send函数所发送的数据个数
	 * Receive the number of bytes which is transfered.
	 * Data may be received in fifo with some delay hence we continuously
	 * check the receive fifo for valid data and update the receive buffer
	 * accordingly.
	 */
	while (1) {
		ReceivedCount += XUartLite_Recv(&UartLite,
					   RecvBuffer + ReceivedCount,
					   TEST_BUFFER_SIZE - ReceivedCount);
		if (ReceivedCount == TEST_BUFFER_SIZE) {
			break;
		}
	}

	/*    for循环,判断接收到的数据是否等于发送的数据若失败则返回XST_FAILURE
	 * Check the receive buffer data against the send buffer and verify the
	 * data was correctly received.
	 */
	for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
		if (SendBuffer[Index] != RecvBuffer[Index]) {
			return XST_FAILURE;
		}
	}

	return XST_SUCCESS;
}

在上述SDK的软件程序正,用到了许多函数,如XUartLite_Initialize、XUartLite_SelfTest、 XUartLite_Send、XUartLite_Recv,这些函数都可以在SDK中按住ctrl键,查看其功能。

比如进入XUartLite.h头文件中,就可以看到串口收发相关的函数调用了,还可以按住ctrl进一步查看其.c文件中的定义。

运行程序上板验证

右键工程,Run As--Run Configurations..中,设置复位。

终端显示

相关推荐
sz66cm10 小时前
FPGA基础 -- cocotb仿真之任务调度cocotb.start_soon与asyncio的使用注意事项
fpga开发
霖0012 小时前
ZYNQ裸机开发指南笔记
人工智能·经验分享·笔记·matlab·fpga开发·信号处理
tiantianuser12 小时前
NVMe高速传输之摆脱XDMA设计52: 上板资源占用率分析
fpga开发·nvme·pcie·xdma·高性能nvme
我爱C编程13 小时前
【仿真测试】基于FPGA的完整DQPSK通信链路实现,含频偏锁定,帧同步,定时点,Viterbi译码,信道,误码统计
fpga开发·帧同步·viterbi译码·dqpsk·频偏锁定·定时点
nnerddboy13 小时前
FPGA自学笔记(正点原子ZYNQ7020):2.IP核与组成
fpga开发
碰大点15 小时前
第8章 zynq uboot更新系统镜像并引导启动和个人心得
驱动开发·fpga开发·uboot·zynq
szxinmai主板定制专家16 小时前
基于ARM+FPGA的无人机数据采集卡,6通道24bit采集
arm开发·嵌入式硬件·fpga开发·无人机·能源
贝塔实验室17 小时前
QPSK信号载波同步技术---四相Costas 环法
数学建模·fpga开发·硬件工程·动态规划·信息与通信·信号处理·傅立叶分析
bnsarocket1 天前
Verilog和FPGA的自学笔记2——点亮LED
笔记·fpga开发·verilog·自学
易享电子1 天前
基于单片机智能台灯(调光,时钟)系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus