fpga verilog rs232 发送模块实现

这篇具有很好参考价值的文章主要介绍了fpga verilog rs232 发送模块实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

RS-232是一种串行通信协议,用于在计算机和其他外部设备之间进行数据传输。RS-232定义了电气特性、信号级别、机械特性和传输速率等规范,为串行通信提供了一种标准化的接口。
RS-232通常使用DB9连接器,用于传输和接收数据、控制信号以及地线连接。
但除了235脚其它基本都省略了,一个发送一个接收还有个地。
rs232是单端传输,还有485,422 差分传输,485半双工,422 全双工,原理差不多
下面是verilog代码。

tx.v

module  tx (
    input wire clk,
    input wire rst_n,
    input wire tx_begin,
    input wire[7:0] tx_pdata,
    output reg txd,
    output reg busy
);

localparam OSC = 50_000_000;
localparam BAUD = 115200;
//localparam BAUD = 57600;
//localparam BAUD = 38400;
//localparam BAUD = 19200;

localparam NUM = OSC/BAUD - 1;

reg[16:0] clk_cnt;

reg [1:0] stage;
reg [2:0] curbit;
reg [7:0] tx_data;
reg done;


always @(posedge clk or negedge rst_n  ) begin
    if (!rst_n ) begin
        busy <= 1'b0;
    end else if (tx_begin === 1'b1 && busy === 1'b0  ) begin // busy ignore
        busy <= 1'b1;
        tx_data <= tx_pdata;
    end else if (done) 
      busy <= 1'b0;
end

reg tx_clk_en;

always @(busy) begin
    if(busy)
        tx_clk_en <= 1'b1;
    else
        tx_clk_en <= 1'b0;
end

reg tx_stage_pulse;
always @(posedge clk or negedge rst_n ) begin
    if (!rst_n)
      clk_cnt <= 0;
    else if( tx_clk_en === 1'b0 || clk_cnt === NUM)
        clk_cnt <= 0;
    else 
        clk_cnt <= clk_cnt + 1;
end

always @(posedge clk) begin
    if (clk_cnt === 1)
      	tx_stage_pulse <= 1'b1;
      else
        tx_stage_pulse <= 1'b0;
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        txd <= 1'b1;
        done <= 1'b0;
        stage <= 2'd0;
    end else if (busy) begin
        if (tx_stage_pulse) begin
            if (stage === 2'd0) begin
                txd <= 1'b0;
                done <= 1'b0;
                stage <= 2'b1;
                curbit <= 3'd0;
            end else if (stage === 2'b1) begin
                txd <= tx_data[curbit];
                if (curbit === 3'd7)
                    stage <= 2'd2;
                else
                    curbit <= curbit + 1;
            end else if (stage === 2'd2) begin
                txd <= 1'b1;
                stage <= 2'd3;
              end else if (stage === 2'd3) begin
                txd <= 1'b1;
                done <= 1'b1;
                stage <= 2'd0;
              end
        end
    end else begin
        txd <= 1'b1;
        done <= 1'b0;
        stage <= 2'd0;
    end
end

endmodule

测试
uart_test.v

module uart_test (
    input wire clk,
    input wire rst_n,
    output wire txd
);

reg tx_begin;
reg[7:0] tx_data = 0;

reg[31:0] cnt;
parameter maxcnt = 32'd1500 ;
wire busy;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cnt <= 0;
    else if (cnt == maxcnt) begin
        cnt <= 0;
        if(!busy) 
        	tx_data <= (tx_data + 1) & 8'h7f ;
        tx_begin <= 1'b1;
    end else begin
        tx_begin <= 1'b0;
        cnt <= cnt+1;
    end
end

tx tx1(clk,rst_n,tx_begin,tx_data,txd,busy);

endmodule

testbench
test.v

module test;

reg rst_n=1 ;

initial begin
    $dumpfile("test.vcd");
    $dumpvars(0, test);

    #10 rst_n = !rst_n;
    #30 rst_n = !rst_n;
    #100000 $finish;
end

reg clk = 0;
always #1 clk = !clk;

wire txd;
uart_test uart1(clk,rst_n,txd);

endmodule

fpga verilog rs232 发送模块实现,fpga开发
两个问题,一帧数据传输完成前,再次接到发送指令,直接丢弃,因为中间即使停止, 对方也会以为这是数据直到完成这一帧 , 有可能会打乱时序 ,或用FIFO。引出一位busy忙标志位。
二停止位,有1位,1.5位,2位的,测试了下若用1位停止位的话,发送停止位完成后,半个停止位内再次发送会出现乱码应该是232芯片有一个要求大于1.5的,从FPGA出来后先转232一个芯片,232再转usb一个芯片,稳定起见,停止位两位。文章来源地址https://www.toymoban.com/news/detail-770580.html

到了这里,关于fpga verilog rs232 发送模块实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包