FPGA上板项目(六)——UART测试,串口收发

embedded/2024/11/25 6:09:06/

目录

  • 实验内容
  • 串口接收模块
    • 模块框图
    • 时序波形
    • 仿真结果
  • 顶层模块设计
    • 模块框图
    • 时序波形
    • 代码调整
    • 仿真结果
    • 上板测试


实验内容

  • 将接收到的数据发送出去,实现串口回环。

串口发送的内容 FPGA上板项目(五)——UART测试,串口发送 已做过阐述,本篇文章在此基础上实现串口接收功能 ,完成串口回环。

串口接收模块

模块框图

在这里插入图片描述

引脚方向位宽说明
clkin1时钟
rst_nin1同步低复位
rx_pinin1接收端引脚
rx_readyin1接收端准备标志位
rx_dataout8接收数据
rx_validout1接收数据有效标志位
  • rx_ready:tx_ready 为高时表示开始接收数据,可以理解为使能信号。

  • rx_valid:表征 tx_data 的有效性,为高时代表此帧数据已经串并转换完成。

时序波形

在这里插入图片描述

状态变量分析:

  • IDLE:空闲状态,等待下一次接收。
  • START:接收起始位。
  • DATA:接收数据位。
  • STOP:接收停止位。

时序图说明:

  • 为了避免错过下一帧数据的接收,STOP 状态的计数只进行半个周期。
  • RX_BITS 是对 RX_2 信号的采样,在每比特数据传输时的中间时刻进行。

仿真结果

对编写的 HDL 代码进行仿真,仿真时序图如下。逐个信号进行比对后,可以看出,仿真结果与预想的时序波形相同。

在这里插入图片描述

下面检验比特信息是否正确,对上面的波形图进行比特位截取。rx_pin 的数据为 1000 0100,将顺序取反后为 0010 0001,下图中 rx_data 的显示格式为无符号十进制数,即 0010 0001 对应的十进制 33。

在这里插入图片描述

顶层模块设计

实验内容回顾:将接收到的数据发送出去,实现串口回环

模块框图

在这里插入图片描述

时序波形

在这里插入图片描述

代码调整

在这里插入图片描述
在这里插入图片描述

调整前代码:

  • 状态机部分:
STOP:   beginif(baud_cnt == BAUD_CNT_MAX) beginstate <= IDLE;endend
  • tx_ready 赋值部分:
always@(posedge clk) beginif(!rst_n) begintx_ready <= 1'b1;endelse if(state == IDLE) begintx_ready <= ~tx_valid;endelse if(state == STOP && baud_cnt == BAUD_CNT_MAX) begintx_ready <= 1'b1;end
end

代码做调整前的仿真结果如上图

  • 现象:接收到了四个字符,但是回环过程只发送了第一、三两个字符。
  • 分析:我的代码设定是,tx_pin 发送停止位时,BAUD_CNT 要达到 BAUD_CNT_MAX,tx_ready 才会被拉高,发送数据的状态才可以从 STOP 变为 IDLE,才可开启下一次发送。这会导致发送数据所用时钟周期比接收数据所用时钟周期多一个,会使得发送模块错过第二个字符的 valid 信号。
  • 本质问题:下一个发送字符的 valid 信号拉高时,上一个字符还在 STOP 状态,没有进入 IDLE 状态。
  • 解决思路:减小发送过程中 STOP 状态的维持时间,可以与接收过程中 STOP 状态的维持时间保持一致(BAUD_CNT_MAX / 2)

调整后代码:

  • 状态机部分:
STOP:   beginif(baud_cnt == BAUD_CNT_MAX / 2) beginstate <= IDLE;endend
  • tx_ready 赋值部分:
always@(posedge clk) beginif(!rst_n) begintx_ready <= 1'b1;endelse if(state == IDLE) begintx_ready <= ~tx_valid;endelse if(state == STOP && baud_cnt == BAUD_CNT_MAX / 2) begintx_ready <= 1'b1;end
end

仿真结果

在这里插入图片描述

上板测试

在这里插入图片描述


http://www.ppmy.cn/embedded/139516.html

相关文章

力扣 LeetCode 111. 二叉树的最小深度(Day7:二叉树)

解题思路&#xff1a; 用后序遍历 题目要求的最小深度为根节点到叶子节点的最小深度&#xff0c;注意是到根节点&#xff0c;所以如图所示假设&#xff08;没有9这个节点&#xff09;是需要返回3的&#xff0c;而不是1&#xff08;根节点左子树为空的情况&#xff09;&#x…

基于yolov8、yolov5的植物类别识别系统(含UI界面、训练好的模型、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8、yolov8 SE注意力机制 或 yolov5、yolov5 SE注意力机制 &#xff0c; 直接提供最少两个训练好的模型。模型十分重要&#xff0c;因为有些同学的电脑没有 GPU&#xff0…

用sqlmap工具打sqli-labs前20关靶场

这个星期我们用手动注入打了前20关靶场&#xff0c;今天我们用sqlmap直接梭哈前20关 1.介绍sqlmap sqlmap是一个自动化的SQL注入工具&#xff0c;其主要功能是扫描&#xff0c;发现并利用给定的URL和SQL注入漏洞。 2.下载和使用sqlmap 官方下载地址&#xff1a;GitHub - sq…

鱼厂实习,光速转正了!

今天要分享的这篇文章&#xff0c;比较特殊&#xff0c;是我们团队一位同事写的。主要分享了他从 0 开始学编程&#xff0c;再到加入鱼厂光速转正的故事。长达 6000 多字&#xff0c;诉说了自己四年多的经历&#xff0c;满满的真情实感&#xff0c;大家可以当个小说阅读。 以下…

Python入门(10)--面向对象进阶

Python面向对象进阶 &#x1f680; 1. 继承与多态 &#x1f504; 1.1 继承基础 class Animal:def __init__(self, name, age):self.name nameself.age agedef speak(self):passdef describe(self):return f"{self.name} is {self.age} years old"class Dog(Anim…

React的hook✅

为什么hook必须在组件内的顶层声明&#xff1f; 这是为了确保每次组件渲染时&#xff0c;Hooks 的调用顺序保持一致。React利用 hook 的调用顺序来跟踪各个 hook 的状态。每当一个函数组件被渲染时&#xff0c;所有的 hook 调用都是按照从上到下的顺序依次执行的。React 内部会…

element ui table进行相同数据合并单元格

示例如图 //要合并的项&#xff08;自定义&#xff09; const columnArr ["dq","sj","xj","zj","zjj","zjfzr","nhxm","nhsjh","nhsfzh","","",""…

网络编程套接字概念(UTP和TCP)

前言&#xff1a; 认识了网络&#xff0c;我们就应该考虑一下如何编程实现不同主机上的应用进程之间如何进行双向互通的端点。 套接字&#xff08;Socket&#xff09;是网络编程的一种基本概念&#xff0c;套接字是应用程序通过网络协议进行通信的接口&#xff0c;是操作系统提…