做的课设,相当于复习了一遍verilog。
实现了
1.接收端固定模式:8N1 BAUD:921600。
2.发送端8N1,任意波特率(不取极端值)。
3.数码管显示波特率(16进制)。
用了
1.两天一夜。
2.ego1平台+usb2uart。
整体框图
输入tx信号经过频率捕获层获得100Mhz下的计数值,送给波特率产生层得到接收层波特率。
接收层接收数据送给串口FIFO层,串口FIFO层根据发送层的反馈将数据送出FIFO。
发送层将数据按固定921600波特率发给PC机。从而实现波特率交换。
频率捕获层算法
1.uart协议
这里只考虑最常用的8N1,即8位数据,无校验,1位停止位。
在时钟线上升沿,tx线下降沿并维持到下一个上升沿即为一个开始位。然后8位数据(低位在前)。然后到第10位停止位高电平。
值得一提的是,tx线不会在某个电平完后恢复初始电平,比如说上一个数据位是低,当前位还是低,这个数据位结束后不会变回高再变低。
有什么影响?倘若tx发送0xff,那么其实只有一个低电平脉宽!即起始位那个脉宽。
2.算法
先打两拍,同步时钟以及滤除尖峰脉冲。考虑到输入的数据信号大多为ascii码。
我们从里面找一个最特殊的,U,这个字符二进制为10101010,再加上开始结束位的tx线电平变化为:
0101010101,这里有4个或者说5个低电平脉宽,这是最理想的情况。这样测出来的脉宽都是波特率。
但是如果是一般的字符,发送一个字节可能获得多个低电平脉宽,从里面找最小的有极大可能就是波特率(极小可能最小的低电平脉宽是波特率的倍数)。
所以我们的算法就是多次测频率,从里面找一个最小的,即认为是波特率。注意这里的频率,波特率都是相对于ego1的100Mhz时钟,并不需要化为实际波特率。
程序
1 `timescale 1ns / 1ps 2 3 4 module cap_freqence( 5 input clk, 6 input rst_n, 7 input