波特率是什么?波特率设计

电子说

1.2w人已加入

描述

01 波特率是什么

从宏观理解,波特率表征了串口的 传输速度

从微观上,波特率是指在系统中 单位时间内传输的码元个数 。对于UART而言,码元是二进制的,都是用高低电平传输,所以波特率和比特率在数值上是相等的。例如,当波特率为115200时,实质就是UART串口每秒传输115200个bit的数据量,传输一个bit的时间等于1/115200秒。常见的UART串口波特率为300、600、1200、4800、9600、19200、34800等。

串口传输中一个bit数据的周期即传输一个bit的时间,即可以表示为:

时钟域

在串口传输中,一帧数据由起始位(1bit)、数据位(典型8bit)、校验位(1bit)和停止位(1bit)组成,在通常情况下一帧数据有11bit。那么可以算出1帧数据传输所需的时间为11x1/bps。

串口通信的双方需要设置相同的波特率 ,由波特率约定数据传输的周期。决定了应该多久读取一次电平值。

02 模块接口与描述

时钟域

  • 26MHz功能时钟主要用于波特率的产生与计算,由外部输入。
  • 接收波特率使能信号由接收数据模块中产生,UART_RX线检测到起始位后使能接收波特率。
  • 发送波特率使能信号由发送数据模块中产生,需要发送数据时即可使能。
  • 波特率分频系数是配置模块产生,由APB总线配置。
  • 接收和发送波特率时钟根据配置由26MHz时钟产生的用接收和发送数据的信号。

03 功能时钟与波特率设计

本项目使用的功能时钟为26MHz,波特率可通过波特率分频系数BAUD_DIV进行配置。波特率分频系数BAUD_DIV与波特率之间的关系为:

时钟域

为了方便计算和设计,我们将N固定为16,只配置BAUD_DIV来调整波特率,波特率可配置如下:

时钟域

波特率计算公式中,分母即为一个数据周期所需要计26MHz时钟的个数。已知波特率和功能时钟频率,即可计算一个波特率周期所需的功能时钟数。公式中的乘N操作使用左移实现(默认波特率为9600)。

always@(posedge clk26m ornegedge rst26m_) begin
    if(!rst26m_) begin
        cnt_value <= 10'd169 < < 4;
    end
    elsebegin
        cnt_value <= (baud_div + 1'b1) < < 4;
    end
end

在产生接收数据的波特率时钟时,需要注意,接收模块是根据所产生的这个波特率时钟来进行数据接收,数据采集如果都在“ 每位数据的中间 ”,那么采样出的数据是最稳定的。

时钟域

接收数据采样

所以在产生波特率时钟时,RX波特率计数器累加到一半时就应使产生接收波特率时钟。而发送数据时则不必这样,只需保证波特率正确即可。

波特率模块实现如下:

`timescale 1ns/1ps
module    UART_BAUD(
   // inputs
    clk26m,
    rst26m_,
    tx_bps_en,
    rx_bps_en,
    baud_div,
    // outputs
    rx_bpsclk,
    tx_bpsclk
);

input            clk26m;             // 26M function clock
input            rst26m_;            // function clk's rst_
input            rx_bps_en;          // baud enable signal
input            tx_bps_en;
input  [9:0]     baud_div;           // baud frequency divide factor
output           rx_bpsclk;          // receive bps clk
output           tx_bpsclk;          // send bps clk

reg  [13:0]     cnt_value;           // bps count value
reg  [13:0]     cnt_baud_rx;         // receive baud counter
reg  [13:0]     cnt_baud_tx;         // send baud counter


// produce receive bpsclk
always@(posedge clk26m ornegedge rst26m_) begin
    if(!rst26m_) begin
        cnt_baud_rx <= 14'd0;
    end
    elsebegin
        if(rx_bps_en) begin
            if(cnt_baud_rx > cnt_value - 1'b1) begin
                cnt_baud_rx <= 14'd0;
            end
            elsebegin
                cnt_baud_rx <= cnt_baud_rx + 1'b1;
            end
        end
        elsebegin
            cnt_baud_rx <= 14'd0;
        end
    end
end
assign  rx_bpsclk = (cnt_baud_rx == (cnt_value > >1))? 1'b1:1'b0;

// produce send bpsclk
always@(posedge clk26m ornegedge rst26m_) begin
    if(!rst26m_) begin
        cnt_baud_tx <= 14'd0;
    end
    elsebegin
        if(tx_bps_en) begin
            if(cnt_baud_tx > cnt_value - 1'b1) begin
                cnt_baud_tx <= 14'd0;
            end
            elsebegin
                cnt_baud_tx <= cnt_baud_tx + 1'b1;
            end
        end
        elsebegin
            cnt_baud_tx <= 14'd0;
        end
    end
end
assign  tx_bpsclk = (cnt_baud_tx == (cnt_value > >1))? 1'b1:1'b0;

always@(posedge clk26m ornegedge rst26m_) begin
    if(!rst26m_) begin
        cnt_value <= 10'd169 < < 4;
    end
    elsebegin
        cnt_value <= (baud_div + 1'b1) < < 4;
    end
end

endmodule

波特率模块虽然理解和实现起来比较简单,但也是比较重要的,是接收和发送数据的依据。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分