当前位置: 首页 > news >正文

FPGA实现UART对应的电路和单片机内部配合寄存器实现的电路到底有何区别?

一、UART相关介绍

UART是我们常用的全双工异步串行总线,常用TTL电平标准,由TXD和RXD两根收发数据线组成。

那么,利用硬件描述语言实现UART对应的电路和51单片机内部配合寄存器实现的电路到底有何区别呢?接下来我们对照看一下。

二、FPGA实现UART异步串行收发方式

对于FPGA而言,利用verilog实现这个过程,其实最重要的就是安排好对应的计数器并配合移位寄存器串并转换即可完成。

FPGA发送端对应的代码如下:

module uart_tx(input wire clk ,input wire rst_n ,input wire [7:0] pi_data ,input wire pi_flag ,output reg tx );reg [7:0] pi_data_reg;//用于寄存传进来的数据reg tx_flag ;reg [12:0] cnt_baud ;reg bit_flag1;reg [3:0] bit_cnt ;//在接收到pi_flag为高电平的时候寄存输入数?always@(posedge clk or negedge rst_n)beginif(!rst_n)pi_data_reg <= 'd0;else if(pi_flag == 1'b1)pi_data_reg <= pi_data ;endalways@(posedge clk or negedge rst_n)beginif(!rst_n)tx_flag <= 1'b0;else if(bit_flag1 == 1'b1 && bit_cnt == 'd8)tx_flag <= 1'b0;else if(pi_flag == 1'b1)tx_flag <= 1'b1;end always@(posedge clk or negedge rst_n)beginif(!rst_n)cnt_baud <= 'd0;else if(tx_flag == 1'b0)cnt_baud <= 'd0;else if(cnt_baud == 'd5207 && tx_flag == 1'b1)cnt_baud <= 'd0;else if(tx_flag == 1'b1)cnt_baud <= cnt_baud + 1'b1;endalways@(posedge clk or negedge rst_n)beginif(!rst_n)bit_flag1 <= 1'b0;else if(cnt_baud == 5206)bit_flag1 <= 1'b1;else bit_flag1 <= 1'b0;endalways@(posedge clk or negedge rst_n)beginif(!rst_n)bit_cnt <= 'd0;else if(bit_cnt == 'd8 && bit_flag1 == 1'b1)bit_cnt <= 'd0;else if(bit_flag1 == 1'b1)bit_cnt <= bit_cnt + 1'b1;end always@(posedge clk or negedge rst_n)beginif(!rst_n)tx <= 1'b1;//空闲状态else if(pi_flag == 1'b1)tx <= 1'b0;//起始?else if(bit_flag1 == 1'b1 && bit_cnt <= 'd7)tx <= pi_data_reg[bit_cnt];//8位数?else if(bit_cnt == 'd8 && bit_flag1 == 1'b1)tx <= 1'b1;//空闲?end
endmodule
FPGA接收端对应的代码如下:
module uart_rx(input wire clk ,input wire rst_n ,input wire rx ,output reg [7:0] po_data ,output reg po_flag);//用于打拍的寄存器reg rx1;reg rx2;reg rx2_reg ;reg rx_flag ;reg [12:0] cnt_baud ;reg bit_flag ;reg [3:0] bit_cnt ;//对接收到的外部信号进行打拍寄存always@(posedge clk)beginrx1 <= rx ;rx2 <= rx1 ;rx2_reg <= rx2 ;end//检测下降沿,拉高rx_flagalways @(posedge clk or negedge rst_n) beginif (!rst_n) beginrx_flag <= 1'b0;endelse if (rx2 == 1'b0 && rx2_reg == 1'b1) beginrx_flag <= 1'b1;endelse if(bit_flag == 1'b1 && bit_cnt == 'd8)rx_flag <= 1'b0;endalways @(posedge clk or negedge rst_n) beginif (!rst_n) cnt_baud <= 'd0;else if(rx_flag == 1'b0)cnt_baud <= 'd0;else if(cnt_baud == 'd5207 && rx_flag == 1'b1)//5207为波特率是9600时对应的计数值cnt_baud <= 'd0;else if(rx_flag == 1'b1)cnt_baud <= cnt_baud + 1'b1;endalways @(posedge clk or negedge rst_n) beginif (!rst_n) bit_flag <= 1'b0;else if(cnt_baud == 'd2603 && rx_flag == 1'b1)bit_flag <= 1'b1;else bit_flag <= 1'b0;end always @(posedge clk or negedge rst_n) beginif (!rst_n) bit_cnt <= 'd0;else if(bit_cnt == 'd8 && bit_flag == 1'b1)bit_cnt <= 'd0;else if(bit_flag == 1'b1 && rx_flag == 1'b1)bit_cnt <= bit_cnt + 1'b1;endalways @(posedge clk or negedge rst_n) beginif (!rst_n) po_data <= 'd0;else if(bit_flag == 1'b1 && bit_cnt >= 'd1)po_data <= {rx2_reg,po_data[7:1]};end always @(posedge clk or negedge rst_n) beginif (!rst_n) po_flag <= 1'b0 ;else if(bit_flag == 1'b1 && bit_cnt == 'd8)po_flag <= 1'b1 ;else po_flag <= 1'b0;endendmodule
顶层代码如下:
module top_uart(input wire clk ,input wire rst_n ,input wire rx ,output wire tx);wire [7:0] po_data ;wire po_flag ;uart_rx inst_uart_rx (.clk(clk), .rst_n(rst_n), .rx(rx), .po_data(po_data), .po_flag(po_flag));uart_tx inst_uart_tx (.clk(clk), .rst_n(rst_n), .pi_data(po_data), .pi_flag(po_flag), .tx(tx));endmodule
经过综合后,生成的对应原理图如下:

顶层:

tx:可以发现,这里其实每一位寄存器都对应着一个D触发器,剩余的逻辑由LUT实现。

rx:接收端同理。

三、单片机内部UART异步串行收发实现方式

对于51单片机而言,它内部是CPU控制一些在物理层面已经连接好寄存器,通过对寄存器的控制配合电路的改变完成整个任务。

对于串口通信这个任务而言,它的整个实现过程总结如下:

整个实现可分为三大部分,定时器、中断系统及对应的缓冲寄存器完成,三大部分配合内部CPU便可完成收发任务,具体示意图如下:

红色区域是定时器部分,它外部连接着晶振,通过对TH1和TL1寄存器写入初始值可实现具体溢出频率的控制,假设晶振频率位12MHz(12T模式下1us计数一次),TH1和TL1填入0xF3(对应十进制243),一共256,则每隔256-243=13个数就会溢出一次,则溢出率为1/13us=0.07692MHz,当SMOD=1时,频率只经过16也就对应4800Hz,就会对应波特率4800Baud。配合控制器即可完成对波特率的控制。

蓝色部分是用于发送和接收数据的缓冲区;

黄色部分是串口中断器,这个中断器在接收数据的时候需要使用,TI和RI是中断标志。

在使用方式上,对涉及的寄存器进行初始化后,将数据写入SBUF或通过中断读取SBUF内的数据即可完成发送接收任务。

对应配置代码如下:

#include <REGX51.H>/***  @brief 串口初始化,4800bps@11.0592MHz*  @param 无	*  @retval 无*/
void UART_Init()
{//对串行寄存器配置SCON=0x50;		//串行控制寄存器,涉及模式选择PCON &= 0x7F;		//电源控制寄存器(包括波特率)//对定时器0进行配置#11.0592MTMOD &= 0x0F;		//设置定时器模式,低4位保持不变TMOD |= 0x20;		//设置定时器模式,串口对应的模式需要是双8位模式TL1 = 0xFA;		//设定定时初值TH1 = 0xFA;		//设定定时器重装值ET1 = 0;		//禁止定时器1中断TR1 = 1;		//启动定定时器1//串口中断配置EA=1;//启动所有中断ES=1;//启动串口中断
}
/***  @brief 串口发送1个字节数据,4800bps@11.0592MHz*  @param Byte 要发送的一个字节数据*  @retval 无*/
void UART_SendByte(unsigned char Byte)
{SBUF=Byte;//将数据写入发送缓冲器即可while(TI==0);//是否有中断请求位TI=0;//软件置0
}//串口中断函数的模板,需要用的时候复制到主函数中
/*
//注意:一个函数不能既在主函数中出现,又在中断函数中出现
void UART_Routine() interrupt 4 //串口中断对应的中断号
{if(RI==1)//接收到了串口中断{P2=~SBUF;UART_SendByte(SBUF);RI=0;//需要由软件清0}}
*/

主函数代码如下:

#include <REGX51.H>
#include "Delay.h"
#include "UART.h"void main()
{UART_Init();while(1){}
}//注意:一个函数不能既在主函数中出现,又在中断函数中出现
void UART_Routine() interrupt 4 //串口中断对应的中断号
{if(RI==1)//接收到了串口中断{P2=~SBUF;UART_SendByte(SBUF);RI=0;//需要由软件清0}}

四、总结

均由寄存器加逻辑电路组成,只不过二者工作模式及灵活性差别很大,单片机依赖冯诺依曼架构需要控制器控制且电路固定(使得定时器、寄存器等资源有限),FPGA的并行及灵活性在这里体现的淋漓尽致。

相关文章:

FPGA实现UART对应的电路和单片机内部配合寄存器实现的电路到底有何区别?

一、UART相关介绍 UART是我们常用的全双工异步串行总线&#xff0c;常用TTL电平标准&#xff0c;由TXD和RXD两根收发数据线组成。 那么&#xff0c;利用硬件描述语言实现UART对应的电路和51单片机内部配合寄存器实现的电路到底有何区别呢&#xff1f;接下来我们对照看一下。 …...

数据库模型全解析:从文档存储到搜索引擎

目录 前言1. 文档存储&#xff08;Document Store&#xff09;1.1 概念与特点1.2 典型应用1.3 代表性数据库 2. 图数据库&#xff08;Graph DBMS&#xff09;2.1 概念与特点2.2 典型应用2.3 代表性数据库 3. 原生 XML 数据库&#xff08;Native XML DBMS&#xff09;3.1 概念与…...

【Java基础】Java异常捕捉,throws/throw、finally、try、catch关键字的含义与运用

1. Java 异常处理&#xff1a; 异常是程序中的一些错误&#xff0c;但并不是所有的错误都是异常&#xff0c;并且错误有时候是可以避免的。 比如说&#xff0c;你的代码少了一个分号&#xff0c;那么运行出来结果是提示是错 java.lang.Error&#xff1b;如果你用System.out.p…...

Android Studio 安装配置(个人笔记)

Android studio安装的前提是必须保证安装了jdk1.8版本以上 一、查看是否安装jdk cmd打开命令行&#xff0c;输入java -version 最后是一个关键点 输入 javac &#xff0c;看看有没有相关信息 没有就下载jdk Android studio安装的前提是必须保证安装了jdk1.8版本以上 可以到…...

计算机网络——数据链路层-介质访问控制

一、介质访问控制方法 在局域网中, 介质访问控制(medium access control)简称MAC&#xff0c;也就是信道访问控制方法&#xff0c;可以 简单的把它理解为如何控制网络节点何时发送数据、如何传输数据以及怎样在介质上接收数据&#xff0c; 是解决当局域网中共用信道的使用产生竞…...

pytest日志显示

在 pytest 中&#xff0c;可以通过 钩子函数 和 配置文件 pytest.ini 配置日志的显示方式&#xff0c;实现对日志的灵活控制。以下是常用实现方式及配置说明。 方式一&#xff1a;使用 conftest.py 钩子函数自定义日志显示 通过 conftest.py 文件中的钩子函数&#xff0c;实现…...

【信息系统项目管理师】第15章:项目风险管理过程详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 一、规划风险管理1、输入2、工具与技术3、输出二、识别风险1、输入2、工具与技术3、输出三、实施定性风险分析1、输入2、工具与技术3、输出四、实施定量风险分析1、输入2、工具与技术3、输出五、规划风险应对1、…...

Diffusers 使用 LoRA

使用diffusers 加载 LoRA&#xff0c;实现文生图功能。摘自 diffusers文档。 模型可以根据名称去modelscope找对应资源下载。使用的时候需要替换成具体路径。虽然modelscope和diffusers都使用了模型id&#xff0c;但是并不能通用。 不同的LoRA对应了不同的“trigger” words&am…...

云安全博客阅读(二)

2024-05-30 Cloudflare acquires BastionZero to extend Zero Trust access to IT infrastructure IT 基础设施的零信任 不同于应用安全&#xff0c;基础设置的安全的防护紧急程度更高&#xff0c;基础设施的安全防护没有统一的方案IT基础设施安全的场景多样&#xff0c;如se…...

SpringCloud系列教程:微服务的未来(六)docker教程快速入门、常用命令

对于开发人员和运维工程师而言&#xff0c;掌握 Docker 的基本概念和常用命令是必不可少的。本篇文章将带你快速入门 Docker&#xff0c;并介绍一些最常用的命令&#xff0c;帮助你更高效地进行开发、测试和部署。 目录 前言 快速入门 docker安装 配置镜像加速 部署Mysql …...

Vue 快速入门:开启前端新征程

在当今的 Web 开发领域&#xff0c;Vue.js 作为一款极具人气的 JavaScript 前端框架&#xff0c;正被广泛应用于各类项目之中。它以简洁的语法、高效的数据绑定机制以及强大的组件化开发模式&#xff0c;为开发者们带来了前所未有的开发体验。如果你渴望踏入前端开发的精彩世界…...

UVM:uvm_component methods configure

topic UVM component base class uvm_config_db 建议使用uvm_config_db代替uvm_resource_db uvm factory sv interface 建议&#xff1a;uvm_config_db 以下了解 建议打印error...

LLM 训练中存储哪些矩阵:权重矩阵,梯度矩阵,优化器状态

LLM 训练中存储哪些矩阵 目录 LLM 训练中存储哪些矩阵深度学习中梯度和优化器是什么在 LLM 训练中通常会存储以下矩阵: 权重矩阵:这是模型的核心组成部分。例如在基于 Transformer 架构的 LLM 中,每一层的多头注意力机制和前馈神经网络都会有相应的权重矩阵。以 BERT 模型为…...

大模型思维链推理的进展、前沿和未来分析

大模型思维链推理的综述&#xff1a;进展、前沿和未来 "Chain of Thought Reasoning: A State-of-the-Art Analysis, Exploring New Horizons and Predicting Future Directions." 思维链推理的综述&#xff1a;进展、前沿和未来 摘要&#xff1a;思维链推理&#…...

NLP 技术的突破与未来:从词嵌入到 Transformer

在过去的十年中&#xff0c;自然语言处理&#xff08;NLP&#xff09;经历了深刻的技术变革。从早期的统计方法到深度学习的应用&#xff0c;再到如今Transformer架构的普及&#xff0c;NLP 的发展不仅提高了模型的性能&#xff0c;还扩展了其在不同领域中的应用边界。 1. 词嵌…...

嵌入式中QT实现文本与线程控制方法

第一:利用QT进行文件读写实现 利用QT进行读写文本的时候进行读写,读取MP3歌词的文本,对这个文件进行读写操作。 实例代码,利用Qfile,对文件进行读写。 //读取对应文件文件,头文件的实现。 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #incl…...

云备份项目--服务端编写

文章目录 7. 数据管理模块7.1 如何设计7.2 完整的类 8. 热点管理8.1 如何设计8.2 完整的类 9. 业务处理模块9.1 如何设计9.2 完整的类9.3 测试9.3.1 测试展示功能 完整的代码–gitee链接 7. 数据管理模块 TODO: 读写锁&#xff1f;普通锁&#xff1f; 7.1 如何设计 需要管理…...

Node.js——fs(文件系统)模块

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…...

SAP BC 同服务器不同client之间的传输SCC1

源配置client不需要释放 登录目标client SCC1...

CentOS: RPM安装、YUM安装、编译安装(详细解释+实例分析!!!)

目录 1.什么是RPM 1.1 RPM软件包命名格式 1.2RPM功能 1.3查询已安装的软件&#xff1a;rpm -q 查询已安装软件的信息 1.4 挂载&#xff1a;使用硬件&#xff08;光驱 硬盘 u盘等&#xff09;的方法&#xff08;重点&#xff01;&#xff01;&#xff01;&#xff09; 1…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...