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. bzoj4066: 简单题 K-Dtree

    bzoj4066: 简单题 链接 bzoj 思路 强制在线.k-dtree. 卡常啊.空间开1e6就T了. 代码 #include <bits/stdc++.h> #define my_m ...

  2. bootstrap弹框去除遮罩层效果

    是通过css解决这个问题,核心css代码如下: .modal-backdrop { filter: alpha(opacity=)!important; opacity: !important; } ...

  3. Jedis与Jedis连接池

    1.Jedis简介 实际开发中,我们需要用Redis的连接工具连接Redis然后操作Redis, 对于主流语言,Redis都提供了对应的客户端: https://redis.io/clients 2. ...

  4. Honk's pool[STL multiset]

    目录 题目地址 题干 代码和解释 题目地址 Honk's pool(The Preliminary Contest for ICPC Asia Shenyang 2019 ) 题干 代码和解释 本题使 ...

  5. HTTP协议之multipart/form-data

    HTTP协议之multipart/form-data REST API可以用multipart/form-data,来上传文件. 在最初的 http 协议中,没有上传文件方面的功能. rfc1867为 ...

  6. g-api notes

    目录 Q: What is GOrigin? What the meaning of parameters GMat(const GNode &n, std::size_t out) Q: h ...

  7. 微信支付:URL未注册问题

    起因:一个项目已经做好了,微信支付也调通的,域名 www.xxxx.com ,某天客户需要换域名,改为weixin.xxxx.com, 原先的www转向客户自己的官网,结果换了之后,发现微信支付出错: ...

  8. StarGAN: Unified Generative Adversarial Networks for Multi-Domain Image-to-Image Translation - 1 - 多个域间的图像翻译论文学习

    Abstract 最近在两个领域上的图像翻译研究取得了显著的成果.但是在处理多于两个领域的问题上,现存的方法在尺度和鲁棒性上还是有所欠缺,因为需要为每个图像域对单独训练不同的模型.为了解决该问题,我们 ...

  9. 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 / ...

  10. 树莓派小用手册(安装系统,配置图形界面,连接WiFi,调用摄像头,安装ffmpeg)

    安装树莓派系统(重装) 准备工作: 安装需要干净的TF卡(最好 8G 以上),如果是重装的话,需要先将其清理后再使用.清理步骤下面会给出,清理需要工具 DiskGenius,下载链接:http://w ...