基于FPGA的UART串口接收模块设计.doc

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

UART串口接收模块设计

实验目标:实现FPGA接收其他设备通过UART协议发送过来的数据。

知识点:

1、URAT通信协议工业环境下数据接收实现。

2、In system sources and probes editor(ISSP)调试工具的使用。

UART发送端发送一个字节数据时序图:

对于其中的每一位进行采样,一般情况下每一位数据的中间点是最稳定的,因此一般应用中,

:

采集中间时刻时的数据即可,如下图所示

但是在工业应用中,往往有非常强的电磁干扰,只采样一次就作为该数据的电平判定,是不保险的,有可能恰好采集到被干扰的信号而导致结果出错,因此需要使用多次采样求概率的方式进行。

以下为改进型的单bit数据接收方式示意图:

12345678910111213141516

在这张图中,将每一位数据又平均分成了16小段,对于Bit_x这一位数据,考虑到数据在刚刚发生变化和即将发生变化的这一时期,数据极有可能不稳定的(用红色标出的两段),在这两个时间段采集数据,很有可能得到错误的结果,因此这两段时间的电平无效,采集时直接忽略。而中间这一时间段(用绿色标出),

数据本身是比较稳定的,一般都代表了正确的结果。但是也不排除该段数据受强电磁干扰而出现错误的电平脉冲,因此对这一段电平,进行多次采样,并求高低电平发生的概率,6次采集结果中,取出现次数多的电平作为采样结果。例如,采样6次的结果分别为1/1/1/1/0/1/,则取电平结果为1,若为0/0/1/0/0/0,,则取电平结果为0,当6次采样结果中1和0各占一半(各3次),则可判断当前通信线路环境非常恶劣,数据不具有可靠性。

串口发送模块包含两个主要组件:

1、起始位检测进程(低电平,下降沿)

2、波特率产生模块

3、数据接收模块

串口接收模块整体结构图:

波特率时钟计算:

Modelsim仿真图:

·在testbench文件中我们为设计输入了假定的信号,在仿真图中我们可以看到data_byte_r 在Rx_done标志位产生的时候成功的将仿真数据data_byte_t接收到其中。实现了串口接收数据的功能,其余各状态表现正常。

Rtl功能图

附录:源程序:

一,顶层功能代码

module uart_rx_top(Clk,Rst_n,Rs232_Rx);

input Clk;

input Rst_n;

input Rs232_Rx;

reg [7:0]data_rx_r;

wire [7:0]data_rx;

wire Rx_Done;

uart_byte_rx uart_byte_rx(

.Clk(Clk),

.Rst_n(Rst_n),

.baud_set(3'd0),

.Rs232_Rx(Rs232_Rx),

.data_byte(data_rx),

.Rx_Done(Rx_Done)

);

issp issp(

.probe(data_rx_r),

.source()

);

always@(posedge Clk or negedge Rst_n)

if(!Rst_n)

data_rx_r <= 8'd0;

else if(Rx_Done)

data_rx_r <= data_rx;

else

data_rx_r <= data_rx_r; endmodule

二testbench仿真文件

`timescale 1ns/1ns

`define clk_period 20

module uart_byte_rx_tb;

reg Clk;

reg Rst_n;

reg Rs232_Rx;

wire [7:0]data_byte_r;

wire Rx_Done;

reg [7:0]data_byte_t;

reg send_en;

reg [2:0]baud_set;

wire Rs232_Tx;

wire Tx_Done;

wire uart_state;

uart_byte_rx uart_byte_rx(

.Clk(Clk),

.Rst_n(Rst_n),

.baud_set(baud_set),

.Rs232_Rx(Rs232_Tx),

.data_byte(data_byte_r),

.Rx_Done(Rx_Done)

);

uart_byte_tx uart_byte_tx(

.Clk(Clk),

.Rst_n(Rst_n),

.data_byte(data_byte_t),

.send_en(send_en),

.baud_set(baud_set),

.Rs232_Tx(Rs232_Tx),

.Tx_Done(Tx_Done),

.uart_state(uart_state)

);

initial Clk = 1;

always#(`clk_period/2)Clk = ~Clk;

initial begin

Rst_n = 1'b0;

data_byte_t = 8'd0;

send_en = 1'd0;

baud_set = 3'd4;

#(`clk_period*20 + 1 );

Rst_n = 1'b1;

#(`clk_period*50);

data_byte_t = 8'haa;

send_en = 1'd1;

#`clk_period;

send_en = 1'd0;

@(posedge Tx_Done)

#(`clk_period*5000);

data_byte_t = 8'h55;

send_en = 1'd1;

#`clk_period;

send_en = 1'd0;

@(posedge Tx_Done)

#(`clk_period*5000);

$stop;

end

endmodule

相关文档
最新文档