【基本知识】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 ...
随机推荐
- 洛谷 P5408 【模板】第一类斯特林数·行
传送门 首先,有 \[ x^{\overline n}=\sum_k\begin{bmatrix}{n\\ k}\end{bmatrix}x^{k}\\ \] 那么我们只需要求出\(x^{\overl ...
- 用Python实现一个简单的——人脸相似度对比
近几年来,兴起了一股人工智能热潮,让人们见到了AI的能力和强大,比如图像识别,语音识别,机器翻译,无人驾驶等等.总体来说,AI的门槛还是比较高,不仅要学会使用框架实现,更重要的是,需要有一定的数学基础 ...
- C#中得到每周,每月,每季,每年的年初末日期
DateTime表示时间上的一刻,通常以日期和当天的时间表示.借用这个结构,我们可以实现较丰富的功能,本文给出得到每周每天的方法,及得到本月第一天,本月最后一天,本季第一天,本季最后一天,本年第一天及 ...
- golang调用c动态库
golang调用c动态库 简介 golang调用c语言动态库,动态方式调用,可指定动态库路径,无需系统目录下 核心技术点 封装c动态库 go语言调用c代码 实例代码 封装c动态库 头文件 test_s ...
- [原]globalmapper设置高程配色(globalmapper自定义配色方案)
1.使用的globalmapper版本:1.8以上(之前的版本也应该支持) 2.将全球DEM加载进去 (零时找的小DEM 全球7级) 3.右击此处,选择“高程图例选项” 4.选择 配置-着色器选项 ...
- Nodejs 包与 npm第三方模块安装和 package.json 以及 cnpm
包与 NPM 1. 包 Nodejs 中除了它自己提供的核心模块外,可以自定义模块,也可以使用第三方的模块.Nodejs 中第三方模块由包组成,可以通过包来对一组具有相互依 赖关系的模块进行统一管理. ...
- 【转】Sql Server查看所有数据库名,表名,字段名(SQL语句)
-- 获取所有数据库名 select * from master..SysDatabases; -- 获取hotline数据库中所有表名 select name from hotline..SysOb ...
- mysql5.7的主从切换
mysql5.7的主从切换 主库: master 10.11.0.211 从库: slave 10.11.0.210 目标:主从切换,将slave切换为master,master切换为slave 一. ...
- Ubuntu 上编译opencv_contrib模块for Android
https://blog.csdn.net/ipfpm/article/details/81132144 [ubuntu]Ubuntu中Android SDK下载跟配置 android24的版本 (1 ...
- linux zip命令 tar命令 【压缩、解压缩】参数列表:
linux zip命令参数列表: -a 将文件转成ASCII模式 -F 尝试修复损坏的压缩文件 -h 显示帮助界面 -m 将文件压缩之后,删除源文件 -n 特定字符串 不压缩具有特定字尾字符串 ...