【FPGA】UART串口通信

本文详细介绍了UART串口通信协议,包括起始位、数据位、奇偶校验位和停止位等关键要素。此外,还阐述了RS-232协议在UART中的应用,并展示了UART通信的RX和TX模块的设计流程图,以及对应的Verilog代码实现,用于数据的接收和发送。最后,通过实验结果展示了串口通信的正确性。
摘要由CSDN通过智能技术生成

UART串口通信协议



前言

UART通信协议:

当检测到输入信号的下降沿时开始数据传输,同时传输数据每次不超过8位不低于5位,当数据传输结束时将电平拉高作为停止位通常为1,1.5或2位。

在这里插入图片描述
标识态:

在1个字符开始传输前,输出线必须在逻辑上处于“1”状态,这称为标识态。

起始位:

传输一开始,输出线由标识态变为“0”状态,从而作为起始位。

数据位:

起始位后面为5~8个信息位,信息位由低往高排列,即先传字符的低位,后传字符的高位。

奇偶校验位:

信息位后面为校验位,校验位可以按奇校验设置,也可以按偶校验设置,或不设校验位。
按位异或,若结果为1则将奇偶校验位赋值为1,若结果为0则将奇偶校验位赋值为0

奇校验:1000110-------->1000110(0)
	
偶校验:1000110-------->1000110(1)

停止位:

最后是逻辑的“1”作为停止位,停止位可为1位、1.5位或者2位

注:如果传输完1个字符以后,立即传输下一个字符,那么,后一个字符的起始位便紧挨着前一个字符的停止位了,否则,输出线又会进入标识态。

在这里插入图片描述


一、RS232协议

UART即通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),一般计算机外设的UART使用的协议是RS-232-C。RS-232-C是美国电子工业协会EIA(Electronic Industry Association)制定的一种串行物理接口标准。通常 RS-232 接口以9个接脚 (DB-9) 或是25个接脚 (DB-25) 的型态出现。接头分为公头和母头两种,只有公头和母头配对才能连接。

二、设计思路

1.设计流程图

外设结构

USB-TTL
VCC
连接5V电源
TXD
连接电脑端RXD
RXD
连接电脑端TXD
GND
接地

代码设计结构

RX模块
TOP
RX
使能模块
下降沿信号产生检测模块
数据传输计数器
比特流计数器
握手信号done计数器

RX模块代码实现:

`timescale 1ns / 1ps
module rx(
    input               clk     ,//系统时钟
    input               rst_n   ,//复位按键
    input               rx      ,//输入信号
    output reg[7:0]    data_reg ,//输出数据
    output reg          done	 //握手信号
    );
parameter           CLK = 50_000_000,//系统时钟频率
                     BPS = 9600,	 //波特率
                     DELAY = CLK / BPS;
parameter           check = 0;		//奇偶性 0为偶 1为奇
reg     [31:0]      cnt_bps;
reg     [3:0]       cnt_bit;
reg     [8:0]       data;
reg                 check_bit;
reg                 en_rx;
reg                 reg01;
reg                 reg02;
wire                flag;
//——————————negedge————————————————//
always@(posedge clk)//检测下降沿
    if(!rst_n)
        begin
            reg01 <= 0;
            reg02 <= 0;
        end
     else
        begin
            reg01 <= rx;
            reg02 <= reg01;        
        end
assign  flag = (~reg01) & (reg02);
//——————————energy——————————————//
always@(posedge clk)//使能信号
    if(!rst_n)
        en_rx <= 0;
    else if(flag == 1)//触发输入时使能信号拉高
        en_rx <= 1;
    else if(cnt_bit == 10 && cnt_bps == (DELAY)/2 - 1)//当数据传输完毕使能信号归零
        en_rx <= 0;
//——————————count of BPS————————————//
always@(posedge clk)//计算比特流
    if(!rst_n)
        cnt_bps <= 0;
    else if(en_rx == 1)
        begin
            if(cnt_bps == (DELAY) - 1)
                cnt_bps <= 0;
            else
                cnt_bps <= cnt_bps + 1; 
        end
     else
        cnt_bps <= 0;
//——————————count of bit——————————————//
always@(posedge clk)//计算传输数据位数
    if(!rst_n)
        cnt_bit <= 0;
     else if(en_rx == 1)
        begin
            if(cnt_bps == (DELAY) - 1)
                cnt_bit <= cnt_bit + 1;
        end
     else
        cnt_bit <= 0;
//——————————get the data————————————————//
always@(posedge clk)//扫描数据
    if(!rst_n)
        data <= 0 ;
    else if(cnt_bit > 0 && cnt_bit < 10 && en_rx == 1 && cnt_bps == (DELAY)/2)
        data[cnt_bit - 1] <= reg02;
    else if(en_rx == 1)
        data <= data;
    else
        data <= 0;
//————————————check——————————————//
always@(posedge clk)//奇偶性检测
    if(!rst_n)
        check_bit <= 0;
    else if(cnt_bit == 10 && cnt_bps == 20)
        check_bit <= ^data;
//———————————check bit——————————————//
always@(posedge clk)//二级寄存器存入数据
    if(!rst_n)
        data_reg <= 0;
     else if(cnt_bit == 10 && cnt_bps == (DELAY) / 3)
        begin
            if(check_bit == check)
                data_reg <= data[7:0];
            else
                data_reg <= 0;
        end    
//——————————————done——————————————//
always@(posedge clk)//握手信号赋值
    if(!rst_n)
        done <= 0;
    else if(cnt_bps == (DELAY) / 2 - 10 && cnt_bit ==10)
        done <= 1;
    else
        done <= 0;
        
endmodule


TX模块
TOP
TX
使能模块
数据传输计数器
比特流计数器
TX数据赋值

TX模块代码实现:

`timescale 1ns / 1ps
module tx(
    input           clk     ,
    input           rst_n   ,
    input           done    ,
    input  [7:0]    data_reg,//输入数据
    output    reg   tx		//输出信号
    );
parameter           CLK = 50_000_000,
                     BPS = 9600,
                     DELAY = CLK / BPS;
parameter          check = 0;
reg     [31:0]      cnt_bps;
reg     [3:0]       cnt_bit;
reg                 en_tx;
reg     [7:0]       data;
//——————————data—————————————//
always@(posedge clk)
    if(!rst_n)
        data <= 0;
    else if(done == 1)
        data <= data_reg;
//——————————energy————————————//
always@(posedge clk)
    if(!rst_n)
        en_tx <= 0;
    else if(done == 1)
        en_tx <= 1;
    else if(cnt_bit == 10 && cnt_bps == (DELAY)/2 - 1)
        en_tx <= 0;
//----------count of BPS------------//
always@(posedge clk)
    if(!rst_n)
        cnt_bps <= 0;
    else if(en_tx == 1)
        begin
            if(cnt_bps == (DELAY) - 1)
                cnt_bps <= 0;
            else
                cnt_bps <= cnt_bps + 1; 
        end
     else
        cnt_bps <= 0;
//----------count of bit--------------//
always@(posedge clk)
    if(!rst_n)
        cnt_bit <= 0;
     else if(en_tx == 1)
        begin
            if(cnt_bps == (DELAY) - 1)
                cnt_bit <= cnt_bit + 1;
        end
     else
        cnt_bit <= 0;
//————————————————————//
always@(posedge clk)//tx赋值
    if(!rst_n)
        tx <= 1;
     else if(en_tx == 1 && cnt_bit > 0 && cnt_bit < 9)
        tx <= data[cnt_bit - 1];
     else if(en_tx == 1 && cnt_bit == 9)
        tx <= (check)?(~(^data)):(^data);
     else if(en_tx == 1 && cnt_bit == 0)
        tx <= 0;
      else if(en_tx == 1 && cnt_bit == 10)
        tx <= 1;
      else
        tx <= 1;
endmodule


顶层模块
TOP
RX
TX

TOP模块代码如下(示例):

`timescale 1ns / 1ps
module TOP(
    input                   clk                     ,
    input                   rst_n                   ,    
    input                   rx                      ,
    output                  tx                      
    );
parameter                   sysclk = 50_000_000,
                             bps = 9600;
parameter                   check = 0;     ///0  偶   1 奇
wire                        done;
wire         [7:0]          data_reg;
tx tx_u(
    .clk                        (clk        ),
    .rst_n                      (rst_n      ),
    .done                       (done       ),
    .data_reg                   (data_reg   ),
    .tx                         (tx         )
    );
rx rx_u(
    .clk                        (clk        ),
    .rst_n                      (rst_n      ),
    .rx                         (rx         ),
    .data_reg                   (data_reg   ),
    .done                       (done       )
    );
endmodule

2.实验结果

串口调试工具页面如下:

在这里插入图片描述

发送区为输入数据,接收区为传输到PC端数据

总结

串口通信总结:

了解串口传输的基本应用场景,了解UART传输数据原理,能够合理设计模块使各个模块信号实现总体功能。

  1. 掌握基本通信协议;

  2. 掌握基本接口标准;

  3. 了解ADC/DAC接口标准;

  4. 了解信号处理原理;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值