09 AB 10串口通信发送原理

        通用异步收发传输器( Universal Asynchronous Receiver/Transmitter, UART)是一种异步收发传输器,其在数据发送时将并行数据转换成串行数据来传输, 在数据接收时将接收到的串行数据转换成并行数据, 可以实现全双工传输和接收。它包括了 RS232、 RS449、 RS423、RS422 和 RS485 等接口标准规范和总线标准规范。 换句话说, UART 是异步串行通信的总称。而 RS232、 RS449、 RS423、 RS422 和 RS485 等,是对应各种异步串行通信口的接口标准和总线标准,它们规定了通信口的电气特性、传输速率、连接特性和接口的机械特性等内容。

1. 09AB 基于FPGA的串口(UART)发送实验

  1. 串口通信模块设计的目的是用来发送数据的,因此需要有一个数据输入端口。
  2. 串口通信,支持不同的波特率,所以需要有一个波特率设置端口。
  3. 串口通信的本质就是将8位的并行数据,在不同的时刻传输并行数据的不同位,通过一根信号线将八位并行数据全部传出。
  4. 串口通信以1位的低电平标志串行传输的开始,待8位数据传输完成之后,再以1位的高电平标志传输的结束。
  5. 控制信号,控制并转串模块什么时候开始工作,什么时候一个数据发送完成?所以需要一个发送开始信号,以及一个发送完成信号

设计代码

  1. bps_cnt在空闲状态下保持为0,而bps_cnt为0会使得uart_tx为0,为了解决该问题,我们避开空闲状态下的bps_cnt=0,使bps_cnt从1开始判定。
  2. 但是这又会导致bps_cnt从0到1存在空闲,发送起始位时会延后一段数据位,于是我们将基础计数时间改为1时counter1开始加一。
  3. 为了出现bps_clk脉冲信号,当(div_cnt == (bps_dr - 1)成立时会输出1,我们利用该特性作为我们的脉冲信号。
  4. 我们要输入八位数据以及起始位和终止位共十位数据,为了保证十位数据完整输出,我们需要设置到第十一位停止,发送tx_done信号。
  5. 输入信号不能是reg类型,否则综合设计代码时报错:Non-net port key_in cannot be of mode input,写代码时遇到的问题。

 1.1 tx_done只保持1拍的方法

写法一相比于写法二来说,可以使bps_cnt等于11时只保持1拍,然后bps_cnt变为0,由于tx_done信号受bps_cnt影响,如果bps_cnt等于11只保持1拍就变为0的话,tx_done就可以变成我们需要的脉冲信号了(也只保持1拍为1的情况)。 

//写法一相比于写法二来说,可以使bps_cnt等于11时只保持1拍,
//然后bps_cnt变为0,由于tx_done信号受bps_cnt影响,
//如果bps_cnt等于11只保持1拍就变为0的话,
//tx_done就可以变成我们需要的脉冲信号了(也只保持1拍为1的情况)。  

   reg[3:0] bps_cnt;    
     always@(posedge clk or negedge rstn)
     if(!rstn)
         bps_cnt <= 0;
     else if(send_en)begin
         if(bps_cnt == 11)
         bps_cnt <= 0;
     else if(div_cnt == 1)   //写法1
            bps_cnt <= bps_cnt + 4'd1;
    end
    else
        bps_cnt <= 0;


    reg[3:0] bps_cnt;    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        bps_cnt <= 0;
    else if(send_en)begin
        if(div_cnt == 1)    //写法2
            if(bps_cnt == 11)
                bps_cnt <= 0;
            else 
                bps_cnt <= bps_cnt + 4'd1;
    end
    else
        bps_cnt <= 0;
module uart_byte_tx(
    clk,
    rstn,
    blaud_set,
    data,
    send_en,
    uart_tx,
    tx_done
);
    
    input clk;
    input rstn;
    input [2:0]blaud_set;
    input [7:0]data;
    input send_en;
    output reg uart_tx;
    output tx_done;
    
    //Blaud_set = 0时,波特率 = 9600;
    //Blaud_set = 1时,波特率 = 19200;
    //Blaud_set = 2时,波特率 = 38400;
    //Blaud_set = 3时,波特率 = 57600;
    //Blaud_set = 4时,波特率 = 115200;
    
    reg[17:0] bps_dr;
    always@(*)
        case(blaud_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;
        endcase
    
    wire bps_clk;
    assign bps_clk = (div_cnt == (bps_dr - 1)); //3.为了出现bps_clk脉冲信号

    reg[17:0] div_cnt;
    always@(posedge clk or negedge rstn)
    if(!rstn)
        div_cnt <= 0;
    else if(send_en)begin
        if(bps_clk)
            div_cnt <= 0;
        else
            div_cnt <= div_cnt + 1'd1;
    end
    else
        div_cnt <= 0;    
    
    reg[3:0] bps_cnt;    
    always@(posedge clk or negedge rstn)
    if(!rstn)
        bps_cnt <= 0;
    else if(send_en)begin
        if(bps_cnt == 11)
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值