【基本知识】UART接口
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接口的更多相关文章
- UART接口基本知识
Universal asynchronous transciever即同一异步收发器,也就是我们平时所说的串口,是一种最简单,最基本的通信接口. 通信接口按照不同的标准有不同的分类,常见的有同步或异步 ...
- 【原创】FPGA开发手记(一) UART接口
以下内容均以Xilinx的Nexys3作为开发板 1. UART简介 UART(即Universal Asynchronous Receiver Transmitter 通用异步收发器)是广泛使用的串 ...
- UART接口
1.UART UART(Universal Asynchronous Receiver and Transmitter)通用异步收发器(异步串行通信口),是一种通用的数据通信协议,它包括了RS232. ...
- UART接口与COM口的区别
原文地址:https://blog.csdn.net/wordwarwordwar/article/details/78883732 简单的讲:(UART与COM) 嵌入式里面说的串口,一般是指UAR ...
- UART接口介绍
1. 简介 UART, Universal Asynchronous Receiver-Transmitter, 通用异步收发传输器 UART协议规定了通信双方所遵守的规定,属于数据链路层RS232接 ...
- uart接口介绍和认识
接口/总线/驱动 UART (Universal Asynchronous Receiver/Transmitter) 通用异步收发器. UART是用于控制计算机与串行设备的芯片.有一点要注意的是,它 ...
- Cypress的开发板的UART接口打印调试信息
说实话,在官方论坛现在还没有找到相关有用的消息,因为我们这个开发板的UART没引出来. http://www.cypress.com/?app=forum&id=167&rID=527 ...
- MVVM设计模式基础知识--ICommand接口
命令是 Windows Presentation Foundation (WPF) 中的输入机制,它提供的输入处理比设备输入具有更高的语义级别. 命令有若干用途: 第一个用途是将语义以及调用命令的对象 ...
- UART Explained(转载)
做嵌入式开发,UART几乎是必不可少的,调试串口.GPS.GPRS.Bluetooth等模块很多都是用的UART接口.时下火热的IoT也不乏UART的身影,串口的BLE.WIFI.Zigbee.Lor ...
随机推荐
- bzoj4066: 简单题 K-Dtree
bzoj4066: 简单题 链接 bzoj 思路 强制在线.k-dtree. 卡常啊.空间开1e6就T了. 代码 #include <bits/stdc++.h> #define my_m ...
- bootstrap弹框去除遮罩层效果
是通过css解决这个问题,核心css代码如下: .modal-backdrop { filter: alpha(opacity=)!important; opacity: !important; } ...
- Jedis与Jedis连接池
1.Jedis简介 实际开发中,我们需要用Redis的连接工具连接Redis然后操作Redis, 对于主流语言,Redis都提供了对应的客户端: https://redis.io/clients 2. ...
- Honk's pool[STL multiset]
目录 题目地址 题干 代码和解释 题目地址 Honk's pool(The Preliminary Contest for ICPC Asia Shenyang 2019 ) 题干 代码和解释 本题使 ...
- HTTP协议之multipart/form-data
HTTP协议之multipart/form-data REST API可以用multipart/form-data,来上传文件. 在最初的 http 协议中,没有上传文件方面的功能. rfc1867为 ...
- g-api notes
目录 Q: What is GOrigin? What the meaning of parameters GMat(const GNode &n, std::size_t out) Q: h ...
- 微信支付:URL未注册问题
起因:一个项目已经做好了,微信支付也调通的,域名 www.xxxx.com ,某天客户需要换域名,改为weixin.xxxx.com, 原先的www转向客户自己的官网,结果换了之后,发现微信支付出错: ...
- StarGAN: Unified Generative Adversarial Networks for Multi-Domain Image-to-Image Translation - 1 - 多个域间的图像翻译论文学习
Abstract 最近在两个领域上的图像翻译研究取得了显著的成果.但是在处理多于两个领域的问题上,现存的方法在尺度和鲁棒性上还是有所欠缺,因为需要为每个图像域对单独训练不同的模型.为了解决该问题,我们 ...
- linux安装redis时报collect2: fatal error: cannot find 'ld'和In file included from adlist.c:34:0:
如题,看了下该ld命令所在文件: [root@centos redis-]# whereis ld ld: /usr/bin/ld.gold /usr/bin/ld /usr/bin/ld.bfd / ...
- 树莓派小用手册(安装系统,配置图形界面,连接WiFi,调用摄像头,安装ffmpeg)
安装树莓派系统(重装) 准备工作: 安装需要干净的TF卡(最好 8G 以上),如果是重装的话,需要先将其清理后再使用.清理步骤下面会给出,清理需要工具 DiskGenius,下载链接:http://w ...