1.简介

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

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

    

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

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

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

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

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

2.内部结构

    

3.实现

  发送模块代码如下:

  1. module uart_tx_path #
  2. (
  3. parameter BAUD_DIV = 'd9, //baud
  4. parameter BAUD_DIV_CAP = 'd4 //baud capture point
  5. )
  6. (
  7. input clk, //main clk
  8. input rst_n, //reset
  9. input uart_tx_en, //send one byte data enable
  10. input[:] uart_tx_byte, //one byte data
  11. output uart_txd, //the txd pin
  12. output uart_tx_done //send one byte data done
  13. );
  14.  
  15. //------------------------- Baud rate generator -------------------------
  16. reg[:] cnt_baud_div;
  17. reg baud_cap;
  18. reg baud_start;
  19.  
  20. always@(posedge clk or negedge rst_n)
  21. begin
  22. if(!rst_n) begin
  23. cnt_baud_div <= 'd0;
  24. end
  25. else begin
  26. if(baud_start) begin
  27. if(cnt_baud_div >= BAUD_DIV) begin
  28. cnt_baud_div <= 'd0;
  29. end
  30. else begin
  31. cnt_baud_div <= cnt_baud_div + 'b1;
  32. end
  33. end
  34. else begin
  35. cnt_baud_div <= 'd0;
  36. end
  37. end
  38. end
  39.  
  40. always@(posedge clk or negedge rst_n)
  41. begin
  42. if(!rst_n) begin
  43. baud_cap <= 'b0;
  44. end
  45. else begin
  46. if(cnt_baud_div==BAUD_DIV_CAP) begin
  47. baud_cap <= 'b1;
  48. end
  49. else begin
  50. baud_cap <= 'b0;
  51. end
  52. end
  53. end
  54.  
  55. //-------------------------capture the uart_tx_en posedge-------------------------
  56. reg uart_tx_en_r0,uart_tx_en_r1;
  57. wire uart_tx_en_p;
  58.  
  59. always@(posedge clk or negedge rst_n)
  60. begin
  61. if(!rst_n) begin
  62. uart_tx_en_r0 <= 'b0; //uart_tx_en of the idle state is low
  63. uart_tx_en_r1 <= 'b0;
  64. end
  65. else begin
  66. uart_tx_en_r0 <= uart_tx_en;
  67. uart_tx_en_r1 <= uart_tx_en_r0;
  68. end
  69. end
  70.  
  71. assign uart_tx_en_p = (~uart_tx_en_r1 & uart_tx_en_r0)? 'b1:1'b0; //capture the uart_tx_en posedge
  72.  
  73. //------------------------- capture the txd data -------------------------
  74. localparam TX_IDLE = 'b0;
  75. localparam TX_WORK = 'b1;
  76.  
  77. reg state_tx;
  78. reg uart_tx_done_r;
  79. reg[:] send_data;
  80. reg[:] tx_bit;
  81.  
  82. always@(posedge clk or negedge rst_n)
  83. begin
  84. if(!rst_n) begin
  85. state_tx <= TX_IDLE;
  86. send_data <= 'b1111_1111_11;
  87. uart_tx_done_r <= 'b0;
  88. end
  89. else begin
  90. case(state_tx)
  91. TX_IDLE: if(uart_tx_en_p) begin
  92. baud_start <= 'b1;
  93. send_data <= {'b1,uart_tx_byte,1'b0};
  94. state_tx <= TX_WORK;
  95. uart_tx_done_r <= 'b0;
  96. end
  97. else begin
  98. baud_start <= 'b0;
  99. send_data <= 'b1111_1111_11;
  100. state_tx <= TX_IDLE;
  101. uart_tx_done_r <= 'b0;
  102. end
  103. TX_WORK: if(tx_bit == 'd10) begin
  104. baud_start <= 'b1;
  105. send_data <= 'b1111_1111_11;
  106. state_tx <= TX_WORK;
  107. uart_tx_done_r <= 'b0;
  108. end
  109. else if(tx_bit>='d11) begin
  110. baud_start <= 'b0;
  111. send_data <= 'b1111_1111_11;
  112. state_tx <= TX_IDLE;
  113. uart_tx_done_r <= 'b1;
  114. end
  115. else begin
  116. baud_start <= 'b1;
  117. send_data <= send_data;
  118. state_tx <= TX_WORK;
  119. uart_tx_done_r <= 'b0;
  120. end
  121. default: ;
  122. endcase
  123. end
  124. end
  125. //------------------------- the uart txd work -------------------------
  126. reg uart_txd_r;
  127.  
  128. always@(posedge clk or negedge rst_n)
  129. begin
  130. if(!rst_n) begin
  131. uart_txd_r <= 'b1; //uart_txd of the idle state is high
  132. tx_bit <= 'd0;
  133. end
  134. else begin
  135. if(state_tx == TX_WORK) begin
  136. if(baud_cap) begin
  137. if (tx_bit <= 'd9)
  138. uart_txd_r <= send_data[tx_bit];
  139. else
  140. uart_txd_r <= 'b1;
  141. tx_bit <= tx_bit + 'b1;
  142. end
  143. else begin
  144. uart_txd_r <= uart_txd_r;
  145. tx_bit <= tx_bit;
  146. end
  147. end
  148. else begin
  149. uart_txd_r <= 'b1;
  150. tx_bit <= 'd0;
  151. end
  152. end
  153. end
  154.  
  155. assign uart_tx_done = uart_tx_done_r;
  156. assign uart_txd = uart_txd_r;
  157.  
  158. endmodule

UART_TX_PATH

  接收模块代码如下:

  1. module uart_rx_path #
  2. (
  3. parameter BAUD_DIV = 'd9, //baud
  4. parameter BAUD_DIV_CAP = 'd4 //baud capture point
  5. )
  6. (
  7. input clk, //main clk
  8. input rst_n, //reset
  9. input uart_rxd, //the rxd pin
  10. output uart_rx_done, //receive one byte data done
  11. output[:] uart_rx_byte //one byte data
  12. );
  13.  
  14. //------------------------- Baud rate generator -------------------------
  15. reg[:] cnt_baud_div;
  16. reg baud_cap;
  17. reg baud_start;
  18.  
  19. always@(posedge clk or negedge rst_n)
  20. begin
  21. if(!rst_n) begin
  22. cnt_baud_div <= 'd0;
  23. end
  24. else begin
  25. if(baud_start) begin
  26. if(cnt_baud_div >= BAUD_DIV) begin
  27. cnt_baud_div <= 'd0;
  28. end
  29. else begin
  30. cnt_baud_div <= cnt_baud_div + 'b1;
  31. end
  32. end
  33. else begin
  34. cnt_baud_div <= 'd0;
  35. end
  36. end
  37. end
  38.  
  39. always@(posedge clk or negedge rst_n)
  40. begin
  41. if(!rst_n) begin
  42. baud_cap <= 'b0;
  43. end
  44. else begin
  45. if(cnt_baud_div==BAUD_DIV_CAP) begin
  46. baud_cap <= 'b1;
  47. end
  48. else begin
  49. baud_cap <= 'b0;
  50. end
  51. end
  52. end
  53.  
  54. //------------------------- capture the uart start bit -------------------------
  55. reg uart_rxd_r0,uart_rxd_r1,uart_rxd_r2,uart_rxd_r3;
  56. wire uart_rxd_n;
  57.  
  58. always@(posedge clk or negedge rst_n)
  59. begin
  60. if(!rst_n) begin
  61. uart_rxd_r0 <= 'b1; //uart_rxd of the idle state is high
  62. uart_rxd_r1 <= 'b1;
  63. uart_rxd_r2 <= 'b1;
  64. uart_rxd_r3 <= 'b1;
  65. end
  66. else begin
  67. uart_rxd_r0 <= uart_rxd;
  68. uart_rxd_r1 <= uart_rxd_r0;
  69. uart_rxd_r2 <= uart_rxd_r1;
  70. uart_rxd_r3 <= uart_rxd_r2;
  71. end
  72. end
  73.  
  74. assign uart_rxd_n = (uart_rxd_r3 & uart_rxd_r2 & ~uart_rxd_r1 & ~uart_rxd_r0)? 'b1 : 1'b0; //capture the uart_rxd negedge
  75.  
  76. //------------------------- the uart rxd work -------------------------
  77. localparam[:] UART_IDLE = 'd0; //IDLE
  78. localparam[:] UART_START= 'd1; //START BIT
  79. localparam[:] UART_BIT0 = 'd2; //BIT0
  80. localparam[:] UART_BIT1 = 'd3; //BIT1
  81. localparam[:] UART_BIT2 = 'd4; //BIT2
  82. localparam[:] UART_BIT3 = 'd5; //BIT3
  83. localparam[:] UART_BIT4 = 'd6; //BIT4
  84. localparam[:] UART_BIT5 = 'd7; //BIT5
  85. localparam[:] UART_BIT6 = 'd8; //BIT6
  86. localparam[:] UART_BIT7 = 'd9; //BIT7
  87. localparam[:] UART_STOP = 'd10; //STOP BIT
  88.  
  89. reg[:] state_rx;
  90. reg uart_rx_done_r;
  91. reg[:] uart_rx_byte_r0;
  92. reg[:] uart_rx_byte_r1;
  93.  
  94. always@(posedge clk or negedge rst_n)
  95. begin
  96. if(!rst_n) begin
  97. state_rx <= UART_IDLE;
  98. uart_rx_done_r <= 'b0;
  99. uart_rx_byte_r0 <= 'd0;
  100. uart_rx_byte_r1 <= 'd0;
  101. baud_start <= 'b0;
  102. end
  103. else begin
  104. case(state_rx)
  105. UART_IDLE: if(uart_rxd_n) begin
  106. uart_rx_done_r <= 'b0;
  107. baud_start <= 'b1;
  108. state_rx <= UART_START;
  109. end
  110. else begin
  111. uart_rx_done_r <= 'b0;
  112. baud_start <= 'b0;
  113. state_rx <= UART_IDLE;
  114. end
  115. UART_START: if(baud_cap) begin
  116. state_rx <= UART_BIT0;
  117. end
  118. else begin
  119. state_rx <= UART_START;
  120. end
  121. UART_BIT0: if(baud_cap) begin
  122. uart_rx_byte_r0[] <= uart_rxd;
  123. state_rx <= UART_BIT1;
  124. end
  125. else begin
  126. uart_rx_byte_r0 <= uart_rx_byte_r0;
  127. state_rx <= UART_BIT0;
  128. end
  129. UART_BIT1: if(baud_cap) begin
  130. uart_rx_byte_r0[] <= uart_rxd;
  131. state_rx <= UART_BIT2;
  132. end
  133. else begin
  134. uart_rx_byte_r0 <= uart_rx_byte_r0;
  135. state_rx <= UART_BIT1;
  136. end
  137. UART_BIT2: if(baud_cap) begin
  138. uart_rx_byte_r0[] <= uart_rxd;
  139. state_rx <= UART_BIT3;
  140. end
  141. else begin
  142. uart_rx_byte_r0 <= uart_rx_byte_r0;
  143. state_rx <= UART_BIT2;
  144. end
  145. UART_BIT3: if(baud_cap) begin
  146. uart_rx_byte_r0[] <= uart_rxd;
  147. state_rx <= UART_BIT4;
  148. end
  149. else begin
  150. uart_rx_byte_r0 <= uart_rx_byte_r0;
  151. state_rx <= UART_BIT3;
  152. end
  153. UART_BIT4: if(baud_cap) begin
  154. uart_rx_byte_r0[] <= uart_rxd;
  155. state_rx <= UART_BIT5;
  156. end
  157. else begin
  158. uart_rx_byte_r0 <= uart_rx_byte_r0;
  159. state_rx <= UART_BIT4;
  160. end
  161. UART_BIT5: if(baud_cap) begin
  162. uart_rx_byte_r0[] <= uart_rxd;
  163. state_rx <= UART_BIT6;
  164. end
  165. else begin
  166. uart_rx_byte_r0 <= uart_rx_byte_r0;
  167. state_rx <= UART_BIT5;
  168. end
  169. UART_BIT6: if(baud_cap) begin
  170. uart_rx_byte_r0[] <= uart_rxd;
  171. state_rx <= UART_BIT7;
  172. end
  173. else begin
  174. uart_rx_byte_r0 <= uart_rx_byte_r0;
  175. state_rx <= UART_BIT6;
  176. end
  177. UART_BIT7: if(baud_cap) begin
  178. uart_rx_byte_r0[] <= uart_rxd;
  179. state_rx <= UART_STOP;
  180. end
  181. else begin
  182. uart_rx_byte_r0 <= uart_rx_byte_r0;
  183. state_rx <= UART_BIT7;
  184. end
  185. UART_STOP: if(baud_cap) begin
  186. uart_rx_done_r <= 'b1;
  187. uart_rx_byte_r1 <= uart_rx_byte_r0;
  188. baud_start <= 'b0;
  189. state_rx <= UART_IDLE;
  190. end
  191. else begin
  192. uart_rx_done_r <= 'b0;
  193. uart_rx_byte_r1 <= uart_rx_byte_r1;
  194. baud_start <= 'b1;
  195. state_rx <= UART_STOP;
  196. end
  197. default: state_rx <= UART_IDLE;
  198. endcase
  199. end
  200. end
  201.  
  202. assign uart_rx_done = uart_rx_done_r;
  203. assign uart_rx_byte = uart_rx_byte_r1;
  204. 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. 使用VS2017遇到的一些小问题

    一.去掉预编译头 使用VS2017的时候,发现总是会有"pch.h","stdafx.h"这类预编译头,去掉还会报错.作为新手的我,暂时用不到这些预编译头,于是 ...

  2. JPA批量插入优化

    遇到一个需求是excel数据导入,一次大概会批量插入几万的数据.写完一测奇慢无比. 于是开始打日志,分析代码,发现是插入数据库的时候耗时很长,发现是spring data jpa的原因. 翻看jpa的 ...

  3. Linux权限:提示-bash: ./startup.sh: Permission denied的解决方案

    Linux权限:提示-bash: ./startup.sh: Permission denied的解决方案 Linux上启动Tomcat,结果弹出:-bash: ./startup.sh: Permi ...

  4. 配置HTTPS全过程

    HTTPS配置全过程服务器配置https协议HTTPS,是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL. ...

  5. 运维笔记--Docker文件占用磁盘空间异常处理

    场景描述: 1. 服务器运行一段时间后,发现系统盘磁盘空间在不断增加,一开始的时候,不会影响系统,随着时间的推移,磁盘空间在不断增加,直到有一天你会发现系统盘剩余空间即将使用完,值得庆幸的是,如果您使 ...

  6. Java:JSON和Map相互转换

    Java:JSON与Map相互转换 需要jar包:jackson-core-2.6.0.jar,jackson-databind-2.6.0.jar,jackson-annotations-2.6.0 ...

  7. python-- python threadpool 的前世今生

    引出 首先需要了解的是threadpool 的用途,他更适合于用到一些大量的短任务合集,而非一些时间长的任务,换句话说,适合大量的CPU密集型短任务,那些消耗时间较长的IO密集型长任务适合用协程去解决 ...

  8. 查找算法(5)--Tree table lookup--树表查找

    1.树表查找 (1) 最简单的树表查找算法——二叉树查找算法. [1]基本思想:二叉查找树是先对待查找的数据进行生成树,确保树的左分支的值小于右分支的值,然后在就行和每个节点的父节点比较大小,查找最适 ...

  9. Git采坑与问题排查

    目录 Case1:代码库中存大文件 Case1:代码库中存大文件 背景 有这种情况,项目运行需要依赖一个文件(比如需要读一个文件中的数据),那么最直接的方式就是将该文件添加到代码中的分支中,然后将分支 ...

  10. json 格式化处理工具

    json 格式化处理工具 用于JSON的快速命令行处理工具,简单无依赖. 我这边列举一些最常用的: 调试 http 请求时打印格式化后的数据 格式化本地或或流中的数据 获取 json 的键值或进行执行 ...