UART双向通信实现(序列机)

news2025/7/8 15:38:59

前言        

        UART(通用异步收发传输器)是一种串行通信协议,用于在电子设备之间进行数据传输。RS232是UART协议的一种常见实现标准,广泛应用于计算机和外围设备之间的通信。它定义了串行数据的传输格式和电气特性,以确保不同设备之间的兼容性和可靠性。RS232协议采用异步串行通信方式,通过数据线将并行数据转换为串行数据进行传输,接收端再将串行数据恢复为并行数据。RS232的标准包括信号电平、连接器类型和数据格式等规范,确保了设备之间的正确通信。它的常见应用包括计算机串口、调制解调器、打印机等设备的连接。

        UART通信实现与验证(RS232)

正文

一、UART双向通信实现(序列机)的设计验证

        1.项目需求

        完成9600波特率串口的数据收发实验

        2.技术介绍

        采用序列机架构,使用锁相环产生一个16倍9600波特率的时钟,当该时钟计数到16时,表示串口数据发送的1bit数据传输完成(即1bit数据在计数0时放置与txd数据线上,在16时完成该数据传输,下次计数0时传输下1bit数据)。为保证数据接收正常,数据接收需要在9600波特率的时钟的周期中心接收,对应16倍时钟,在计数器到7或8的时刻进行数据接收。

        为完成数据收发实验,将接收的数据在发送出去,完成数据回环,可以通过上位机去观察接收的数据是否完整以此验证实验成功。

        涉及到数据传递,虽然时钟相同但是正常情况需要进行数据缓存(建议,如果是异步时钟,必须进行数据缓存),常用的数据缓存有异步fifo,双口ram(本实验实验异步fifo)

        3.顶层架构

        

        4.端口描述

clk时钟接口(50Mhz)
rst_n复位按键(低电平有效)
rxd数据接收接口
txd数据发送接口

二、代码验证

顶层连线

module uart_tx_rx(
	input			clk	,
	input			rst_n	,
	input 		rxd	,
	
	output 		txd	
);

	wire clk_01536;
	wire rst_en;
	
	clk_uart	clk_uart_inst (
		.areset 	( ~rst_n ),
		.inclk0 	( clk ),
		.c0 		( clk_01536 ),
		.locked 	( rst_en )
	);
	
	wire[7:0]data,q_sig;
	wire rdempty,rdreq,down;

	uart_rx rx(
		.clk	(clk_01536	),
		.rst_n	(rst_en		),
		.rxd	(rxd			),//数据接收
		    
		.data	(data			),//接收数据打包
		.down	(down			) //输出有效
	);
	
	fifo	fifo_inst (
		.data 	(data	),
		.rdclk 	(clk_01536  ),
		.rdreq 	(rdreq  ),
		.wrclk 	(clk_01536  ),
		.wrreq 	(down  ),
		.q 		(q_sig  ),
		.rdempty (rdempty 	),
		.wrfull 	(  )
	);

	uart_txd_v1 tx(
		.clk		(clk_01536	),
		.rst_n	(rst_en		),
		.data		(q_sig		),
	   .done		(rdempty		),
		
		.txd		(txd			),
		.rd_en	(rdreq		)
	);
endmodule

收数据模块

module uart_rx(
	input				clk	,
	input				rst_n	,
	input				rxd	,//数据接收
		
	output reg[7:0]data	,//接收数据打包
	output reg 		down	 //输出有效
);
	reg state;
	reg [7:0]temp;
	reg [7:0]cnt;
	
	always@(posedge clk,negedge rst_n)//cnt在工作状态计数
	begin
		if(!rst_n)
			cnt <= 0;
		else if(state == 1)
			cnt <= cnt + 1;
		else
			cnt <= 0;
	end
	
	always@(posedge clk,negedge rst_n)
	begin
		if(!rst_n)
			state <= 0;
		else
			case(state)
				0:	if(rxd == 0)//等待起始信号
						state <= 1;
					else
						state <= 0;
				1: if(cnt == 153)//完成一包数据接收
						state <= 0;
					else
						state <= 1;
			default:state <= 0;
			endcase
	end
	
	always@(posedge clk,negedge rst_n)
	begin
		if(!rst_n)
			begin
				temp <= 0;
				down <= 0;
				data <= 0;
			end
		else
			case(cnt)
				0:
				begin
					temp <= 0;
					down <= 0;
					data <= data;
				end
				1*16+7:temp[0] <= rxd;//在每个时序的中间收数据,数据在N*16时放在rxd上,保证数据稳定,在N*16 + 7时读
				2*16+7:temp[1] <= rxd;
				3*16+7:temp[2] <= rxd;
				4*16+7:temp[3] <= rxd;
				5*16+7:temp[4] <= rxd;
				6*16+7:temp[5] <= rxd;
				7*16+7:temp[6] <= rxd;
				8*16+7:temp[7] <= rxd;
				9*16+7:
				begin
					down <= 1;
					data <= temp;
				end
				9*16+7+1:down <= 0;
			endcase
	end
	
endmodule

发数据模块

module uart_txd(//fifo不为空时发
	input			clk	,//0.1536 = 9600 * 16 = 153600hz = 0.1536Mhz 
	input			rst_n	,
	input	[7:0]	data	,
	input			done	,
	
	output reg	txd	,
	output reg 	rd_en	
);
	
	reg [7:0]temp;
	reg [7:0]cnt;
	reg state;
	
	always@(posedge clk,negedge rst_n)//计数器在工作时进行计数
	begin
		if(!rst_n)
			cnt <= 0;
			else if(state == 1)//fifo不空,开始发送
			if(cnt < 10*16)
				cnt <= cnt + 1;
			else
				cnt <= 0;
			else
		cnt <= 0;
	end
	
	always@(posedge clk,negedge rst_n)
	begin
		if(!rst_n)
			state <= 0;
		else case(state)
				0:	if(done == 0)
						state <= 1;
					else
						state <= 0;
				1: if(cnt == 10*16)
						state <= 0;
					else
						state <= 1;
				default:state <= 0;
			endcase
	end
	
	always@(posedge clk,negedge rst_n)
	begin
		if(!rst_n)
			rd_en <= 0;
		else
			case(cnt)
				0:rd_en <= 0;
				1:rd_en <= 1;
				2:rd_en <= 0;
			endcase
	end
	
	always@(posedge clk,negedge rst_n)
	begin
		if(!rst_n)
			txd <= 1;
		else
			case(cnt)
				0:txd <= 1;
				1:txd <= 0;//起始位
				3:temp <= data;
				1*16:txd <= temp[0];//数据在时序开始时放在txd,
				2*16:txd <= temp[1];
				3*16:txd <= temp[2];
				4*16:txd <= temp[3];
				5*16:txd <= temp[4];
				6*16:txd <= temp[5];
				7*16:txd <= temp[6];
				8*16:txd <= temp[7];
				9*16:txd <= 1;
			endcase
	end

endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2328302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS 7 全流程部署Magic-PDF数据清洗工具(附GPU加速方案)

CentOS 7 全流程部署Magic-PDF数据清洗工具&#xff08;附GPU加速方案&#xff09; 一、环境准备与方案选型 1.1 硬件要求 配置项最低要求推荐配置CPU4核8核内存8GB16GB存储50GBSSD/NVMeGPU可选NVIDIA T4 1.2 系统环境检查 # 查看系统版本 cat /etc/redhat-release# 检查G…

LabVIEW多线程

在 LabVIEW 中&#xff0c;多线程编程是提升程序执行效率的关键手段&#xff0c;尤其是在需要并行处理数据采集、控制执行和用户界面交互的场景下。LabVIEW 本身是基于数据流&#xff08;Dataflow&#xff09;的编程语言&#xff0c;天然支持多线程&#xff0c;但要高效利用多线…

ctfshow _萌新 萌新_密码篇

萌新_密码1 先对密文进行 Hex 解码&#xff0c;得到了 S1lkZjBhM2ViZDVjNGRjMTYwLUV7ZmI2M2VlMDI5OGI4ZjRkOH0 再进行 base64 解码&#xff0c;得到了 KYdf0a3ebd5c4dc160-E{fb63ee0298b8f4d8} 再进行栅栏解码&#xff0c;得到了 flag KEY{dffb06a33eeeb0d259c84bd8cf146d08…

蓝桥杯2024省赛PythonB组——日期问题

题目链接: https://www.lanqiao.cn/problems/103/learning/?page1&first_category_id1&name%E6%97%A5%E6%9C%9F%E9%97%AE%E9%A2%98 题目内容&#xff1a; 解题思路 import os import sys# 请在此输入您的代码 from datetime import datetime date_str input().str…

带头结点 的单链表插入方法(头插法与尾插法)

带头结点的单链表插入方法&#xff08;头插法与尾插法&#xff09; 在单链表的操作中&#xff0c;插入是最常见的操作之一&#xff0c;本文介绍 带头结点的单链表 如何实现 后插法 和 前插法&#xff08;包括 插入法 和 后插数据交换法&#xff09;&#xff0c;并提供完整的 C …

Opencv之dilib库:表情识别

一、简介 在计算机视觉领域&#xff0c;表情识别是一个既有趣又具有挑战性的任务。它在人机交互、情感分析、安防监控等众多领域都有着广泛的应用前景。本文将详细介绍如何使用 Python 中的 OpenCV 库和 Dlib 库来实现一个简单的实时表情识别系统。 二、实现原理 表情识别系统…

基于web的生产过程执行管理系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 随着世界经济信息化、全球化的到来和电子商务的飞速发展&#xff0c;推动了很多行业的改革。若想达到安全&#xff0c;快捷的目的&#xff0c;就需要拥有信息化的组织和管理模式&#xff0c;建立一套合理、畅通、高效的线上管理系统。当前的生产过程执行管理存在管理效率…

C++:继承+菱形虚拟继承的一箭双雕

目录 一、继承概念与定义 1.1、什么是继承&#xff1f; 1.2、继承定义 二、继承关系与访问限定符 2.1、继承方式 三、基类与派生类对象的赋值转换 3.1、向上转型 3.2、对象切片 四、继承中的作用域 4.1、隐藏 五、派生类中的成员函数 5.1、构造与析构 六、继承与友…

网络:华为数通HCIA学习:静态路由基础

文章目录 前言静态路由基础静态路由应用场景 静态路由配置静态路由在串行网络的配置静态路由在以太网中的配置 负载分担配置验证 路由备份&#xff08;浮动静态路由&#xff09;配置验证 缺省路由配置验证 总结 华为HCIA 基础实验&#xff0d;静态路由 & eNSP静态路由 基础…

CFResNet鸟类识别:原网络基础上改进算法

​本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊​ 先放一张ResNet50模型的鸟类识别结果图 一 ResNetSE-NetBN import matplotlib.pyplot as plt import tensorflow as tf import warnings as w w.filterwarnings(ignore) # 支持中文 plt.rcP…

Ubuntu 20.04 出现问号图标且无法联网 修复

在 Ubuntu 中遇到网络连接问题&#xff08;如出现问号图标且无法联网&#xff09;&#xff0c;可以通过以下命令尝试重启网络服务&#xff1a; 1. 推荐先修改DNS 编辑 -> 虚拟机网络编辑器-> VMnet8 ->NAT 设置 -> DNS 设置 -> 设置DNS 服务器 DNS填什么 取决…

基于Contiue来阅读open-r1中的GRPO训练代码

原创 快乐王子HP 快乐王子AI说 2025年04月03日 23:54 广东 前面安装了vscode[1]同时也安装了Coninue的相关插件[2]&#xff0c;现在想用它们来阅读一下open-r1项目的代码[3]。 首先&#xff0c;从启动训练开始(以GRPO为例子&#xff09; 第一步&#xff0c;使用TRL的vLLM后端…

51c嵌入式~单片机~合集7~※

我自己的原文哦~ https://blog.51cto.com/whaosoft/13692314 一、芯片工作的心脏--晶振 在振荡器中采用一个特殊的元件——石英晶体&#xff0c;它可以产生频率高度稳定的交流信号&#xff0c;这种采用石英晶体的振荡器称为晶体振荡器&#xff0c;简称晶振。 制作方法 …

英菲克(INPHIC)A9无线蓝牙鼠标 链接电脑的方式

英菲克&#xff08;INPHIC&#xff09;A9鼠标链接至电脑时&#xff0c;要长按住“模式切换MODE”按钮5秒左右的时间&#xff0c;此时模式指示灯变成蓝色&#xff0c;并且闪烁。 这时使用电脑的蓝牙设置中&#xff0c;“添加设备”&#xff0c;会出现BT4.0 Mouse提示&#xff0…

lua表table和JSON字符串互转

--print("local ssxc{\n"..string.gsub(str,":","").."\n}") Utils {} ---------------------------------------------------------------------------------- -- Lua-Table 与 string 转换 local function value2string(value, isA…

【每日一个知识点】分布式数据湖与实时计算

在现代数据架构中&#xff0c;分布式数据湖&#xff08;Distributed Data Lake&#xff09; 结合 实时计算&#xff08;Real-time Computing&#xff09; 已成为大数据处理的核心模式。数据湖用于存储海量的结构化和非结构化数据&#xff0c;而实时计算则确保数据能够被迅速处理…

c语言数据结构--------拓扑排序和逆拓扑排序(Kahn算法和DFS算法实现)

#include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h>//使用卡恩算法(Kahn)和深度优先算法(DFS)实现//拓扑排序和逆拓扑排序//拓扑排序和逆拓扑排序顶点顺序相反//图&#xff0c;邻接矩阵存储 #define MaxVertexNum 100 …

谷粒微服务高级篇学习笔记整理---nginx搭建正反向代理

正向与反向代理 **正向代理:**客户端向代理服务器发请求并指定目标服务器,代理向目标转交请求并将获得的内容转给客户端。 反向代理:用户直接访问反向代理服务器就可以获得目标服务器的资源。反向代理服务器统一了访问入口。 给首页配置反向代理 修改windows的hosts文件配…

2.pycharm保姆级安装教程

一、pycharm安装 1.官网上下载好好软&#xff0c;双击打开 2.下一步 3.修改路径地址 (默认也可以) 4.打勾 5.安装 不用重启电脑 二、添加解释器 1.双击软件&#xff0c;打开 2.projects – new project 3.指定项目名字&#xff0c;项目保存地址&#xff0c;解释器 4.右击 – …

【SQL】取消sql某一列的唯一值key值的方法

在插入数据到sql时&#xff0c;遇到了这个问题&#xff1a; Duplicate entry ‘XXX’ for key 起因是&#xff1a; 我之前设计表的时候&#xff0c;手动给product_title 这个列加了一个key&#xff0c; key 是这个字段的唯一键约束&#xff0c;就不能重复在这一列存入重复的数…