搜索
bottom↓
回复: 7

怎样提高FPGA实现串口通讯的可靠性?

[复制链接]

出0入0汤圆

发表于 2011-8-14 22:16:57 | 显示全部楼层 |阅读模式
写了接和发的程序,verilog描述
115200bps,串口助手100mS发一个字节,FPGA收到后返回原字节,FPGA晶振50MHz
串口助手共发送298个,只收到275个
丢了23,7.x%了

点击此处下载 ourdev_667582P45W1E.rar(文件大小:766字节) (原文件名:USART_RX.rar)
点击此处下载 ourdev_667583U5QS3E.rar(文件大小:1K) (原文件名:USART_TX.rar)

贴个接收的,短些
-----------------------------------------------------
`define UD #1

module USART_RX
        (
        // input ports
      SYSCLK,
      RST_B,
        RX_IN,
       
        // output ports
        RX_FINISH,
        RX_DATA
        );

//===========================================================================
// Input and output declaration
//===========================================================================
input SYSCLK;
input RST_B;
input RX_IN;

output RX_FINISH;
output [7:0] RX_DATA;

//===========================================================================
// Wire and reg declaration
//===========================================================================
wire SYSCLK;
wire RST_B;
wire RX_IN;

wire RX_FINISH;
reg [7:0] RX_DATA;

//===========================================================================
// Wire and reg in the module
//===========================================================================
reg RX_IN_REG;
reg RX_IN_REG_N;

wire RX_START;  // 开始接收

reg [15:0] CLK_DIV_CNT;
reg [15:0] CLK_DIV_CNT_N;

reg [7:0] RX_DATA_N;
//===========================================================================
// Logic
//===========================================================================
always @ (posedge SYSCLK)
    RX_IN_REG_N <= `UD RX_IN;

always @ (posedge SYSCLK)
    RX_IN_REG <= `UD RX_IN_REG_N;

assign RX_START = (!RX_IN && (RX_IN_REG_N || RX_IN_REG)) ? 1'b1 : 1'b0;

assign RX_FINISH = (CLK_DIV_CNT == 16'h11A3) ? 1'b1 : 1'b0;

// 波特率需要的时钟
always @ (posedge SYSCLK or negedge RST_B)
begin
    if(!RST_B)
        CLK_DIV_CNT <= `UD 16'h0;
    else
        CLK_DIV_CNT <= `UD CLK_DIV_CNT_N;
end

always @ (*)
begin
    if(RX_START && (CLK_DIV_CNT == 16'h0))
        CLK_DIV_CNT_N = 16'h1;
    else if(CLK_DIV_CNT == 16'h11A3)
        CLK_DIV_CNT_N = 16'h0;
    else if(CLK_DIV_CNT != 16'h0)
        CLK_DIV_CNT_N = CLK_DIV_CNT + 1'h1;
    else
        CLK_DIV_CNT_N = CLK_DIV_CNT;
end
//---------------------------------------------------

// 接收数据
always @ (posedge SYSCLK or negedge RST_B)
begin
    if(!RST_B)
        RX_DATA <= `UD 8'h0;
    else
        RX_DATA <= `UD RX_DATA_N;
end

always @ (*)
begin
    if((CLK_DIV_CNT == 16'h2D0)
        || (CLK_DIV_CNT == 16'h47E)
        || (CLK_DIV_CNT == 16'h62C)
        || (CLK_DIV_CNT == 16'h7DA)
        || (CLK_DIV_CNT == 16'h988)
        || (CLK_DIV_CNT == 16'hB36)
        || (CLK_DIV_CNT == 16'hCE4)
        || (CLK_DIV_CNT == 16'hE92))
                RX_DATA_N = {RX_IN, RX_DATA[7:1]};
     else
            RX_DATA_N = RX_DATA;
end
endmodule

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-8-16 09:31:12 | 显示全部楼层
给你个你看看有没有你需要的
点击此处下载 ourdev_668140CXTYE5.rar(文件大小:1.08M) (原文件名:VHDL程序部分.rar)

出0入0汤圆

发表于 2011-8-16 09:49:50 | 显示全部楼层
提高时间频率,不要一个时钟周期对应一个数据位,这样在判断起始位时可以通过几个时钟周期来判断,比如4个时钟周期都是低电平了,就说明起始位到来,开始接收数据,并增加校验位等

出0入0汤圆

发表于 2011-8-17 16:11:13 | 显示全部楼层
thanks for sharing

出0入0汤圆

发表于 2011-8-29 17:27:25 | 显示全部楼层
正在做串口,希望能早些搞定啊

出0入0汤圆

发表于 2011-12-29 11:28:04 | 显示全部楼层
用核实现串口逻辑,基本不会错 我在115200波特率 基本上半小时一起误码

出0入0汤圆

发表于 2012-1-9 17:01:23 | 显示全部楼层
不错,关注
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 11:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表