FPGA学习笔记——串口回环实验
串口回环实验
串口大家应该都不陌生,总共一收一发两根线,很多FPGA也自带usb转串口芯片,今天做一个pc上位机将数据通过串口发给FPGA,FPGA直接将数据发回给pc端的串口环回实验。
波特率
波特率bps指的是串口一秒内能发多少个bit位,常见的波特率有9600、38400、115200等,这是PC与FPGA使用串口通信所约定好的一个速率。比如FPGA的时钟频率是50MHz,那么一秒钟就有50M个时钟周期,我又需要一秒钟发送9600个bit位,所以用50M除以9600得到大约5208,也就是说一个bit位要占据5208个时钟周期。
在本实验中我们使用50M的时钟,9600的波特率。
模块框图
框图很简单,总共两个主要的模块就是rx接收模块和tx发送模块,再加上一个顶层模块即可。接收模块将接收到的数据传给发送模块,发送模块再把数据发给PC,接收和发送是互不干扰的。
rx时序
这是我画的一张rx时序图。首先串口的时序是起始位为0,再跟八个数据位,然后是校验位(可有可无,这里省略),最后结束位拉高为1。
rx是一个异步信号,所以我在代码中是做了打两拍的异步处理;rx_flag是一个标志位,当检测到rx拉低时,立刻拉高rx_flag,同时这个信号也作为bps_cnt的加一条件,拉低条件是当bps_cnt记到5208个并且bit_cnt==0时可以拉低;bps_cnt就是在rx_flag拉高时不断地记满5208个即可;bit_cnt是比较重要的一个计数器,尤其要注意它的加一条件是当bps_cnt记到一半时加一,其实这也代表了rx_data在该时刻才去获取rx的值,这是为了取到最稳定的数据位,减少误码率。rx_vld就是一个标志接收到一个字节的数据的标志位,在bit_cnt记满清零的时刻拉高一个时钟;rx_data根据bit_cnt的加一来赋值,要注意串口是从一个字节的低位开始发的,发到最后是最高位,在rx_vld拉高的同时,正好读取完成一个字节的数据。
tx时序
发送模块的时序比接收简单一些,按照串口发送规则先拉低tx最后拉高即可,要注意的是在rx_vld到来时,要记得用一个寄存器锁存发来的一个字节的数据,不能直接用rx_data。
仿真验证
仿真结果如上,看上去没有问题。
RTL图
Quartus生成的RTL图,也可以看看。
上板验证
我们使用友善串口调试助手验证结果如上,实验成功。
本文地址:https://blog.csdn.net/weixin_46058270/article/details/107892385
上一篇: 聚划算说没钱补贴,用户都笑了