Verilog实现串口通讯(UART)

Verilog实现串口通讯(UART)

本代码参考了野火的相关教程,实现了发送和接收回环,同时可以通过串口数据控制LED灯的亮灭,在电脑发送数据时要选择HEX发送模式,发送16进制的数据进行控制。

UART协议中,在空闲时为高电平。在常用的一位停止位和无校验位的设置中,起始位为低电平,紧接着是8位的数据位,最后是一位高电平的停止位。

接收模块

​ 接收模块的主要设计是将起始位下降沿的检测作为接收系统的开始信号,通过起始信号和bit位的计数信号相结合就可以得到一个贯穿整体运行过程的使能信号,通过对使能信号的判断就可以实现对系统的控制。

​ 另一个关键问题是电平采集的时间,应该 在一个bit的中间位置进行采集,这样可以有效避免采集电平不稳定的问题。

接收模块的代码如下:

module uart_receive (
    input  clk,
    input  rst_n,
    input  uart_rx,
    output reg receive_done,
    output reg  [7:0]   uart_data
);
parameter  SYSTERM_CLK = 50_000_000;               //系统时钟频率
parameter  UART_BPS    = 115200;                     //串口波特率
localparam BPS_COUNT_MAX   = SYSTERM_CLK/UART_BPS;     //为得到指定波特率
                                                   //需要对系统时钟计数BPS_COUNT次
reg      [7:0]       reg_data;//接受数据缓存
reg      [3:0]       bit_count;//接收数据时用于计数接收到了多少位
reg      [12:0]      bps_count;//用于按照时钟计算一个字节的时间
reg                  start_bit;//检测到起始位的下降沿之后触发一个时钟的高电平
reg                  reg1     ;
reg                  reg2     ;
reg                  reg3     ;           
reg                  bit_flag ;//在一个电平的中间位置产生高电平标志
reg                  work_en  ;//在本标志位高电平时,接受工作开始,在低电平时工作结束
reg                  rx_flag  ;//在数据缓存器存满了之后产生一个高电平

//插入两级寄存器进行数据同步,用来消除亚稳态
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        reg1 <= 1'b1;//因为UART的空闲状态是高电平,所以复位时电平要设置为高电平
    end
    else        begin
        reg1 <= uart_rx;
    end
end    
//插入两级寄存器进行数据同步,用来消除亚稳态
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        reg2 <= 1'b1;//因为UART的空闲状态是高电平,所以复位时电平要设置为高电平
    end
    else        begin
        reg2 <=reg1;
    end        
end

//插入两级寄存器进行数据同步,用来消除亚稳态
always @(posedg
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值