基于Xlinx Artix7的FPGA高级应用(三) USB转串口通信
本项目采用CP2102-GMR USB转串口芯片
UART之间采用双全工通信方式,理想的UART只有三个引脚:
我们知道CPU中的数据是并行的,所以在发送数据时,CPU将数据写入UART,然后UART以一定的格式将数据从TXD口串行输出;在接受数据时,RXD口串行接受数据然后存放在缓冲区内以供CPU读取。GND作为地为数据提供参考电位。
UART采用标准TTL/CMOS标准,但是为了提高抗干扰能力以及数据的长度,我们通常把它转换到RS-232逻辑标准(3到12V表示0,-3到 -12V表示1)
数据线以bit为单位串行收发数据,而UART有它自己的数据帧标准,有开始位、数据位、校验位(非必需)、停止位。在开始传输之前我们还需要约定好数据传输速率(每位占用时间,其倒数叫做波特率)和数据格式。
数据传输流程如下:
(1)平时数据线处于空闲状态(1状态)
(2)当要发送数据时,UART改变TxD数据线的状态(变为0状态)并维持1位的时间,这样接收方检测到开始位后,在等待1.5位的时间就开始一位一位地检测数据线的状态得到所传输的数据。
(3)UART一帧中可以有5、6、7或8位的数据,发送方一位一位地改变数据线的状态将他们发送出去,首先发送最低位。
(4)如果使用校验功能,UART在发送完数据后,还要发送1位校验位。有两种校验方法:奇校验、偶校验——数据位连同校验位中,1的数据等于奇数或偶数。
(5)最后,发送停止位,数据线恢复到空闲状态(1状态)。停止位的长度有3种:1位、1.5位、2位。
接下来我们看代码:
先来看发送部分
模块输入时钟、数据、还要有一个使能信号,输出串行数据。
首先设置波特率,我们选择每秒9600bit这种常见的速度标准,经过计算可以算出波特率,然后我们设置中间采样点。
接下来设置标志位等必要的环节。然后我们设置待发送数据寄存器,这里我们选用1bit开始位+8bit数据位+1bit停止位,除此之外我们还得设置一个一位的数据寄存器,数据将会从这个寄存器一位一位地输出,正好对应了我们前面讲的,数据流程如下:
接下来看一下波特率时钟产生:
当数据发送标志位有效时我们让波特率时钟开始计数,这里我们令到达中点时产生采样信号让数据开始发送。值得注意的是,在串行通信中波特率和比特率两个概念不一样,在二进制传输数据时它们的值相等,但一个单位是bit一个单位是次数。
当数据开始传输,我们按照流程先将input的八位数据填充上开始位和结束位,交给我们的待发送数据寄存器,然后我们之前定义了一个数据位数计数器,一旦完成写入,立刻清零标志位和待发送数据寄存器。
在写入数据寄存器的同时,我们用发送寄存器把待发送寄存器中的数据一位一位地取出来并且交给output输出。
上面两部操作是并行执行的,这样可以利用FPGA的优势,加快通信速度。
接下来我们看一下接受代码:
前面不用说,还是产生波特率时钟。
接收部分我们先定义一个数据接收缓冲器,第一个函数的功能是每个时钟上升沿就从输入口往缓冲器里写入一位数据。当接收到5个连续的0时作为开始接收数据的标志。
这里比较重要的是设置一个接受数据个数计数器来一位一位地接收数据。我们令了两个数据接收寄存器,一个r0,一个r1.随着波特率时钟到达中点,我们用不断计数数据个数计数器表示数据接收寄存器的每一位,然后从低到高依次写入r0,当接收结束时我们将r0的值赋给r1,将各项标志位,计数器清零。最后我们把r1输出给input完成数据接收。
我们的顶层驱动模块如下图:
今天就讲到这里了,如果需要完整工程文件的朋友可以私信我,或者发邮件到[email protected]
谢谢观看!