做的课设,相当于复习了一遍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时钟,并不需要化为实际波特率。

程序

 `timescale 1ns / 1ps

 module cap_freqence(
input clk,
input rst_n,
input freq_in,
input cap_en,
output freq_cap//27bit 0-134,217,727 对输入信号波特率测得的频率
);
reg[:] freq_cap = 'd10416; //rst ??????
reg[:] tmp_cap,sequence_cap[:]; //cap 5 times and Use the smallest one as baud
reg [:] cap_cnt;
// reg cap_finish;
reg s0_RS_232_RX,s1_RS_232_RX; //同步寄存器,消除亚稳态
reg tmp0_RS_232_RX,tmp1_RS_232_RX; //数据寄存器,移位寄存器
reg cap_state; //0:idle 1:work
wire neg_RX;//下降沿
always@(posedge clk or negedge rst_n)//同步寄存器,消除亚稳态
if(!rst_n)
begin
s0_RS_232_RX <= 'b0;
s1_RS_232_RX <= 'b0;
end
else
begin
s0_RS_232_RX <= freq_in; //次态
s1_RS_232_RX <= s0_RS_232_RX;//现态
end
always@(posedge clk or negedge rst_n)//数据寄存器
if(!rst_n)
begin
tmp0_RS_232_RX <= 'b0;
tmp1_RS_232_RX <= 'b0;
end
else
begin
tmp0_RS_232_RX <= s1_RS_232_RX;
tmp1_RS_232_RX <= tmp0_RS_232_RX;
end
//共打两拍再检测输入脚
assign neg_RX = (!tmp0_RS_232_RX) & tmp1_RS_232_RX;//下降沿检测 always@(posedge clk or negedge rst_n)//cap工作状态
if(!rst_n)begin
cap_state <= ;
end
else if(neg_RX) //下降沿开始测频
cap_state <= ;
else if (tmp0_RS_232_RX) //高电平退出测频
cap_state <= ; always@(posedge clk or negedge rst_n)//以100Mhz时钟测输入引脚低电平脉宽
if(!rst_n)
begin
tmp_cap <= 'd0; end
else if(cap_state) //串口工作状态(接受)时计数
begin
if(tmp0_RS_232_RX) //计完一次频率
begin
sequence_cap[cap_cnt] <= tmp_cap;
tmp_cap <= 'd0;
cap_cnt <= cap_cnt + ;//0 1 2 3,4测完4次后为4
end
else
tmp_cap <= tmp_cap + 'b1;
end integer i;
reg[:] min_cap; always@(cap_cnt) //测完一个序列便从测频序列里找出最小脉宽即为bps
begin
if (cap_cnt == 'd5)
begin
min_cap=sequence_cap[];//1st one as minimal cap
for (i=;i<;i=i+)
if (sequence_cap[i] < min_cap)
if (sequence_cap[i] > )
min_cap = sequence_cap[i];
if (cap_en) //手动控制更新baud
freq_cap = min_cap;
end
end endmodule

这个程序有瑕疵,用了初始化。不懂

freq_cap
这个变量放在rst里面复位后,之后都不能被下面
freq_cap = min_cap;
这句更新,暂时这么写吧!

效果

基于FPGA自适应串口通信(Auto Baud Rate)的更多相关文章

  1. 012 基于FPGA的网口通信实例设计【转载】

    一.网口通信设计分类 通过上面其他章节的介绍,网口千兆通信,可以使用TCP或者UDP协议,可以外挂PHY片或者不挂PHY片,总结下来就有下面几种方式完成通信: 图8‑17基于FPGA的网口通信实例设计 ...

  2. 【Delphi】基于状态机的串口通信

    通信协议 串行通信接口(如RS232.RS485等)作为计算机与单片机交互数据的主要接口,广泛用于各类仪器仪表.工业监测及自动控制领域中. 通信协议是需要通信的双方所达成的一种约定,它对包括数据格式. ...

  3. 基于FPGA的光口通信开发案例|基于Kintex-7 FPGA SFP+光口的10G UDP网络通信开发案例

    前言 自著名华人物理学家高锟先生提出"光传输理论",实用化的光纤传输产品始于1976年,经历了PDH→SDH→DWDM→ASON→MSTP的发展历程.本世纪初期,ASON/OADM ...

  4. 纠错:基于FPGA串口发送彩色图片数据至VGA显示

    今天这篇文章是要修改之前的一个错误,前面我写过一篇基于FPGA的串口发送图片数据至VGA显示的文章,最后是显示成功了,但是显示的效果图,看起来确实灰度图,当时我默认我使用的MATLAB代码将图片数据转 ...

  5. QT5 TK1 串口通信

    对TK1中基于QT5的串口通信过程进行总结.按照软件安装及通信实现的顺序. 1.QT5安装 较简洁方式:打开软件中心(类似A形),搜索qtcreator,点击安装即可. 2.串口通信库安装 采用上述方 ...

  6. 基于FPGA的红外遥控解码与PC串口通信

    基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...

  7. [python] 3 、基于串口通信的嵌入式设备上位机自动测试程序框架(简陋框架)

    星期一, 20. 八月 2018 01:53上午 - beautifulzzzz 1.前言 做类似zigbee.ble mesh...无线网络节点性能测试的时候,手动操作然后看表象往往很难找出真正的原 ...

  8. PC和FPGA间的串口通信实现

    应用笔记 V1.0 2015/03/26 PC和FPGA间的串口通信实现   概述   本文将介绍PC和FPGA间的串口通信实现的基本思路和Verilog代码,对于通信而言,收发双方都要有相应的控制. ...

  9. VS2008基于对话框的MFC上位机串口通信(C++实现)简单例程

    首先,在 vs2008 环境下创建 MFC 运用程序 设置项目名称为 ComTest(这个地方随意命名,根据个人习惯),点击确定后,点击下一步 出现如下界面 选择"基于对话框"模式 ...

随机推荐

  1. LeetCode 674. 最长连续递增序列(Longest Continuous Increasing Subsequence) 18

    674. 最长连续递增序列 674. Longest Continuous Increasing Subsequence 题目描述 给定一个未经排序的整型数组,找到最长且连续的递增序列. Given ...

  2. win10改装win7

    参考链接: https://jingyan.baidu.com/article/3ea51489d0f3c852e61bba01.html 1. 制作win7 U盘启动盘 2. 设置BIOS 1:OS ...

  3. todo----mysql常用语句总结补充完成

    todo----mysql常用语句总结补充完成

  4. React项目使用Redux

    ⒈创建React项目 初始化一个React项目(TypeScript环境) ⒉React集成React-Router React项目使用React-Router ⒊React集成Redux Redux ...

  5. WUSTOJ 1333: Sequential game(Java)

    题目链接:1333: Sequential game Description Sequential detector is a very important device in Hardware ex ...

  6. pandas之时间序列笔记

    时间戳tiimestamp:固定的时刻->pd.Timestamp 固定时期period:比如2016年3月份,再如2015年销售额->pd.Period 时间间隔interval:由起始 ...

  7. Linux 进程控制

    分享知乎上看到的一句话,共勉: 学习周期分为学习,思考,实践,校正四个阶段,周期越短,学习效率越高. 前面讲的都是操作系统如何管理进程,接下来,看看用户如何进行进程控制. 1.进程创建 先介绍一下函数 ...

  8. 使用UltraISO制作Centos7 U盘启动盘遇到的坑

    下载.安装UltraISO软件 安装好以后,打开软件 击菜单栏的"文件"选项,再点击"打开"按钮,选择要刻录的系统镜像 点击菜单栏的"启动" ...

  9. lock的等效代码

    1.lock的等效代码 在.NET的多线程程序中,经常会遇到lock关键字来控制同步,比如下列代码: private object o = new object(); public void Work ...

  10. C#方法(用法,参数)

    方法:是一种用于实现可以由对象或类执行的计算或操作的成员,是一个已命名的语句集.方法就是把一些相关的语句组织到一起,用来执行一个任务的语句块.比如每个C#程序至少带一个main函数 1.格式:修饰符  ...