FPGA学习之串口篇

文章目录

  • FPGA学习之串口篇
  • 前言
  • 二、UART发送代码
  • 三、UART接收代码
  • 三、 总结

前言

  UART(Universal Asynchronous Receiver/Transmitter)中文名称为通用异步收发器,是一种全双工异步通信总线,俗称串口。串口在MCU中很常见,串口仅用两根信号线就可以实现全双工通信,是各类MCU和一些传感器的标配,在高端SOC芯片中通常用USB取代UART。
  串口通信蕴含着最朴素的数字通信思想:通过协议规定收发双方的行为;通过约定动作获得收发同步;通过冗余实现错误检测。串口的传输格式如下:

  串口在不发送数据时,数据信号线上总是呈现高电平状态,称为空闲状态。当有数据发送时, 信号线变成低电平,并持续一个波特的时间, 用于表示发送字符的开始,该位称为起始位。起始位之后,在信号线上依次出现待发送的每一位字符数据, 并且按照先低位后高位的顺序逐位发送。待发送的位数可以选择5位、6位、7位或8位,而数据位的后面可以加上一位奇偶校验位,也可以选择不加。最后传送的是停止位,一般选择1位、1.5位或2位。


二、UART发送代码

  可以通过参数传递修改波特率。

module uart_tx #(parameter Burd_rate    = 9600 ,         // 波特率parameter Clk_freq     = 100_000_000    // 时钟频率
)(input clk_in,input rst_n,input         tx_flag,input  [7:0] tx_data,output reg tx);localparam CNT_MAX = Clk_freq/Burd_rate;reg [7:0]   tx_data_reg;
reg [0:0]   trans_en;
reg [13:0]  burd_cnt;
reg         bit_flag;
reg  [3:0]  bit_cnt;// tx_flag为高时寄存tx_data
always@(posedge clk_in or negedge rst_n)if(!rst_n)tx_data_reg <= 'h0;else if(tx_flag)tx_data_reg <= tx_data;elsetx_data_reg <= tx_data_reg;// 生成发送使能信号
always@(posedge clk_in or negedge rst_n)if(!rst_n)trans_en <= 'h0;else if(tx_flag)trans_en <= 1'b1;      else if(bit_cnt == 4'd9 && bit_flag == 1'b1)trans_en <= 1'b0;        // 累加波特计数器
always@(posedge clk_in or negedge rst_n)if(!rst_n)burd_cnt <= 'h0;else if((trans_en == 0) || (burd_cnt == CNT_MAX -1))burd_cnt <= 'h0;       else if(trans_en)burd_cnt <= burd_cnt + 1'b1; // 生成比特发送使能信号
always@(posedge clk_in or negedge rst_n)if(!rst_n)bit_flag <= 'b0;else if(burd_cnt ==  1)bit_flag <= 1'b1;     else bit_flag <= 'b0;// 累加比特计数器
always@(posedge clk_in or negedge rst_n)if(!rst_n)bit_cnt <= 'b0;else if(bit_cnt ==  4'd9 && bit_flag == 1'b1)bit_cnt <= 'b0;      else if(bit_flag ==  1'b1)bit_cnt <= bit_cnt + 1'b1;// 发送比特数据
always@(posedge clk_in or negedge rst_n)if(!rst_n)tx <= 1'b1;else if(bit_flag == 1'b1) begincase(bit_cnt)0: tx <= 1'b0;1: tx <= tx_data_reg[0];2: tx <= tx_data_reg[1];3: tx <= tx_data_reg[2];4: tx <= tx_data_reg[3];5: tx <= tx_data_reg[4];6: tx <= tx_data_reg[5];7: tx <= tx_data_reg[6];8: tx <= tx_data_reg[7];9: tx <= 1'b1;default:tx <= 1'b1;endcaseendendmodule

三、UART接收代码

  可以通过参数传递修改波特率。

module uart_rx #(parameter Burd_rate    = 9600 ,         // 波特率parameter Clk_freq     = 100_000_000    // 时钟频率
)(input clk_in,input rst_n,input rx,output reg rx_flag,output reg [7:0] rx_data
);localparam CNT_MAX =  Clk_freq/Burd_rate;reg [2:0] rx_reg;
reg       start_flag;
reg       receive_en;
reg [13:0] buad_cnt;
reg [3:0] bit_cnt;
reg       bit_flag;
reg [7:0] rx_data_reg;
reg [7:0] rx_data;
reg [0:0] rx_flag;wire fall_edge;
// 提取 rx打拍信号的下降沿
assign fall_edge = (~rx_reg[1]) && rx_reg[2] ;// 将rx打三拍
always@(posedge clk_in or negedge rst_n)if(!rst_n)rx_reg <= 3'b000;else rx_reg <= {rx_reg[1],rx_reg[0],rx};// 产生起始信号
always@(posedge clk_in or negedge rst_n)if(!rst_n)start_flag <= 1'b0;else if(fall_edge && (receive_en == 1'b0))start_flag <= 1'b1;elsestart_flag <= 1'b0;// 产生计数使能信号
always@(posedge clk_in or negedge rst_n)if(!rst_n)receive_en <= 1'b0;else if(start_flag == 1'b1 && bit_cnt == 4'b0)receive_en <= 1'b1;else if((bit_cnt == 4'd9) && (buad_cnt == CNT_MAX-1))//else if((bit_cnt == 4'd8) && (bit_flag == 1'b1))receive_en <= 1'b0;   else        receive_en <= receive_en;   // 波特计数器累加
always@(posedge clk_in or negedge rst_n)if(!rst_n)buad_cnt <= 'h0;else if(buad_cnt == CNT_MAX - 1 || receive_en == 1'b0)buad_cnt <= 'h0;else if(receive_en == 1'b1)buad_cnt <= buad_cnt + 1'b1;    // 比特采样标志信号
always@(posedge clk_in or negedge rst_n)if(!rst_n)bit_flag <= 1'b0;else if(buad_cnt == CNT_MAX/2 - 1)bit_flag <= 1'b1;else bit_flag <= 1'b0;// 接收比特计数器累加
always@(posedge clk_in or negedge rst_n)if(!rst_n)bit_cnt <= 4'b0;else if(bit_cnt == 4'd9  && buad_cnt== CNT_MAX-1)bit_cnt <= 4'b0;else if(bit_flag )bit_cnt <= bit_cnt + 1'b1;   // 接收数据移位,先接收的是低位,最后接收的是高位
always@(posedge clk_in or negedge rst_n)if(!rst_n)rx_data_reg <= 8'b0;else if(bit_flag && bit_cnt > 4'd0)rx_data_reg <= {rx_reg[2],rx_data_reg[7:1]};else if(bit_cnt == 4'b0)rx_data_reg <= 8'b0;elserx_data_reg <= rx_data_reg;// 输出数据有效信号和八位数据
always@(posedge clk_in or negedge rst_n)if(!rst_n) beginrx_data <= 8'b0;rx_flag <= 1'b0;endelse if((bit_cnt == 4'd9) && (buad_cnt== CNT_MAX -1)) beginrx_data <= rx_data_reg;rx_flag <= 1'b1;      endelse beginrx_data <= 8'b0;rx_flag <= 1'b0;endendmodule

三、 总结

  串口一次最多传输8位而不是更多位的原因在于收发双方并不是时钟同源的,并不像SPI系统有一个主时钟供主、从机共享。如果收发双方时钟偏差超过5%,则双方对同一数据序列采样经过20个时钟周期后,就会出现一个样点差异。 这种情况必然会导致数据统计错误。而UART的设计标准就是允许收发两端的频率偏差在10%以内,因此当接收8位数据后,收发双方的误差刚好控制在一位以内,对数据的采样不会出错,可正确通信。

FPGA学习之串口篇相关推荐

  1. FPGA学习之串口发送模块设计与验证

    FPGA学习之串口发送模块设计与验证 1.实验目的: 实现一个串口输出,通过上位机PC查看接收到的是否是串口发送的数据. 2.实验介绍: 学习UART通信原理及其硬件电路设计,使用FPGA实现UART ...

  2. 小梅哥FPGA学习笔记——串口发送模块

    串口发送模块 串口发送模块结构框图 顶层模块 串口发送模块结构框图 发送模块具体实现结构框图如图所示,按照图片的内容一步步实现发送模块的设计. DR_LUT查找表的作用是选择不同波特率时,得到对应波特 ...

  3. FPGA学习 Vivado使用篇之ILA(逻辑分析仪)

    ILA(Integrated Logic Analyzer),集成逻辑分析仪,允许用户在FPGA设备上执行系统内的调试.作为一名FPGA工程师,掌握在线调试工具进行时序分析是必备的职业技能之一. IL ...

  4. FPGA学习之串口发送程序设计(来自小梅哥的教程学习者)

    1. UART说明 可参考维基百科的文档:https://zh.wikipedia.org/wiki/UART 2. 实现逻辑图示 3. 程序实现 module UART_TX(rst_n,clk,s ...

  5. FPGA学习—串口通信

    FPGA学习系列 接下来介绍串口通信控制,本次就不用串口回环了,像正点原子,野火等fpga教程都会教串口回环,所以本文我将介绍如何串口控制去执行一些操作.之后也将拓展FPGA控制串口屏. 目录 FPG ...

  6. 奋斗的小孩系列 FPGA学习altera系列: FPGA学习altera 系列 第二十一篇 数码管设计

    奋斗的小孩系列 FPGA学习altera系列: FPGA学习altera 系列 第二十一篇 数码管设计 作者:奋斗的小孩 郝旭帅(转载请注明出处) 大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是 ...

  7. FPGA学习笔记_UART串口协议_串口接收端设计

    FPGA学习笔记 1. UART串口协议以及串口接收端设计 1 原理图 2 Verilog 代码 3 Modelsim仿真 4. FPGA板级验证 1.1 串口协议接收端设计 目标:FPGA接收其他设 ...

  8. Cyclone V SoC FPGA学习之路第二章:硬件篇

    Cyclone V SoC FPGA学习之路第二章:硬件篇(内部资源) 前言 上一章了解了<cycloneV device datasheet>,其中数据手册里重点介绍了电源要求,时序参数 ...

  9. 奋斗的小孩系列 FPGA学习altera系列: 第十七篇 自动售货机设计

    奋斗的小孩系列 FPGA学习altera系列: 第十七篇 自动售货机设计 作者:奋斗的小孩 郝旭帅(转载请注明出处) 大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分.大侠可以关注FPGA技术 ...

最新文章

  1. 【OpenCV 4开发详解】图像连通域分析
  2. Ubuntu中如何使得程序在后台运行
  3. UI基础视图----UIImageView总结
  4. springboot2.5.0 整合 redis 配置详解
  5. 第一章MCS-51单片机结构,单片机原理、接口及应用
  6. canvas 圆角矩形填充_一篇文章让你学会你最“害怕”的Canvas,太有意思了
  7. 剑指 Offer 10- I. 斐波那契数列/剑指 Offer 10- II. 青蛙跳台阶问题
  8. php raido mysql,linux – 如何停止并修复已失败且I / O挂起的RAID 5阵列?
  9. KVC、谓词、单例设计模式
  10. Week of year bug in Ax3
  11. 有了linux基础还学习学哪些,学linux的前途和好处有哪些
  12. 持久层框架 -Xxmm.Net
  13. Photoshop之渐变工具使用
  14. 【GPU精粹与Shader编程】(二) 《GPU Gems 1》全书核心内容提炼总结 · 上篇
  15. php curl 417,cURL简单文件上传-417预期失败
  16. bitbucket 代码备份
  17. 华为首款台式机计算机发布,华为首款商用台式机一文读懂:商用PC进入智慧时代...
  18. 苹果手机测试网络速度的软件,‎App Store 上的“网速测试大师-测网速首选”
  19. sae mysql 跨应用授权_SAE Tornado 应用连接并使用 Mysql
  20. 4.2k Star!实用的 Mac 进程管理工具

热门文章

  1. VS2015的下载及安装
  2. 通过以太坊实现自己的ICO
  3. nginx添加ssl证书
  4. KAPPA领衔实施服装ERP软件树立行业榜样
  5. 五行塔怎么吃第五个_卸甲枭雄最新章节_章节目录 第1541章 真正的五行塔_小说下载/手机阅读_领域文学...
  6. matlab中surf出来要有颜色,matlab中surf什么意思
  7. GitLab-CI 基础介绍
  8. 机器学习图像特征提取—颜色(RGB、HSV、Lab)特征提取并绘制直方图
  9. Android自定义九宫格密码解锁
  10. C++ strcpy函数的使用