admin管理员组

文章数量:1530235

ZYNQ进阶之路14--PS端uart串口接收不定长数据

  • 导语
  • ZYNQ串口简介
  • 实现步骤

导语

繁忙的博主又来了,本节我们实现一个比较简单的东西:串口。之前的章节中我们也有使用PS端的串口进行收发数据,但是都是接收固定长度的数据包,在实际的项目工程中是很不方便和不实用的。本章节我们来详细讲解ZYNQ中PS端串口接收的机制和实现接收不定长数据的原理。
本章节对应工程源码: ZYNQ进阶之路14工程 对应软件版本vivado2018.3

ZYNQ串口简介

ZYNQ PS端有两个串口,uart0和uart1。两个串口基本一样,只要学会了其中一个串口的配置,另一个串口也就照搬程序了。串口的硬件框图大致如下图所示:

如上图所展示的,一个串口有两个FIFO,接收和发送各用一个,FIFO的缓存能大大的提高串口的工作效率,并且减少CPU的干预。两个FIFO的宽度都为8bit,深度为64字节。当串口发送数据时,CPU/DMA通过总线将需要发送的数据写入TxFIFO中,硬件检测到FIFO中有数据或者数据到达一定数量就会往外发送数据直到TxFIFO为空。当串口接收数据时,硬件将数据缓存如RxFIFO中,当软件检测到RxFIFO有数据时,CPU/DMA就通过总线去读取RxFIFO直到RxFIFO为空。对于串口发送,我们一个字节一个字节发送便可,已经足够我们日常使用。本节我们主要讲解串口接收的原理,本节中我们使用两种中断实现串口接收不定长数据,第一种为RxFIFO阈值触发中断:这种中断首先是要给FIFO设置一个阈值,当RxFIFO中有效数据量大于等于阈值时,产生中断;第二种是接收数据超时(timeout)中断,使用过STM32的同学可能比较熟悉STM32中有一个串口的空闲中断,这里的接收数据超时中断和这个类似,如果在设定时间周期内没有接收到串口数据则产生超时中断。
同时使能以上两种中断便可以实现任意长度的串口数据接收了,接下来我们来看一下具体是如何实现的吧!

实现步骤

首先我们创建一个新的ZYNQ工程,具体工程创建流程参照 ZYNQ进阶之路5中的工程创建流程。工程创建后如下所示:

然后导入到SDK中,创建helloworld工程,输入如下代码实现本节功能:


上图中红框1为串口中断服务函数,
红框2读取中断类型
红框3中是读取FIFO数据代码,500为设置的读取数据长度,该值无论设置多大都无所谓,因为读取到FIFO为空后就不会再读数据了,而返回数值为实际读取到的数据数量。所以这里我们设置为500也是可以的。
红框4中为数据发送程序,将接收到的数据全部发送出去,并且只有接收到最后一个数据后发生超时中断才会触发数据发送。
红框5为串口初始化函数
红框6为设置超时中断的超时时间,超时时间=16个波特率时钟周期。其计算公式为:超时时间=n*4个波特率周期,本程序中n=4.
然后编译程序后,下载但芯片中,便可实现不定长数据接收了,其实际运行效果如下所示:

一次发送130个字节,发送一段时间后也不会出现丢数据的状况,还是相当稳定可靠的!好了本节内容就到此为止了,在下一节的内容中我们将讲解在ZYNQ中通过AXI stream接口+AXI DMA实现PS和PL的高速数据传输,有兴趣的博友可以持续关注本博主哦!博主邮箱:wanpengwork@163 博主微信技术公众号:鹏哥DIY。

本文标签: 进阶定长之路串口数据