目录

前言

1、UART串口的介绍

2、实验开始前一些参数的计算

3、UART通信的时序

4、代码部分

1、接收部分代码

2、发送部分的代码


前言

本篇文章是为了记录自己FPGA的学习过程,不完全正确,仅供参考!!!

1、UART串口的介绍

uart串口是我们常用的一种通讯协议,它的中文名称是通用异步收发传输器,像我们常见的RS232、RS485都是uart串口的一种,只不过是电平不同,通讯时序上都是一样的,像是RS232,只需要用MAX3232芯片进行电平转换就可以,那么uart串口既然是串行的通行协议,我们在使用的时候一般需要将并行数据转换成串行数据,这点需要注意,uart一般有四条线,VCC、GND、RX、TX,在使用的时候通讯双方一定要共地,因为其有tx和rx两根线,所以uart是全双工的通讯,但是uart是通讯速率比较慢的一种。

2、实验开始前一些参数的计算

首先我们需要知道波特率是啥,波特率就是表示uart串口传输速度的一个表示方式,常见的有4800、9600、115200,其实波特率就是uart串口传输一个bit数据所需要的时间,也是uart窗口工作时做基本的时间单位,时间=1/bound,我们在使用uart之前,需要约定好bound和奇偶效验位,本次实验以9600的波特率和无奇偶效验位来做,那么我需要知道约定好波特率之后,我们一个bit的数据需要保持相应的时间啊,那我们来计算下(1/9600)x10*9约等于10416ns,我们系统的时间周期为20ns,那么我们需要进行计数的值为5207(从0开始)

3、UART通信的时序

程序就是按照这个图中的时序写的,其中需要注意的是uart串口的空闲状态是高电平,起始位是一个bit的低电平(实际操作是我们可以去捕获下降沿),然后传输8位数据,先传输的是低位数据 ,然后是高位数据,在八位数据结束后,可以约定奇偶效验位,然后就是停止位和空闲状态,实际上直接拉高电平,就结束传送了,本实验室将接收的数据发送出去。

4、代码部分

1、接收部分代码

module  uart_rx
(input   wire        sys_clk,input   wire        sys_rst,input   wire        rx_data,output  reg  [7:0]  out_data,//串转并并输出output  reg         out_reg//接收完成的标志
);parameter   [12:0]   UART_MAX = 13'd5207,[3:0]    BIT_MAX = 4'd9;reg     [12:0]  uart_cnt;//利用该计数器来计算不同波特率下传送一bit数据的时间
reg             uart_data1; //打三拍的中间变量
reg             uart_data2; //打三拍的中间变量
reg             uart_data3; //打三拍的中间变量
reg             begin_flag;//传输开始标志
reg             data_en;//数据有效信号
reg     [3:0]   bit_cnt;//位数计数
wire            data_flag;//该标记主要用于取中中间部分的数据,主要是中间数据较为稳定
reg     [7:0]   tx_data;
reg             rx_end_flag;/*波特率为9600时,当系统时钟为50MHZ的时候,这时每传输一个bit的数据,每个传输周期相当于5208个周期
所以这边需要一个计数器来计算出一个传输的周期(具体计数值为((1/bound)*10*9)/系统周期)这边的单位是ns*/always@(posedge sys_clk)
beginif(sys_rst == 1'b0)uart_cnt <= 13'd0;else if((uart_cnt == UART_MAX)||(data_en == 1'd0))uart_cnt <= 13'd0;else  uart_cnt <= uart_cnt +13'd1;
endalways@(posedge sys_clk)
beginif(sys_rst == 1'b0)bit_cnt <= 4'd0;else if((bit_cnt == BIT_MAX)&&(uart_cnt == UART_MAX))bit_cnt <= 4'd0;else if(uart_cnt == UART_MAX)bit_cnt <= bit_cnt + 4'd1;elsebit_cnt <= bit_cnt;
end//对输入的数据打三拍这边一定要注意,uart串口空闲状态为高电平,开始标志为高电平到下降沿的一个下降沿,所以在给初值的时候,需要赋值为高电平
always@(posedge sys_clk)
beginif(sys_rst == 1'b0){uart_data3,uart_data2,uart_data1} <= 3'b111;else{uart_data3,uart_data2,uart_data1} <= {uart_data2,uart_data1,uart_data};
end  //因为空闲状态到开始的状态是一个下降沿,这边判断是下降沿就把开始标志置一
always@(posedge sys_clk)
beginif(sys_rst == 1'b0)begin_flag <= 1'b0;else if((uart_data2 == 1'b0)&&(uart_data3 == 1'b1)&&(data_en == 1'b0))begin_flag <= 1'b1;else begin_flag <= 1'b0;
end/*数据使能信号,因为我们判断开始信号是用下降沿来判断的,但是这可能产生一个误判,
因为串行数据传输的时候,也会产生下降沿,所以这里我们用data_en变量来辅助判断*/
always@(posedge sys_clk)
beginif(sys_rst == 1'b0)data_en <= 1'b0;else if(begin_flag == 1'b1)data_en <= 1'b1;else if((bit_cnt == 4'd9)&&(data_flag == 1'b1))data_en <= 1'b0;else data_en <= data_en;
endassign data_flag = ((bit_cnt >= 4'd1)&&(bit_cnt < 4'd9)&&(uart_cnt == 13'd2603))? 1'b1 : 1'b0;    always@(posedge sys_clk)
begin if(sys_rst == 1'b0)tx_data <= 8'b0;else if((data_flag == 1'b1))tx_data <= {uart_data3,tx_data[7:1]};elsetx_data <= tx_data;
endalways@(posedge sys_clk)
beginif(sys_rst == 1'b0)rx_end_flag <= 1'b0;else if((bit_cnt == 4'd8)&&(data_flag == 1'b1))rx_end_flag <= 1'b1;elserx_end_flag <= 1'b0;
end/*开始我以为代码写到这里就结束了,但其实我还是太年轻了,为了使我们的输出的数据和输出的接收完成的标志信号同步(这样在标志有效的时候,读的数据才对)
其实上面的数据也是对齐的,但是为了养成一个良好的习惯,下面还是在同一条件下对数据和标志信号进行输出*/always@(posedge sys_clk)
beginif(sys_rst == 1'b0)out_data <= 8'b0;else if(rx_end_flag == 1)out_data <= tx_data;else out_data <= out_data;
endalways@(posedge sys_clk)
beginif(sys_rst == 1'b0)out_reg <= 1'b0;else if(rx_end_flag == 1)out_reg <= rx_end_flag;else out_reg <= 1'b0;
endendmodule

2、发送部分的代码

module  uart_tx
(input   wire            sys_clk,input   wire            sys_rst,input   wire    [7:0]   in_data,input   wire            in_flag,//这个是rx模块输出的标志信号output  reg     [7:0]   tx_data
);parameter   [12:0]   UART_MAX = 13'd5207,[3:0]    BIT_MAX = 4'd9;reg     [12:0]  uart_cnt;//利用该计数器来计算不同波特率下传送一bit数据的时间
reg             data_en;//数据有效信号
reg     [3:0]   bit_cnt;//位数计数
wire            data_flag;//always@(posedge sys_clk)
beginif(sys_rst == 1'b0)uart_cnt <= 13'd0;else if((uart_cnt <= UART_MAX)||(data_en == 1'b0))uart_cnt <= 13'd0;else uart_cnt <= uart_cnt + 13'd1;
endalways@(posedge sys_clk)
beginif(sys_rst == 1'b0)bit_cnt <= 4'd0;else if((uart_cnt == UART_MAX)&&(bit_cnt == BIT_MAX))bit_cnt <= 4'd0;else bit_cnt <= bit_cnt +4'd1;
endalways@(posedge sys_clk)
beginif(sys_rst == 1'b0)data_en <= 1'b0;else if(in_flag == 1'b1)data_en <= 1'b1;else if((bit_cnt == 4'd9) && (data_flag == 1'b1))data_en <= 1'b0; else data_en <= data_en;
endalways@(posedge sys_clk)
beginif(sys_rst == 1'b0)data_flag <= 1'b0;else if(uart_cnt == 13'd2605)data_flag <= 1'b1;else data_flag <= 1'b0;
endalways@(posedge sys_clk)
beginif(sys_rst == 1'b0)data_flag <= 1'b0;else if(data_flag == 1'b1)case(bit_cnt)4'd0 : tx_data <= 1'b0;4'd1 : tx_data <= in_data[0];4'd2 : tx_data <= in_data[1];4'd3 : tx_data <= in_data[2];4'd4 : tx_data <= in_data[3];4'd5 : tx_data <= in_data[4];4'd6 : tx_data <= in_data[5];4'd7 : tx_data <= in_data[6];4'd8 : tx_data <= in_data[7];4'd9 : tx_data <= 1'b1;default: tx_data <= 1'b1;endcase
endendmodule 

FPGA-UART串口通信相关推荐

  1. 基于FPGA Uart串口通信实验

    基于FPGA Uart串口通信实验 首先需要了解uart串口通信协议,根据个人专业需求不同,了解的层面可以不同. UART简介 通用异步收发传输器(Universal Asynchronous Rec ...

  2. 基于FPGA的UART串口通信实验(VHDL语言实现)

    一.前言: 最近在做UART串口通信的相关实验时,在网上查了很多资料,发现网上的大部分文章只注重理论,不注重代码,很多代码有错误不说,而且难以理解.故在完成此实验后,起了写一篇博客的心思,以供有想做相 ...

  3. 【FPGA】八、UART串口通信

    文章目录 前言 一.UART简介 1.基本概念 2.UART协议 3.波特率简介 二.UART串口回环实验 1.设计思路 2.程序代码 ① 串口接收模块 ② 串口发送模块 ③ 串口顶层模块 ④ 串口仿 ...

  4. 【FPGA练习】(一): UART串口通信实验

    由于之前学习FPGA的过程中,没有做一个良好的记录,以及已学知识的扩展,所以从今天开始每一个实验例程和扩展应用,都要做文档记录.本实验,是基于正点原子达芬奇xc7a35tfgg484-2开发板.开发板 ...

  5. (一)FPGA之串口通信(UART)

    (一)FPGA之串口通信(UART) 回到梦开始的地方,如今回过头来看串口协议,确实清晰了很多,但是奈何好记性不如烂笔头,我还是要重新记录一下学习的知识点,方便查找和学习. 波特率(Band Rate ...

  6. 【FPGA】UART串口通信

    目录 前言 一丶通信方式 1.串行通信 2.并行通信 二丶UART 串口通信 三丶模块设计 四丶发送模块 1.代码 2.仿真 五丶接收模块 1.代码 2.仿真 六丶顶层模块 1.代码 2.模块原理图 ...

  7. 【正点原子MP157连载】 第十六章 UART串口通信实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  8. [FPGA] UART串口回环

    文章目录 前言 一.UART是什么? 二.UART协议 1.内容 2.系统模块划分 2.1.接收模块 2.2.发送模块 2.3.控制模块 2.4.顶层模块 3.仿真 前言 上期介绍了串行通信的基本概念 ...

  9. UART串口通信(回环测试)

    一 UART串口通信简介 UART(Universal Asynchronous Receiver-Transmitter)是采用异步串行通信方式的通用异步收发传输器,在发送数据时将并行数据转换为串行 ...

  10. UART 串口通信实验

            串口是"串行接口"的简称,即采用串行通信方式的接口.串行通信将数据字节分成一位一位的形式在一条数据线上逐个传送,其特点是通信线路简单,但传输速度较慢.因此串口广泛应 ...

最新文章

  1. linux shell 得到当前时间
  2. 关于HTML加密混淆、源码保护、代码安全,防止解压直接看源码
  3. python开发框架 代码生成_500 行 Python 代码构建一个轻量级爬虫框架
  4. linux-压缩和解压类
  5. 深度学习基础(三)loss函数
  6. 使用git时报错出现vim.exe.stackdump
  7. sql:MySQL 6.7 表,视图,存储过程结构查询
  8. parzen窗估计如何进行结果分析_Parzen窗方法的分析和研究
  9. MEF体验使用接口导出的优越性
  10. What is “Deploy applications configured in Tomcat instance” in IntelliJidea
  11. 管理感悟:学会推论及验证
  12. 为什么苏联打下了如此强的数学基础,俄罗斯却至今无法成为AI强国?
  13. threejs学习笔记:贴图实现木地板效果
  14. 网络操作系统 Linux配置与管理,网络操作系统—Linux配置与管理
  15. Python 中 ‘unicodeescape’ codec can’t decode bytes in position XXX: trun错误原因分析及解决方案
  16. SCRM升级--企业微信数字营销解决方案
  17. 什么是CVE?常见漏洞和暴露列表概述
  18. 自媒体:我为什么要写一篇关于睡眠的文章?
  19. 动态规划DP模板题汇总
  20. matlab csp详解,内容安全策略(CSP)详解

热门文章

  1. 华为云云主机主机迁徙服务的作用
  2. python 基础面试题
  3. FineReport(帆软)根据条件显示和隐藏列数据
  4. Xtensa 仿真环境tunning分析(ISS profile)
  5. 关于成长、个人增值,未来机遇/发展
  6. 为自己的不当行为致歉
  7. 深度学习了40万个表情,一大波AI 表情包来了
  8. Eclipse 中添加注释,注释中包含作者时间等
  9. 酒店中计算机信息应用的重要性,计算机在酒店管理中的应用价值
  10. 安装plsql,一定要安装oracle客户端