手写一个uart协议——rs232

server/2024/9/19 3:29:10/ 标签: fpga开发

先了解一下关于uart和rs232的基础知识

文章目录

  • 一、RS232的回环测试
    • 1.1模块整体架构
    • 1.2 rx模块设计
      • 1.2.1 波形设计
      • 1.2.2代码实现与tb
      • 1.2.4 仿真
    • 1.3 tx模块设计
      • 1.3.1 波形设计
      • 1.3.2 代码实现与tb
      • 1.3.4 顶层设计
      • 1.3.3 仿真

本篇内容:

一、RS232的回环测试

上位机由串口助手通过 rx 线往 FPGA 发 8 比特数据,当 FPGA接收到 8 比特数据后,再通过 tx 线把接收到的 8 比特数据给上位机发回去,要求上位机接收到的数据和上位机发送的数据一样,并且保证连续发送也没问题。

在这里插入图片描述

1.1模块整体架构

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

1.2 rx模块设计

1.2.1 波形设计

在这里插入图片描述

1.2.2代码实现与tb

代码:

module uart_rx(input wire clk,input wire rst,input wire rx,output reg [7:0]po_data,output reg po_flag);parameter CNT_END=100;  //9600bps cnt=5207  sim时,cnt=100;
parameter CNT_END_HALF=CNT_END/2;reg rx_t;
reg rx_tt;
reg rx_tt_reg;
reg [12:0] cnt;
reg cnt_flag;
reg bit_flag;
reg [3:0]bit_cnt;
// rx_t
always @(posedge clk) begin if(rst==1'b1) beginrx_t <= 'd1;end else beginrx_t<=rx ;end
end// rx_tt
always @(posedge clk) begin if(rst==1'b1) beginrx_tt <= 'd1;end else beginrx_tt<=rx_t ;end
end// rx_tt_reg
always @(posedge clk) begin if(rst==1'b1) beginrx_tt_reg <= 'd1;end else beginrx_tt_reg<=rx_tt ;end
end//cnt
always @(posedge clk) begin if(rst==1'b1) begincnt<= 'd0;end else if (cnt_flag==1'b1 && cnt==CNT_END) begincnt<='d0;endelse if (cnt_flag==1'b1) begincnt<=cnt+1'b1;endelse if (bit_cnt=='d8 && bit_flag==1'b1) begincnt<='d0;end
end//bit_flag
always @(posedge clk) begin if(rst==1'b1) beginbit_flag <= 'd0;end else if (cnt_flag==1'b1 && cnt==CNT_END_HALF) beginbit_flag<='d1;endelse bit_flag<='d0;
end// cnt_flag
always @(posedge clk) begin if(rst==1'b1) begincnt_flag <= 'd0;end else if (rx_tt==1'b0 && rx_tt_reg==1'b1) begincnt_flag<='d1;endelse if (bit_cnt=='d8 && cnt==CNT_END_HALF) begincnt_flag<='d0;end
end// bit_cnt
always @(posedge clk) begin if(rst==1'b1) beginbit_cnt  <= 'd0;end else if (bit_cnt=='d8 && bit_flag==1'b1) beginbit_cnt<='d0;endelse if (bit_flag==1'b1) beginbit_cnt<=bit_cnt+1'b1;endend// po_data
always @(posedge clk) begin if(rst==1'b1) beginpo_data <= 'd0;end else if (bit_cnt>0 && bit_flag==1'b1) beginpo_data<={rx,po_data[7:1]};end
end// po_flag
always @(posedge clk) begin if(rst==1'b1) beginpo_flag<= 'd0;end else if (bit_cnt=='d8 && bit_flag==1'b1) beginpo_flag<='d1;endelse po_flag<='d0;
end
endmodule

tb:

`timescale 1ns / 1psmodule tb_rx();reg clk;reg rst;reg rx;wire [7:0] po_data;wire po_flag;initial beginclk=0;rst=1;#100rst=0;endinitial beginrx=1;//空闲状态#100gen_rx();end//这里模拟发送20帧数据,每次发送80~1的任意数,发送前rx拉低,表示起始位
//由于9600波特率需要计数5207次,为了仿真方便,假设只需要计数100次。task gen_rx;integer i;integer j;begin		for (j = 0; j < 20; j=j+1) beginrx=0;for ( i = 0; i < 8; i=i+1) begin  repeat(100) begin //每隔100周期发送1bit数据;@(posedge clk);  endrx={$random};endrx=1; //每发送完一帧数据后,rx恢复空闲状态,维持10个周期后继续发送数据,直到发够20帧数据。repeat(10) begin@(posedge clk);end		endendendtask always #5 clk=~clk;uart_rx inst_uart_rx (.clk     (clk),.rst     (rst),.rx      (rx),.po_data (po_data),.po_flag (po_flag));endmodule

1.2.4 仿真

在这里插入图片描述

1.3 tx模块设计

1.3.1 波形设计

在这里插入图片描述

1.3.2 代码实现与tb

module uart_tx(input wire clk,input wire rst,input wire[7:0] po_data,input wire po_flag,output reg tx);parameter CNT_END=100; // bps为9600时,这里为:5207, 为仿真方便设为100。reg [7:0] po_data_reg;
reg [12:0]cnt;
reg cnt_flag;
reg bit_flag;
reg [3:0] bit_cnt;
// po_data_reg
always @(posedge clk) begin if(rst==1'b1) beginpo_data_reg<= 'd0;endelse po_data_reg<=po_data;
end// cnt
always @(posedge clk) begin if(rst==1'b1) begincnt <= 'd0;end else if (cnt_flag==1'b1 && cnt==CNT_END) begincnt <= 'd0;endelse if (cnt_flag==1'b1) begincnt<=cnt+1'b1;endend//cnt_flag
always @(posedge clk) begin if(rst==1'b1) begincnt_flag <= 'd0;end else if (po_flag==1'b1) begincnt_flag<='d1;endelse if (bit_cnt=='d8 && bit_flag==1'b1) begincnt_flag<='d0;end	
end// bit_flag
always @(posedge clk) begin if(rst==1'b1) beginbit_flag <= 'd0;end else if (cnt==CNT_END-1 && cnt_flag==1'b1) beginbit_flag<='d1;endelse bit_flag<='d0;
end// bit_cnt
always @(posedge clk) begin if(rst==1'b1) beginbit_cnt <= 'd0;end else if (bit_flag==1'b1 && bit_cnt=='d8) beginbit_cnt<='d0;endelse if (bit_flag==1'b1) beginbit_cnt<=bit_cnt+1'b1;end
end
// tx
always @(posedge clk) begin if(rst==1'b1) begintx <= 'd1;end else if (po_flag==1'b1) begintx<='d0;endelse if (bit_flag==1'b1 && bit_cnt=='d8) begintx<='d1;endelse if (bit_flag==1'b1) begintx<=po_data_reg[bit_cnt];end
end
endmodule

tb:

`timescale 1ns / 1ps
module tb_rx();reg clk;reg rst;reg rx;wire tx;initial beginclk=0;rst=1;#100rst=0;endinitial beginrx=1;//空闲状态#100gen_rx();end//这里模拟发送20次数据,每次发送80~1的任意数,发送前rx拉低,表示起始位
//由于9600波特率需要计数5207次,为了仿真方便,假设只需要计数100次。task gen_rx;integer i;integer j;begin		for (j = 0; j < 20; j=j+1) beginrx=0;for ( i = 0; i < 8; i=i+1) begin  repeat(100) begin //每隔100周期发送1bit数据;@(posedge clk);  endrx={$random};endrx=1; //每发送完一帧数据后,rx恢复空闲状态,维持100个周期(方便tx端完整传输完一帧数据)后继续发送数据,直到发够20帧数据。repeat(1000) begin@(posedge clk);end		endendendtask always #5 clk=~clk;top_uart inst_top_uart (.clk(clk), .rst(rst), .rx(rx), .tx(tx));endmodule

1.3.4 顶层设计

module top_uart(input wire clk,input wire rst,input wire rx,output wire tx);wire [7:0] po_data;
wire po_flag;uart_rx inst_uart_rx (.clk     (clk),.rst     (rst),.rx      (rx),.po_data (po_data),.po_flag (po_flag));uart_tx  inst_uart_tx (.clk     (clk),.rst     (rst),.po_data (po_data),.po_flag (po_flag),.tx      (tx));endmodule

1.3.3 仿真

在这里插入图片描述
可以看到,rx和tx波形一致,则能实现传输要求。


http://www.ppmy.cn/server/31777.html

相关文章

算法提高之货币系统

算法提高之货币系统 核心思想&#xff1a;背包 贪心 贪心思路&#xff1a;将a从小到大排序&#xff0c;因为a数组中数如果能用之前的数线性表示则它一定没用 所以对每一个数 求其是否能用前i-1个数表示&#xff08;背包求方案数&#xff09;如果不能被其他数表示 就加入到b数组…

Django后台项目开发实战五

完成两个功能&#xff1a; HR 可以维护候选人信息面试官可以录入面试反馈 第五阶段 创建 interview 应用&#xff0c;实现候选人面试评估表的增删改功能&#xff0c;并且按照页面分组来展示不同的内容&#xff0c;如候选人基础信息&#xff0c;一面&#xff0c;二面的面试结…

【JVM】Java工具(Arthas,APM,Java Agent,JMX)

Java工具 常见的Java工具有以下几类&#xff1a; 1、诊断类工具&#xff0c;如Arthas、VisualVM等。 2、开发类工具&#xff0c;如Idea、Eclipse。 3、APM应用性能监测工具&#xff0c;如Skywalking、Zipkin等。 4、热部署工具&#xff0c;如Jrebel等。 Arthas中 Java Ag…

初识MVC

初识MVC 理论部分 今天第一次学MVC&#xff0c;拿到一个练手项目。现在来记录一下学习过程。 项目的背景就是个学生管理系统。我只做后端。 从大的来说MVC将应用程序分为三个主要组件&#xff08;部分&#xff09;&#xff1a; 模型&#xff08;Model&#xff09;是应用程序…

Springboot 学习之数据库配置项加密工具:ulisesbocchio

在 springboot 项目中&#xff0c;我们为了规避安全漏洞的问题&#xff0c;要对数据库连接的用户名和密码等信息加密处理。ulisesbocchio 是一款好用的加密插件&#xff0c;下面分享一下使用方法。 一.配置 mavan 依赖&#xff0c;直接使用 spring-boot-starter 方式 <depe…

定点小数_

目录 定点小数表示和运算 定点小数的原码 定点小时加减法运算 定点小数 vs 定点整数 定点小数表示和运算 定点小数的原码 定点小数原反补转换 定点小时加减法运算 定点小数 vs 定点整数 定点小数原码依然是 取值范围等比数列 符号位 定点小数 同样的:

tensorflow_decision_forests\tensorflow\ops\inference\inference.so not found

恰好有一个帖子提到了py3.10里面的解决方案 pip install --user tensorflow2.11.0My tensorflow version is 2.11.0 and my tensorflow_decision_forests version is 1.2.0 so those should be compatible. I also am using Python version 3.10.11原文链接&#xff1a; http…

创建和激活python虚拟环境(venv), 以及在vscode上运行python虚拟环境

最近使用python做项目&#xff0c;发现佬们都是在用python的虚拟环境来放项目。发现确实有一些优势在这之中&#xff0c; 首先就是隔离性&#xff0c;我们将每个项目放入相对应的环境配置&#xff0c;可以有效避免乱七八糟的库出现在解释器中。其次就是可移植性强&#xff0c;…

【C++风云录】图形和动作捕捉库全面解析:从OpenPose到OpenCV

深入浅出&#xff1a;六大计算机视觉和动作捕捉库的教程和比较 前言 本文将为读者详细介绍六种在计算机视觉领域广泛使用的开源软件和SDK&#xff0c;包括OpenPose、Vicon SDK、Intel RealSense SDK、Microsoft Kinect SDK、PCL (Point Cloud Library)和OpenCV。我们会一一解…

【前端学习——call和apply函数】

call()和apply()这两个方法的作用可以简单归纳为改变this指向&#xff0c;从而让我们的this指向不在是谁调用了函数就指向谁。 call()方法的作用和 apply() 方法类似&#xff0c;区别就是call()方法接受的是参数列表&#xff0c;而apply()方法接受的是一个参数数组。 https:/…

用C#写一个特性,在函数上面可以自动计算函数耗时情况

用C#写一个特性&#xff0c;在函数上面可以自动计算函数耗时情况 TimingAttribute类是自定义的特性类&#xff0c;用来标记需要计时的方法。TimingInterceptor类是一个拦截器&#xff0c;它通过反射来拦截被TimingAttribute标记的方法&#xff0c;并在方法执行前后进行计时。My…

面试题分享之Java集合篇(三)

注意&#xff1a;文章若有错误的地方&#xff0c;欢迎评论区里面指正 &#x1f36d; 系列文章目录 面试题分享之Java基础篇&#xff08;二&#xff09;面试题分享之Java基础篇&#xff08;三&#xff09; 面试题分享之Java集合篇&#xff08;一&#xff09;、 面试题分享之Ja…

Java 基础面试 -- 异常处理

一、引言 在Java编程中&#xff0c;异常处理是确保程序稳定性和健壮性的重要机制。当程序在运行时遇到不可预见的问题&#xff0c;如文件读取失败、网络错误、除零异常等&#xff0c;异常处理机制允许我们捕获这些错误&#xff0c;并进行相应的处理&#xff0c;从而避免程序崩…

SQL-慢查询的定位及优化

定位慢查询sql 启用慢查询日志&#xff1a; 确保MySQL实例已经启用了慢查询日志功能。可以通过以下命令查看是否启用&#xff1a; SHOW VARIABLES LIKE slow_query_log;如果未启用&#xff0c;可以通过以下命令启用&#xff1a; SET GLOBAL slow_query_log ON;配置慢查询日志&…

ssm104园区停车管理系统+jsp

园区停车管理系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0c;所以对于信息的宣传和管…

数据库管理-第180期 23ai: Cloud/Container Plus AI(20240503)

数据库管理180期 2024-05-03 数据库管理-第180期 23ai: Cloud/Container Plus AI&#xff08;20240503&#xff09;1 Free版本更新2 如我所期3 宣传图Oracle Vector DBJSON Relational DualityProperty GraphsShardingTrue CacheFirewall 总结 数据库管理-第180期 23ai: Cloud/…

QT:label标签/进度条的使用

文章目录 设置不同格式的文本显示图片文本对齐/自动换行/缩进/边距LCDNumber倒计时 ProgressBar进度条 设置不同格式的文本 在文本格式中&#xff0c;存在富文本&#xff0c;makedown格式的文本&#xff0c;还有纯文本&#xff0c;下面就依据这三个进行举例 #include "w…

嵌入式开发四:STM32 基础知识入门

为方便更好的学习STM32单片机&#xff0c;本篇博客主要总结STM32的入门基础知识&#xff0c;重点在于理解寄存器以及存储器映射和寄存器映射&#xff0c;深刻体会STM32是如何组织和管理庞大的寄存器&#xff0c;从而提高开发效率的&#xff0c;为后面的基于标准库的开发做好铺垫…

Python实战开发及案例分析(2)——单目标优化

在Python中&#xff0c;进行单目标优化主要涉及定义一个优化问题&#xff0c;包括一个目标函数和可能的约束条件&#xff0c;然后选择合适的算法来求解。Python提供了多种库&#xff0c;如SciPy、Pyomo、GEKKO等&#xff0c;用于处理各种优化问题。 案例分析&#xff1a;使用 …

python实验一 简单的递归应用

实验一 实验题目 1、兔子繁殖问题(Fibonacci’s Rabbits)。一对兔子从出生后第三个月开始&#xff0c;每月生一对小兔子。小兔子到第三个月又开始生下一代小兔子。假若兔子只生不死&#xff0c;一月份抱来一对刚出生的小兔子&#xff0c;问一年中每个月各有多少只兔子。 &…