新手上路
- 积分
- 21
- 金钱
- 21
- 注册时间
- 2019-7-27
- 在线时间
- 5 小时
|
3金钱
编写完接受程序后,把接受到的信号写到对应的寄存器中,然后不知道为什么就会清零。这是我写的uart接受的代码:
module RE(
input clk,
input rst_n,
input uart_rxd,
output reg[7:0]data,
output reg uartdone
);
parameter CLK_FREQ=50_000_000;
parameter BPS =115200;
localparam CNT_BPS =CLK_FREQ/BPS; //一帧数据对应多少个时钟周期
reg[7:0] uart_rxd0;
reg[7:0] uart_rxd1;
reg[11:0] cnt_bps;
reg[3:0] cnt_data;
reg read_ctr;
wire flag;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
uart_rxd0<=8'd0;
uart_rxd1<=8'd0;
end
else
begin
uart_rxd0 <= uart_rxd;
uart_rxd1 <= uart_rxd0;
end
end
assign flag = (~uart_rxd0) & uart_rxd1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_bps <= 12'b0;
else
if(read_ctr &&(cnt_bps<12'd22))
cnt_bps <= cnt_bps + 1'b1;
else
cnt_bps <= 12'b0;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_data <= 4'b0;
else if(read_ctr)
begin
if(cnt_bps == (12'd22))
begin
if (cnt_data < 4'd10)
cnt_data <= cnt_data +1;
else
cnt_data <= 4'd0;
end
else
cnt_data <= cnt_data;
end
else
cnt_data <= 4'd0;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
read_ctr <= 1'd0;
data <= 8'd0;
end
else
begin
case(read_ctr)
1'd0: begin
uartdone <= 1'd0;
if(flag)
read_ctr <= 1'd1;
else
read_ctr <= read_ctr;
end
1'd1: begin
case(cnt_data)
4'd0 :data <= 8'd0;
4'd1 :data[0] <= uart_rxd;
4'd2 :data[1] <= uart_rxd;
4'd3 :data[2] <= uart_rxd;
4'd4 :data[3] <= uart_rxd;
4'd5 :data[4] <= uart_rxd;
4'd6 :data[5] <= uart_rxd;
4'd7 :data[6] <= uart_rxd;
4'd8 :data[7] <= uart_rxd;
4'd9 : uartdone <= 1'd1;
4'd10:begin
read_ctr <= 1'd0;
uartdone <= 1'd0;
end
default:;
endcase
end
endcase
end
end
endmodule
它的目的是接受到uart—rxd的信号后把它写到data寄存器里,但不知道为什么接收完之后寄存器会清零,下面是用singal tap 2看到的信号图
|
最佳答案
查看完整内容[请看2#楼]
你这种程序的写法很容易出现亚稳态,导致采集错误的数据。应该在接收每一位数据的中间位置采集一次uart_rxd即可。
|