FPGA 串口

第一:基本知识

   波特率:描述的是一秒钟设备接受或者发送的码元个数,由于调制方式不同,因此一个码元可能包含多个比特或者一个比特。因此波特率并不代表串口发送或者接收数据的速率。

   比特率:每秒钟传送的二进制位数,单位b/s,bit/s .

严格来说,波特率不在传输领域,出现传输、信道等字眼容易产生混淆,波特率描述的是单位时间内调制信号的能力,经它调制出来的信号才以比特的形式来传输,或者这样说,信号在传输过程中,如果要经过数模转换,就需要调制,那么传输时间除了消耗在其它领域外,还消耗在调制过程和在信道的传输过程,描述信号调制能力用波特率,描述信号传输能力用比特率。波特率与比特率的关系也可换算成:比特率=波特率*单个调制状态对应的二进制位数。

  晶体分为有缘晶振(oscillator,震荡器)和 无源晶振(crystal)

第二: FPGA 的串口USB 之间的硬件电路

   FPGA 通过串口与上位机间的通信,FPGA 采用的是串口,PC端 采用的是 USB ,因此需要串口转USB ,FPGA逻辑电平3.3 V 代表1,0V 代表0.

第三: FPGA 串口间的源程序和仿真

     

module uart_byte_tx(
    Clk,
    Reset_n,
    Data,
    Send_en,
    Baud_set,
    uart_tx,
    Tx_done
);
    input Clk;
    input Reset_n;
    input [7:0]Data;
    input Send_en;
    input [2:0]Baud_set;
    output reg uart_tx;
    output reg Tx_done;
    
    //Baud_set = 0   就让波特率 = 9600;
    //Baud_set = 1   就让波特率 = 19200
    //Baud_set = 2   就让波特率 = 38400;
    //Baud_set = 3   就让波特率 = 57600;   
    //Baud_set = 4   就让波特率 = 115200; 

    reg [17:0]bps_DR;
    always@(*)
        case(Baud_set)
            0:bps_DR = 1000000000/9600/20;
            1:bps_DR = 1000000000/19200/20;
            2:bps_DR = 1000000000/38400/20;
            3:bps_DR = 1000000000/57600/20;
            4:bps_DR = 1000000000/115200/20;
            default:bps_DR = 1000000000/9600/20;
         endcase

    wire bps_clk;
    assign bps_clk = (div_cnt == 1);
    
    reg [17:0]div_cnt;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        div_cnt <= 0;
    else if(Send_en)begin
        if(div_cnt == bps_DR - 1)
            div_cnt <= 0;
        else 
            div_cnt <= div_cnt + 1'b1;
    end
    else
        div_cnt <= 0;

    reg [3:0]bps_cnt;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        bps_cnt <= 0;
    else if(Send_en)begin
       // if(bps_clk)begin
	   if(div_cnt == 1)begin
            if(bps_cnt == 11)
                bps_cnt <= 0;
            else
                bps_cnt <= bps_cnt + 1'b1;
        end
    end
    else
        bps_cnt <= 0;
    
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n) begin
        uart_tx <= 1'b1;
        Tx_done <= 0;
    end
    else begin
        case(bps_cnt)
            1:begin uart_tx <= 0;Tx_done <= 1'b0;end
            2:uart_tx <= Data[0];
            3:uart_tx <= Data[1];
            4:uart_tx <= Data[2];
            5:uart_tx <= Data[3];
            6:uart_tx <= Data[4];
            7:uart_tx <= Data[5];
            8:uart_tx <= Data[6];
            9:uart_tx <= Data[7]; 
            10:uart_tx <= 1;
            11:begin uart_tx <= 1;Tx_done <= 1'b1;end
            default:uart_tx <= 1;
        endcase
     end     

endmodule

仿真代码:

`timescale 1ns / 1ps

module uart_byte_tx_tb();
    
    reg Clk;
    reg Reset_n;
    reg [7:0]Data;
    reg Send_en;
    reg [2:0]Baud_set;
    wire uart_tx;
    wire Tx_done; 
    
    uart_byte_tx uart_byte_tx(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .Data(Data),
        .Send_en(Send_en),
        .Baud_set(Baud_set),
        .uart_tx(uart_tx),
        .Tx_done(Tx_done)
    );
    
    initial Clk = 1;
    always#10 Clk = ~Clk;
    
    initial begin
        Reset_n = 0;
        Data = 0;
        Send_en = 0;
        Baud_set = 4;
        #201;
        Reset_n = 1;
        #100;
        Data = 8'h57;
        Send_en = 1;
        #20;
        @(posedge Tx_done);
        Send_en = 0;
        #20000;
        Data = 8'h75;
        Send_en = 1;
        #20;
        @(posedge Tx_done);
        #20000;
        Send_en = 0;
        $stop;
    end
    
endmodule

  

参考文献:电子元件:无源晶振与有源晶振

一文教你区分有源晶振与无源晶振

    

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值