「已注销」 2021-12-14 17:53 采纳率: 100%
浏览 51
已结题

FPGA驱动传感器 uart无法接收多字节数据

用FPGA驱动 uart通信协议的 32字节传感器PMS5003,格式9600 8N1,报头文1==0x42;报头文2==0x4d;
现在的问题在于:当传感器连rxd输入时,接收不到数据;
传感器本身是没有问题的,单独连串口助手也可以收发正常
但是通过电脑的串口助手给rxd发送32字节数据时,就可以接收到数据,哪一步出了问题呢?调试了一天也没有结果。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2021/12/13 17:45:57
// Design Name: 
// Module Name: ip_PMS5003
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module ip_PMS5003(
    input clk,
    input rst,
    input rxd,
//    output  txd,
    output reg [7:0]led,
//    output reg [7:0]data_out1,
    output [7:0]seg,
    output [3:0]an
//    output reg data_ready
    );
//assign txd=rxd;
localparam baud_cnt_end = 'd5208 - 'd1                            ;
localparam baud_cnt_m     = (baud_cnt_end ) / 'd2                  ;

reg data_ready;
reg [7:0]data_out1;


reg rx1;
reg rx2;
reg rx_flag;
reg [12:0] baud_cnt;
reg bit_flag;
reg [3:0] bit_cnt;



always@(posedge clk)
begin
    rx1 <= rxd;
    rx2 <= rx1;
end
wire nedge;
assign nedge = rx2 && ~rx1 && !rx_flag;




always @ (posedge clk or negedge rst)
begin
    if(rst)
        rx_flag <= 1'b0;
    else     
        if(nedge)
            rx_flag    <= 1'b1;
        else     
            if(bit_cnt == 'd9 && baud_cnt == baud_cnt_end)
                rx_flag <= 1'b0;
end




always@(posedge clk or negedge rst)
begin
    if(rst)
        baud_cnt <= 13'd0;    
    else 
        if(baud_cnt == baud_cnt_end)
            baud_cnt <= 13'd0;
        else 
            if(rx_flag)
                baud_cnt <= baud_cnt + 1'b1;
            else 
                baud_cnt <= 13'd0;
end




always@(posedge clk or negedge rst)
begin
    if(rst)
        bit_flag <= 1'b0;
    else 
        if(baud_cnt == baud_cnt_m)
            bit_flag <= 1'b1;
        else 
            bit_flag <= 1'b0;
end




always@(posedge clk or negedge rst)
begin
    if(rst)
        bit_cnt <= 4'd0;
    else 
        if(rx_flag == 0)
            bit_cnt <= 4'd0;
        else 
            if(baud_cnt == baud_cnt_end && rx_flag)
                bit_cnt <= bit_cnt + 1'b1;
end




always@(posedge clk or negedge rst)
begin
    if(rst)
        data_ready <= 1'b0;
    else 
        if(bit_cnt == 'd8 && baud_cnt == baud_cnt_end - 'd1)
            data_ready <= 1'b1;
        else 
            data_ready <= 1'b0;
end


reg [7:0] data_out;
always@(posedge clk )
begin
    if(bit_cnt == 'd8 && baud_cnt == baud_cnt_end - 'd1)
    begin
        data_out1 <= data_out;
        led       <= data_out1;
    end
    else 
        data_out1 <= 8'd0;
end



always@(posedge clk or negedge rst)
begin
    if(rst)
        data_out <= 8'b0;
    else 
        if(rx_flag)
            if(bit_flag)
                case(bit_cnt)
                    4'd1 :    data_out[0]    <=        rx2        ;
                    4'd2 :    data_out[1]    <=        rx2        ;
                    4'd3 :    data_out[2]    <=        rx2        ;
                    4'd4 :    data_out[3]    <=        rx2        ;
                    4'd5 :    data_out[4]    <=        rx2        ;
                    4'd6 :    data_out[5]    <=        rx2        ;
                    4'd7 :    data_out[6]    <=        rx2        ;
                    4'd8 :    data_out[7]    <=        rx2        ;
                    default:data_out  <=     data_out        ;    
                endcase
            else 
                data_out <= data_out;
        else 
            data_out <= 8'd0;
end


//TRY TO DORECTLY ADD TEH 1-32 IN THERE

reg [7:0] byte1;
reg [7:0] byte2;
reg [7:0] byte3;
reg [7:0] byte4;
reg [7:0] byte5;
reg [7:0] byte6;
reg [7:0] byte7;
reg [7:0] byte8;
reg [7:0] byte9;
reg [7:0] byte10;
reg [7:0] byte11;
reg [7:0] byte12;
reg [7:0] byte13;
reg [7:0] byte14;
reg [7:0] byte15;
reg [7:0] byte16;
reg [7:0] byte17;
reg [7:0] byte18;
reg [7:0] byte19;
reg [7:0] byte20;
reg [7:0] byte21; 
reg [7:0] byte22; 
reg [7:0] byte23; 
reg [7:0] byte24; 
reg [7:0] byte25; 
reg [7:0] byte26; 
reg [7:0] byte27; 
reg [7:0] byte28; 
reg [7:0] byte29; 
reg [7:0] byte30;
reg [7:0] byte31;
reg [7:0] byte32;


initial
begin
    byte1=0;
    byte2=0;
    byte3=0;
    byte4=0;
    byte5=0;
    byte6=0;
    byte7=0;
    byte8=0;
    byte9=0;
    byte10=0;
    byte11=0;
    byte12=0;
    byte13=0;
    byte14=0;
    byte15=0;
    byte16=0;
    byte17=0;
    byte18=0;
    byte19=0;
    byte20=0;
    byte21=0;
    byte22=0;
    byte23=0;
    byte24=0;
    byte25=0;
    byte26=0;
    byte27=0;
    byte28=0;
    byte29=0;
    byte30=0;
    byte31=0;
    byte32=0;
end


always@(posedge clk)
begin
if(rst)
    begin
    byte1=0;
    byte2=0;
    byte3=0;
    byte4=0;
    byte5=0;
    byte6=0;
    byte7=0;
    byte8=0;
    byte9=0;
    byte10=0; 
    byte11=0;
    byte12=0;
    byte13=0;
    byte14=0;
    byte15=0;
    byte16=0;
    byte17=0;
    byte18=0;
    byte19=0;
    byte20=0;
    byte21=0;
    byte22=0;
    byte23=0;
    byte24=0;
    byte25=0;
    byte26=0;
    byte27=0;
    byte28=0;
    byte29=0;
    byte30=0;
    byte31=0;
    byte32=0;
    end
else
    if(data_ready)
    begin
    byte1  <=data_out1;
    byte2  <=byte1;
    byte3  <=byte2;
    byte4  <=byte3;
    byte5  <=byte4;
    byte6  <=byte5;
    byte7  <=byte6;
    byte8  <=byte7;
    byte9  <=byte8;
    byte10 <=byte9;
    byte11 <=byte10;
    byte12 <=byte11;
    byte13 <=byte12;
    byte14 <=byte13;
    byte15 <=byte14;
    byte16 <=byte15;
    byte17 <=byte16;
    byte18 <=byte17;
    byte19 <=byte18;
    byte20 <=byte19;
    byte21 <=byte20;
    byte22 <=byte21;
    byte23 <=byte22;
    byte24 <=byte23;
    byte25 <=byte24;
    byte26 <=byte25;
    byte27 <=byte26;
    byte28 <=byte27;
    byte29 <=byte28;
    byte30 <=byte29;
    byte31 <=byte30;
    byte32 <=byte31;
    end
    else
    begin
    byte1  <=   byte1;  
    byte2  <=   byte2;  
    byte3  <=   byte3;  
    byte4  <=   byte4;  
    byte5  <=   byte5;  
    byte6  <=   byte6;  
    byte7  <=   byte7;  
    byte8  <=   byte8;  
    byte9  <=   byte9;  
    byte10 <=   byte10; 
    byte11 <=   byte11; 
    byte12 <=   byte12; 
    byte13 <=   byte13; 
    byte14 <=   byte14; 
    byte15 <=   byte15; 
    byte16 <=   byte16; 
    byte17 <=   byte17; 
    byte18 <=   byte18; 
    byte19 <=   byte19; 
    byte20 <=   byte20; 
    byte21 <=   byte21; 
    byte22 <=   byte22; 
    byte23 <=   byte23; 
    byte24 <=   byte24; 
    byte25 <=   byte25;//PM2.5低八位
    byte26 <=   byte26;//PM2.5高八位
    byte27 <=   byte27;//PM10低八位
    byte28 <=   byte28;//PM10高八位
    byte29 <=   byte29;//帧长度低八位 
    byte30 <=   byte30;//帧长度高八位 
    byte31 <=   byte31;//0x4d=0100_1101 a10b11c12d13
    byte32 <=   byte32;//0x42=0100_0010
    end   
end

reg [15:0]PM25;
always@(posedge clk)
    begin
        if((byte32 == 8'b0100_0010)&&(byte31 == 8'b0100_1101))
            begin
                PM25 [15:8]<= byte26;
                PM25 [7:0] <= byte25;
            end         
     end
ip_disp_final_0 U1(clk,rst,PM25,seg,an);
ila_0 U2(
.clk(clk),
.probe0(rxd),
.probe1(data_out1)
);
endmodule


  • 写回答

1条回答 默认 最新

  • Tokeyman 2021-12-15 00:54
    关注

    用电脑串口助手模拟可以的话,程序应该问题不大,虽然没仔细去仿真,建议LZ用示波器看一下波形,尤其时RXD端的开始那个检测下降沿的地方,检查空闲时刻RXD是否为高电平,同时尝试把nedge那个信号同步引出到output pin,然后和RXD信号用示波器双通道跟踪一下,看看nedge是否在期待的位置。
    感觉大概率时RXD接收这里的问题,有可能传感器TXD端发送完毕数据后设计为输出high-z了。假如时这里的问题的话,input的rxd引荐设置一个weak pull-up register的pin assignment。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 12月23日
  • 已采纳回答 12月15日
  • 创建了问题 12月14日

悬赏问题

  • ¥15 iOS 自定义输入法-第三方输入法
  • ¥15 很想要一个很好的答案或提示
  • ¥15 扫描项目中发现AndroidOS.Agent、Android/SmsThief.LI!tr
  • ¥15 怀疑手机被监控,请问怎么解决和防止
  • ¥15 Qt下使用tcp获取数据的详细操作
  • ¥15 idea右下角设置编码是灰色的
  • ¥15 全志H618ROM新增分区
  • ¥15 在grasshopper里DrawViewportWires更改预览后,禁用电池仍然显示
  • ¥15 NAO机器人的录音程序保存问题
  • ¥15 C#读写EXCEL文件,不同编译