通讯协议学习之路:UART协议理论

news2024/11/17 21:41:08

通讯协议之路主要分为两部分,第一部分从理论上面讲解各类协议的通讯原理以及通讯格式,第二部分从具体运用上讲解各类通讯协议的具体应用方法。

后续文章会同时发表在个人博客(jason1016.club)、CSDN;视频会发布在bilibili(UID:399951374)

序、个人简述

  1. UART通讯为异步全双工通讯
  2. UART可以转化为RS232、RS485、RS422等协议
  3. UART数据包:
  • 空闲位:1
  • 起始位:0
  • 数据位:7位,高电平代表’1’,低电平代表’0’(如果没有奇偶位为8位)
  • 奇偶校验位:1位
  • 停止位:1

START(1)+数据位(7)+奇偶校验位(1)+结束位(1位)

一、uart串口通信简介

通用异步收发器 UART(Universal Asynchronous Receiver/Transmitter),是一种串行、异步、全双工的通信协议,将所需传输的数据一位接一位地传输,在UART通讯协议中信号线上的状态位高电平代表’1’,低电平代表’0’。其特点是通信线路简单,只要一对传输线就可以实现双向通信,大大降低了成本,但传送速度较慢。

二、串口传输

1、数据协议

在串口通信中,尤其需要关注的是数据流以及波特率。一个数据流由10个数据位组成,包含1位起始位,7位有效数据位,1位奇偶校验位,1位停止位。uart串口信号线上空闲时常驻高电平,当检测到低电平下降沿时认为数据传输开始,到停止位时数据传输结束,一共10位数据位组成一个数据包。

  • 起始位:通信线路上空闲时为“1”,当检测到“0”即下降沿时,认为数据传输开始
  • 有效数据位:传输开始后传递的需要接收和发送的数据值,可以表示指令或数据
  • 奇偶校验位:奇偶校验,通过来校验传输数据中“1”的个数为奇数个(奇校验)或偶数个(偶校验)来指示传输数据是否正确
  • 停止位:数据传输结束,传输线恢复常“1”状态

此外,还需关注数据传输波特率,波特率表示一秒内传输了多少个码元数量,一般波特率为300,1200,2400,9600,19200,38400,115200等。例如9600 Baud表示一秒内传输了9600个码元信息,当一个码元只含1 bit信息时,波特率=比特率

2、整体架构

串口协议用于与其他模块之间的信息交互,包含接收模块和发送模块,信号传输线上根据波特率完成码元的接收与发送,因而接收模块主要完成并串转换,串并转换是接收和发送模块必备的基本功能,发送模块完成并串转换,接收模块完成串并转换。

波特率与时钟频率关系如下(码元为单bit时):

三、串口传输实现

1、发送模块

代码如下

//===============
//author:LGYSSS
//proj:uart_transimitter
//===============
module uart_tx(
    clk    ,
    rst_n  ,
    data_vld , //有效信号
    data_in,   //输入信号
    data_out,  //并行转串行输出信号
    rdy        //模块有效信号,示意模块准备接收数据
    );


parameter WIDTH    =8;
parameter CLK_CNT= 5208;     //波特率baud=9600下单码元传输 码元宽度为104166  50MHz下一个时钟周期为20ns,传输一个数据位104166/20=5208个clk
parameter  NUM_CNT=10;     //数据位个数


input clk;
input rst_n;
input [WIDTH-1:0]data_in;
input data_vld;
output data_out;
output rdy;
 
reg data_out; 
reg [WIDTH-1:0]data_in_reg;
reg start_tx;
wire [WIDTH-1+2:0] data;

reg   [12:0]     cnt0;
wire             add_cnt0;
wire             end_cnt0;
reg   [3:0]      cnt1;
wire             add_cnt1;
wire             end_cnt1;
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        start_tx<=0;
    else if(start_tx==0&&data_vld==1)
        start_tx<=1;
    else if(end_cnt1)
        start_tx<=0;
end



always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            cnt0 <= 0;
        end
        else if(add_cnt0)begin
            if(end_cnt0)
                cnt0 <= 0;
            else
                cnt0 <= cnt0 + 1;
        end
end

assign add_cnt0 = start_tx;
assign end_cnt0 = add_cnt0 && cnt0== CLK_CNT-1;

always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt1 <= 0;
    end
    else if(add_cnt1)begin
        if(end_cnt1)
            cnt1 <= 0;
        else
            cnt1 <= cnt1 + 1;
    end
end

assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== NUM_CNT-1;

always  @(posedge clk or negedge rst_n)begin  //在数据有vld效时进行数据锁存,进行下一步串并转换
    if(!rst_n)begin
        data_in_reg<=0;
    end
    else if(start_tx==0&&data_vld==1)begin
        data_in_reg<=data_in;
    end
end

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        data_out <= 1'b1;
    end
    else if(add_cnt0 && cnt0==1-1)begin
        data_out <= data[cnt1];
    end
end

assign data={1'b1,data_in_reg,1'b0}; //起始位,停止位拼接

assign rdy=((data_vld==1)||(start_tx==1))?1'b0:1'b1;

endmodule

2、接收模块

代码如下:

//===============
//author:LGYSSS
//proj:uart_receiver
//===============
module uart_rx(
    clk    ,
    rst_n  ,
    data_vld ,
    rx_data_in,
    rx_data_out
    );

parameter WIDTH    =8;
parameter CLK_CNT= 5208;     //波特率baud=9600下单码元传输 码元宽度为104166  50MHz下一个时钟周期为20ns,传输一个数据位104166/20=5208个clk
parameter CLK_CNT_MID=2604;
parameter  NUM_CNT=10;

input clk;
input rst_n;
input rx_data_in;

output reg [WIDTH-1:0] rx_data_out;
output reg data_vld;
wire               start_rx;

reg [19:0]         cnt0;
wire               add_cnt0;
wire               end_cnt0;

reg [3:0]          cnt1;
wire               add_cnt1;
wire               end_cnt1;
reg               flag;
reg rx_data_in_reg0;
reg rx_data_in_reg1;
reg rx_data_in_reg2;


always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        rx_data_in_reg0<=0;
        rx_data_in_reg1<=0;
        rx_data_in_reg2<=0;
    end
    else begin
        rx_data_in_reg0<=rx_data_in;
        rx_data_in_reg1<=rx_data_in_reg0;
        rx_data_in_reg2<=rx_data_in_reg1;
    end
end

assign start_rx=(rx_data_in_reg2&&~rx_data_in_reg1)==1; //下降沿检测


always  @(posedge clk or negedge rst_n)begin
        if(rst_n==1'b0)begin
            flag <= 1'b0;
        end
        else if(start_rx)begin
            flag <= 1'b1;
        end
        else if(end_cnt1)begin
            flag <= 1'b0;
        end
end
 
always @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt0 <= 0;
        end
        else if(add_cnt0)begin
            if(end_cnt0)
                cnt0 <= 0;
            else
                cnt0 <= cnt0 + 1;
        end
end

assign add_cnt0 = flag;
assign end_cnt0 = add_cnt0 && cnt0== CLK_CNT-1;

always @(posedge clk or negedge rst_n)begin 
        if(!rst_n)begin
            cnt1 <= 0;
        end
        else if(add_cnt1)begin
            if(end_cnt1)
                cnt1 <= 0;
            else
                cnt1 <= cnt1 + 1;
        end
end

assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== NUM_CNT-1-1;
 
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        rx_data_out<=0;
    end
    else if(cnt0==CLK_CNT_MID-1&&cnt1!=0&&flag==1)begin
        rx_data_out[cnt1-1]<=rx_data_in_reg2;
    end
end
 
always  @(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            data_vld <= 1'b0;
        end
        else if(end_cnt1)begin
            data_vld <= 1'b1;
        end
        else begin
            data_vld <= 1'b0;
        end    
end
 
endmodule
 

四、串口收发仿真

串口发送模块仿真波形:

串口接收模块仿真波形:

总结

看到这里模块功能其实很清晰了,两个模块完成的功能其实就是收发数据的串并转换,传输的内容具体是什么我们是不用关心的,只需要关心数据收发格式,检测到下降沿时开始传输,传输一定数据位时结束当前传输,就完成了一个数据帧的传输,即完成了uart串口通信的一次收/发。.

同时,在本模块设计中笔者是采用锁存器来锁存当vld有效时的信号,当数据流传输速度较大时,我们也可以采取fifo来缓存我们接收的数据,以免造成数据丢失

参考文章:【精选】通信协议详解(一):UART串口(协议+数据格式+设计实现)_串口数据格式-CSDN博客

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

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

相关文章

国产单片机PY32F002B,32位ARM架构Cortex -M0+内核,性价比高

PY32F002B是普冉推出的新一代入门级32位MCU&#xff0c;内核使用 ARM Cortex M0&#xff0c;主频最高支持到24M&#xff0c;24K FLASH 3K SRAM存储&#xff0c;并支持1.7V~5.5V宽工作电压&#xff0c;-40 ~ 85 C工作温度。拥有1 x 12 位ADC、I2C、SPI、USART、TIM、LPTIM、IWDT…

三相交错LLC软启动控制驱动波形分析--死区时间与占空比关系

三相交错LLC软启动控制驱动波形分析 文章目录 三相交错LLC软启动控制驱动波形分析一、电路原理二、时序分析三、环路分析四、控制策略1.软启动驱动波形趋势2.软启动驱动波形占空图3.软启动驱动波形详细图4.软启动代码分析5.Debug调试界面5.死区时间与实际输出5.1 死区时间50--对…

UnrealEngine5 - Niagara粒子系统问题 当发射器不在视口内时,发射物不可见

最近在弄一点点Niagara粒子系统&#xff0c;发现一个小问题&#xff0c;就是当发射器不在视口内时&#xff08;被物体阻挡也是一样的&#xff09;发射的粒子不可见 解决办法跳转 如下 若往前移动到发射器不在视口内&#xff0c;则发射物不可见 或将其阻挡&#xff08;阻挡物没…

情绪化软文怎么写?媒介盒子分享五大步骤

在网络营销中&#xff0c;情绪化软文通常已经成为品牌营销的重要手段之一&#xff0c;它旨在通过在文案内容中融入情感和故事性的元素&#xff0c;为品牌塑造鲜明的形象&#xff0c;和用户建立情感联系&#xff0c;并促使他们购买产品&#xff0c;提升对品牌的忠诚度&#xff0…

游戏数据分析工具该怎样选择?有哪些选择标准?

选择游戏数据分析工具时&#xff0c;可以考虑以下标准&#xff1a; 1、功能全面性 确保工具提供全面的功能&#xff0c;包括玩家行为分析、性能监测、用户留存率、收入分析等&#xff0c;以满足不同层面的需求。 2、易用性 选择界面友好、易于使用的工具&#xff0c;以确保团…

ros2 UR10仿真包运行

前言 一个月前安装了一下这个包&#xff0c;但是有报错。现在换了一个强劲的电脑&#xff0c;内存64G &#xff0c;显存39G &#xff0c;终于跑起来了&#xff0c;没有报错。网页控制器可以控制RVIZ中的机器人旋转。 vituralBOX中3D加速要勾选&#xff0c;这样才能发挥独立显…

青龙面板安装及配置

一、青龙面板安装 二、初始化配置 首次登录需要进行初始化配置 1、开始安装 2、账号设置 3、通知设置 通知方式 - 钉钉机器人 获取钉钉机器人的token和secret参考如下文章&#xff1a; 获取钉钉机器人的token及secret-CSDN博客 4、完成 5、登录 三、应用 待续

基于SSM的在线教育网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

2023年四川省网络与信息安全技能大赛初赛 团队赛 Writeup

文章目录 Web简单的登录web-game-1-2ezphp2easyLDweb-include-1-1 Pwnjustread ReverseEzGoMediumRev Cryptoeasyhashcrypto-rsa-1-1crypto-classical-1-1 MiscNo.11 is gone2misc-zip-1-1misc-pic-1-1 Web 简单的登录 给了信息 账号为学号密码为电话&#xff0c;写脚本爆破 …

Sectigo DV 通配符证书500元

Sectigo原名Comodo&#xff0c;是知名的CA认证机构。Sectigo旗下的SSL证书品牌产品特点是性价比高、签发速度快&#xff0c;在互联网安全领域&#xff0c;SSL证书的重要性日益凸显。随着数据泄露和网络攻击事件的增加&#xff0c;确保数据传输的安全性已成为当务之急。在这方面…

{大厂漏洞 } OA产品存在SQL注入

0x01 漏洞介绍 江苏叁拾叁-OA是由江苏叁拾叁信息技术有限公司开发的一款OA办公平台&#xff0c;主要有知识管理&#xff0c;工作流程&#xff0c;沟通交流&#xff0c;辅助办公&#xff0c;集成解决方案&#xff0c;应用支撑平台&#xff0c;基础支撑等功能。 该系统也与江苏叁…

stable-diffusion-webui sdxl模型代码分析

采样器这块基本都是用的k-diffusion&#xff0c;模型用的是stability的原生项目generative-models中的sgm&#xff0c;这点和fooocus不同&#xff0c;fooocus底层依赖comfyui中的models&#xff0c;comfy是用load_state_dict的方式解析的&#xff0c;用的load_checkpoint_guess…

RK3568驱动指南|第六篇-平台总线-第55章 初识设备树

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

封装一个滑块控制灯光组件

效果如下gif 只进行了基础的事件和布局&#xff0c;可优化的地方&#xff1a;luminance-box这个div加上后&#xff0c;由于和slider-run-way都是absolute定位&#xff0c;导致slider-run-way的点击事件无法设置值&#xff0c;只能通过滑块设置。暂时想不到咋处理&#xff0c;有…

淘宝代购系统需要电商API接口

在推广一篇淘宝代购系统时&#xff0c;了解电商API接口的重要性是很有必要的。电商API接口可以提供更高效、准确的数据传输和信息交流&#xff0c;从而实现更智能化的购物体验。下面我们将简单介绍电商API接口在推广淘宝代购系统中的应用。 一、数据交互与集成 电商API接口可…

视频SDK,高效视频解决方案

随着企业业务的不断扩展和多样化&#xff0c;视频已成为企业宣传、教育和娱乐等多个领域不可或缺的内容。为了满足企业对视频的需求&#xff0c;美摄视频SDK开发应运而生&#xff0c;为企业提供全面、高效、安全和便捷的视频解决方案。 美摄视频SDK开发公司拥有丰富的经验和卓…

C++14 新特性

C14 新特性 C14 新特性变量模板通用lambda表达式常量表达式二进制字面量数组大小自动推导make_uniqueexchangeinteger_sequenceconstexpr函数的扩展变长参数模板的扩展 C14 新特性 C14 is a minor but important upgrade over C11, and largely “completes C11.” 变量模板 …

找免费音效素材,就上这6个网站,无版权可商用

很多视频剪辑或从事自媒体工作的朋友都不知道去哪里找免费的音效素材&#xff0c;很多网站需要付费或会员才能下载&#xff0c;还不能商业用途。如何找到即免费还能商用的音效素材&#xff1f; 本期就把我收藏多年的6个免费可商用的音效素材网站分享给大家&#xff0c;以后就不…

快速了解服务器单CPU与双CPU

​  在当今快节奏的技术环境中&#xff0c;用户们对功能强大且高效的服务器配置需求不断增长。CPU作为构成任何计算基础设施的骨干&#xff0c;服务器的“大脑”&#xff0c;负责执行计算、控制数据流并协调各个组件之间的任务&#xff0c;是服务器选择硬件中的重要一环。因此…

CSS 之 display属性详解

一、总览 ​ CSS的 display 属性用于设置元素的显示类型&#xff0c;或设置其子元素的布局类型。 display属性值的适用性取决于元素的类型和上下文。某些属性值只适用于特定类型的元素&#xff0c;使用时需注意兼容性和语义化。 ​ 其属性值共计有18种&#xff0c;按照类别可…