1.简介

  (1)UART一种通用异步串口数据总线,最低采用两路信号(TX/RX)即可实现全双工通信,十分简单;

  (2)UART采用LSB模式传输,串口数据传输格式如下图所示:

    

    起始位:长度为1位的时间,用于表示发送字符的开始;

    数据位:长度长度不固定,一般是8位;

    校验位:可以加也可以不加。

    停止位:一般是1位、1.5位、2位长度,用于告知接收端字符传输结束;

  (3)每个字符的发送都需要有起始位和停止位,对于连续数据也是如此;

2.内部结构

    

3.实现

  发送模块代码如下:

 module uart_tx_path #
(
parameter BAUD_DIV = 'd9, //baud
parameter BAUD_DIV_CAP = 'd4 //baud capture point
)
(
input clk, //main clk
input rst_n, //reset
input uart_tx_en, //send one byte data enable
input[:] uart_tx_byte, //one byte data
output uart_txd, //the txd pin
output uart_tx_done //send one byte data done
); //------------------------- Baud rate generator -------------------------
reg[:] cnt_baud_div;
reg baud_cap;
reg baud_start; always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
cnt_baud_div <= 'd0;
end
else begin
if(baud_start) begin
if(cnt_baud_div >= BAUD_DIV) begin
cnt_baud_div <= 'd0;
end
else begin
cnt_baud_div <= cnt_baud_div + 'b1;
end
end
else begin
cnt_baud_div <= 'd0;
end
end
end always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
baud_cap <= 'b0;
end
else begin
if(cnt_baud_div==BAUD_DIV_CAP) begin
baud_cap <= 'b1;
end
else begin
baud_cap <= 'b0;
end
end
end //-------------------------capture the uart_tx_en posedge-------------------------
reg uart_tx_en_r0,uart_tx_en_r1;
wire uart_tx_en_p; always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
uart_tx_en_r0 <= 'b0; //uart_tx_en of the idle state is low
uart_tx_en_r1 <= 'b0;
end
else begin
uart_tx_en_r0 <= uart_tx_en;
uart_tx_en_r1 <= uart_tx_en_r0;
end
end assign uart_tx_en_p = (~uart_tx_en_r1 & uart_tx_en_r0)? 'b1:1'b0; //capture the uart_tx_en posedge //------------------------- capture the txd data -------------------------
localparam TX_IDLE = 'b0;
localparam TX_WORK = 'b1; reg state_tx;
reg uart_tx_done_r;
reg[:] send_data;
reg[:] tx_bit; always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
state_tx <= TX_IDLE;
send_data <= 'b1111_1111_11;
uart_tx_done_r <= 'b0;
end
else begin
case(state_tx)
TX_IDLE: if(uart_tx_en_p) begin
baud_start <= 'b1;
send_data <= {'b1,uart_tx_byte,1'b0};
state_tx <= TX_WORK;
uart_tx_done_r <= 'b0;
end
else begin
baud_start <= 'b0;
send_data <= 'b1111_1111_11;
state_tx <= TX_IDLE;
uart_tx_done_r <= 'b0;
end
TX_WORK: if(tx_bit == 'd10) begin
baud_start <= 'b1;
send_data <= 'b1111_1111_11;
state_tx <= TX_WORK;
uart_tx_done_r <= 'b0;
end
else if(tx_bit>='d11) begin
baud_start <= 'b0;
send_data <= 'b1111_1111_11;
state_tx <= TX_IDLE;
uart_tx_done_r <= 'b1;
end
else begin
baud_start <= 'b1;
send_data <= send_data;
state_tx <= TX_WORK;
uart_tx_done_r <= 'b0;
end
default: ;
endcase
end
end
//------------------------- the uart txd work -------------------------
reg uart_txd_r; always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
uart_txd_r <= 'b1; //uart_txd of the idle state is high
tx_bit <= 'd0;
end
else begin
if(state_tx == TX_WORK) begin
if(baud_cap) begin
if (tx_bit <= 'd9)
uart_txd_r <= send_data[tx_bit];
else
uart_txd_r <= 'b1;
tx_bit <= tx_bit + 'b1;
end
else begin
uart_txd_r <= uart_txd_r;
tx_bit <= tx_bit;
end
end
else begin
uart_txd_r <= 'b1;
tx_bit <= 'd0;
end
end
end assign uart_tx_done = uart_tx_done_r;
assign uart_txd = uart_txd_r; endmodule

UART_TX_PATH

  接收模块代码如下:

 module uart_rx_path #
(
parameter BAUD_DIV = 'd9, //baud
parameter BAUD_DIV_CAP = 'd4 //baud capture point
)
(
input clk, //main clk
input rst_n, //reset
input uart_rxd, //the rxd pin
output uart_rx_done, //receive one byte data done
output[:] uart_rx_byte //one byte data
); //------------------------- Baud rate generator -------------------------
reg[:] cnt_baud_div;
reg baud_cap;
reg baud_start; always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
cnt_baud_div <= 'd0;
end
else begin
if(baud_start) begin
if(cnt_baud_div >= BAUD_DIV) begin
cnt_baud_div <= 'd0;
end
else begin
cnt_baud_div <= cnt_baud_div + 'b1;
end
end
else begin
cnt_baud_div <= 'd0;
end
end
end always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
baud_cap <= 'b0;
end
else begin
if(cnt_baud_div==BAUD_DIV_CAP) begin
baud_cap <= 'b1;
end
else begin
baud_cap <= 'b0;
end
end
end //------------------------- capture the uart start bit -------------------------
reg uart_rxd_r0,uart_rxd_r1,uart_rxd_r2,uart_rxd_r3;
wire uart_rxd_n; always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
uart_rxd_r0 <= 'b1; //uart_rxd of the idle state is high
uart_rxd_r1 <= 'b1;
uart_rxd_r2 <= 'b1;
uart_rxd_r3 <= 'b1;
end
else begin
uart_rxd_r0 <= uart_rxd;
uart_rxd_r1 <= uart_rxd_r0;
uart_rxd_r2 <= uart_rxd_r1;
uart_rxd_r3 <= uart_rxd_r2;
end
end assign uart_rxd_n = (uart_rxd_r3 & uart_rxd_r2 & ~uart_rxd_r1 & ~uart_rxd_r0)? 'b1 : 1'b0; //capture the uart_rxd negedge //------------------------- the uart rxd work -------------------------
localparam[:] UART_IDLE = 'd0; //IDLE
localparam[:] UART_START= 'd1; //START BIT
localparam[:] UART_BIT0 = 'd2; //BIT0
localparam[:] UART_BIT1 = 'd3; //BIT1
localparam[:] UART_BIT2 = 'd4; //BIT2
localparam[:] UART_BIT3 = 'd5; //BIT3
localparam[:] UART_BIT4 = 'd6; //BIT4
localparam[:] UART_BIT5 = 'd7; //BIT5
localparam[:] UART_BIT6 = 'd8; //BIT6
localparam[:] UART_BIT7 = 'd9; //BIT7
localparam[:] UART_STOP = 'd10; //STOP BIT reg[:] state_rx;
reg uart_rx_done_r;
reg[:] uart_rx_byte_r0;
reg[:] uart_rx_byte_r1; always@(posedge clk or negedge rst_n)
begin
if(!rst_n) begin
state_rx <= UART_IDLE;
uart_rx_done_r <= 'b0;
uart_rx_byte_r0 <= 'd0;
uart_rx_byte_r1 <= 'd0;
baud_start <= 'b0;
end
else begin
case(state_rx)
UART_IDLE: if(uart_rxd_n) begin
uart_rx_done_r <= 'b0;
baud_start <= 'b1;
state_rx <= UART_START;
end
else begin
uart_rx_done_r <= 'b0;
baud_start <= 'b0;
state_rx <= UART_IDLE;
end
UART_START: if(baud_cap) begin
state_rx <= UART_BIT0;
end
else begin
state_rx <= UART_START;
end
UART_BIT0: if(baud_cap) begin
uart_rx_byte_r0[] <= uart_rxd;
state_rx <= UART_BIT1;
end
else begin
uart_rx_byte_r0 <= uart_rx_byte_r0;
state_rx <= UART_BIT0;
end
UART_BIT1: if(baud_cap) begin
uart_rx_byte_r0[] <= uart_rxd;
state_rx <= UART_BIT2;
end
else begin
uart_rx_byte_r0 <= uart_rx_byte_r0;
state_rx <= UART_BIT1;
end
UART_BIT2: if(baud_cap) begin
uart_rx_byte_r0[] <= uart_rxd;
state_rx <= UART_BIT3;
end
else begin
uart_rx_byte_r0 <= uart_rx_byte_r0;
state_rx <= UART_BIT2;
end
UART_BIT3: if(baud_cap) begin
uart_rx_byte_r0[] <= uart_rxd;
state_rx <= UART_BIT4;
end
else begin
uart_rx_byte_r0 <= uart_rx_byte_r0;
state_rx <= UART_BIT3;
end
UART_BIT4: if(baud_cap) begin
uart_rx_byte_r0[] <= uart_rxd;
state_rx <= UART_BIT5;
end
else begin
uart_rx_byte_r0 <= uart_rx_byte_r0;
state_rx <= UART_BIT4;
end
UART_BIT5: if(baud_cap) begin
uart_rx_byte_r0[] <= uart_rxd;
state_rx <= UART_BIT6;
end
else begin
uart_rx_byte_r0 <= uart_rx_byte_r0;
state_rx <= UART_BIT5;
end
UART_BIT6: if(baud_cap) begin
uart_rx_byte_r0[] <= uart_rxd;
state_rx <= UART_BIT7;
end
else begin
uart_rx_byte_r0 <= uart_rx_byte_r0;
state_rx <= UART_BIT6;
end
UART_BIT7: if(baud_cap) begin
uart_rx_byte_r0[] <= uart_rxd;
state_rx <= UART_STOP;
end
else begin
uart_rx_byte_r0 <= uart_rx_byte_r0;
state_rx <= UART_BIT7;
end
UART_STOP: if(baud_cap) begin
uart_rx_done_r <= 'b1;
uart_rx_byte_r1 <= uart_rx_byte_r0;
baud_start <= 'b0;
state_rx <= UART_IDLE;
end
else begin
uart_rx_done_r <= 'b0;
uart_rx_byte_r1 <= uart_rx_byte_r1;
baud_start <= 'b1;
state_rx <= UART_STOP;
end
default: state_rx <= UART_IDLE;
endcase
end
end assign uart_rx_done = uart_rx_done_r;
assign uart_rx_byte = uart_rx_byte_r1;
endmodule

UART_RX_PATH

4.参考资料

  《通信IC设计》 李庆华著

【基本知识】UART接口的更多相关文章

  1. UART接口基本知识

    Universal asynchronous transciever即同一异步收发器,也就是我们平时所说的串口,是一种最简单,最基本的通信接口. 通信接口按照不同的标准有不同的分类,常见的有同步或异步 ...

  2. 【原创】FPGA开发手记(一) UART接口

    以下内容均以Xilinx的Nexys3作为开发板 1. UART简介 UART(即Universal Asynchronous Receiver Transmitter 通用异步收发器)是广泛使用的串 ...

  3. UART接口

    1.UART UART(Universal Asynchronous Receiver and Transmitter)通用异步收发器(异步串行通信口),是一种通用的数据通信协议,它包括了RS232. ...

  4. UART接口与COM口的区别

    原文地址:https://blog.csdn.net/wordwarwordwar/article/details/78883732 简单的讲:(UART与COM) 嵌入式里面说的串口,一般是指UAR ...

  5. UART接口介绍

    1. 简介 UART, Universal Asynchronous Receiver-Transmitter, 通用异步收发传输器 UART协议规定了通信双方所遵守的规定,属于数据链路层RS232接 ...

  6. uart接口介绍和认识

    接口/总线/驱动 UART (Universal Asynchronous Receiver/Transmitter) 通用异步收发器. UART是用于控制计算机与串行设备的芯片.有一点要注意的是,它 ...

  7. Cypress的开发板的UART接口打印调试信息

    说实话,在官方论坛现在还没有找到相关有用的消息,因为我们这个开发板的UART没引出来. http://www.cypress.com/?app=forum&id=167&rID=527 ...

  8. MVVM设计模式基础知识--ICommand接口

    命令是 Windows Presentation Foundation (WPF) 中的输入机制,它提供的输入处理比设备输入具有更高的语义级别. 命令有若干用途: 第一个用途是将语义以及调用命令的对象 ...

  9. UART Explained(转载)

    做嵌入式开发,UART几乎是必不可少的,调试串口.GPS.GPRS.Bluetooth等模块很多都是用的UART接口.时下火热的IoT也不乏UART的身影,串口的BLE.WIFI.Zigbee.Lor ...

随机推荐

  1. 反素数 Antiprime(信息学奥赛一本通 1625)(洛谷 1463)

    题目描述 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4. 如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1,2,4,6 ...

  2. Mean Average Precision(mAP),Precision,Recall,Accuracy,F1_score,PR曲线、ROC曲线,AUC值,决定系数R^2 的含义与计算

    背景   之前在研究Object Detection的时候,只是知道Precision这个指标,但是mAP(mean Average Precision)具体是如何计算的,暂时还不知道.最近做OD的任 ...

  3. 关于lct维护动态生成树问题

    水管局长数据加强版 题意是要求维护一棵最小生成树,支持删边操作. 删边操作比较难处理,因为如果删掉树上的边, 很难从已经有备选集合中找出连接不同联通块的最小的边. 然而题目并没有要求在线. 所以离线. ...

  4. 用Eclipse的maven方式创建JFinal项目

  5. Cookie的Secure属性和HttpOnly属性

    基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie ...

  6. mysql插入数据报错IntegrityError: (1062, "Duplicate entry 'xx' for key 'xxxxx'")

    1.问题描述 MySQL插入数据的时候报错,提示如下: IntegrityError: (1062, "Duplicate entry 'xx' for key 'xxxxx'") ...

  7. odoo开发笔记 -- docker容器打包到另一台服务器部署异常

    场景描述: odoo.conf文件指定了数据库配置,如果docker打包的时候,没注意,新环境启动该镜像,会导致并没有连接本地的数据库,如果你配置文件中的数据库地址,当前这台服务器也可以访问到,那么问 ...

  8. SAGAN:Self-Attention Generative Adversarial Networks - 1 - 论文学习

    Abstract 在这篇论文中,我们提出了自注意生成对抗网络(SAGAN),它是用于图像生成任务的允许注意力驱动的.长距离依赖的建模.传统的卷积GANs只根据低分辨率图上的空间局部点生成高分辨率细节. ...

  9. 在centos7上用docker安装宝塔面板

    在centos7上用docker安装宝塔面板   1. [root@web01 ~]# systemctl enable docker 2. [root@web01 ~]# docker pull c ...

  10. WMS培训20190907

    SELECT * FROM WMSADMIN.SPROCEDUREMAP WHERE THEPROCNAME ='NSPBEFOREORDERWRITE' 二,. RF中页面中需要增加申请人,而成品仓 ...