uart串口接收模块的问题
大家好:
我弄了一个uart接收模块,但是有问题,接收不到数据,看了好多遍还是找不出问题,不知道问题出在哪里?
各位帮帮忙啊,代码如下
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 16:25:45 04/14/2010
// Design Name:
// Module Name: uart_rev
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module uart_rev(
iclk,
irstx,
irxd,
odata,
oreceived_char
);
input iclk;
input irstx;
input irxd;
output [7:0]odata;
output oreceived_char;
reg rg_rxd;
reg [13:0]counter;
reg [3:0]rev_bits_count;
reg [7:0]odata;
reg rg_rev_check;
reg oreceived_char;
reg [3:0]CS,NS;
wire w_clk;
parameter IDLE=4'b0000,
START=4'b0001,
REV_BIT=4'b0010,
REV_CHECK=4'b0100,
REV_STOP=4'b1000;
parameter DELAY_COUNT=14'b01_0100_0101_0110;//'d5206
parameter BITS_PER_CHAR=3'b110; //'d6
//generate the slow clock
always@(posedge iclk or negedge irstx)begin
if(~irstx)
counter<=14'b0;
else
begin
if(w_clk)
counter<=14'b0;
else
counter<=counter+1'b1;
end
end
assign w_clk=(counter==DELAY_COUNT);
always@(posedge iclk or negedge irstx)begin
if(~irstx)
rg_rxd<=1'b1;
else
rg_rxd<=irxd;
end
//the state register
always@(posedge w_clk or negedge irstx)begin
if(~irstx)
CS<=IDLE;
else
CS<=NS;
end
//the combinational logic
always@(*)begin
case(CS)
IDLE:if(~rg_rxd) NS=START;
START:NS=REV_BIT;
REV_BIT:if(rev_bits_count[3])NS=REV_CHECK;//8 cycles, 1 byte
REV_CHECK:NS=REV_STOP;
REV_STOP:NS=IDLE;
default:NS=IDLE;
endcase
end
always@(posedge w_clk or negedge irstx)begin
if(~irstx)
rev_bits_count<=BITS_PER_CHAR;
else
if(CS==IDLE)
rev_bits_count<=BITS_PER_CHAR;
else
if(CS==REV_BIT)
rev_bits_count<=rev_bits_count-1'b1;
else
rev_bits_count<=rev_bits_count;
end
always@(posedge w_clk or negedge irstx)begin
if(~irstx)
odata<=8'b0;
else
if(CS==IDLE)
odata<=8'b0;
else
if(CS==REV_BIT)
odata[7:0]<={rg_rxd,odata[7:1]};//右移一位
else
odata<=odata;
end
always@(posedge w_clk or negedge irstx)begin
if(~irstx)
rg_rev_check<=1'b0;
else if(CS==IDLE)
rg_rev_check<=1'b0;
else if(CS==REV_CHECK)
rg_rev_check<=rg_rxd;
else
rg_rev_check<=rg_rev_check;
end
always@(posedge w_clk or negedge irstx)begin
if(~irstx)
oreceived_char<=1'b0;
else if(CS==IDLE)
oreceived_char<=1'b0;
else if(CS==REV_CHECK)
oreceived_char<=1'b1;
else
oreceived_char<=1'b0;
end
endmodule
重新看UART协议吧,然后仿真看对不对
看不大懂··如果你要是VHDL的模块我能帮你解决的。
对了,收不到数据的话你可以看下数据输入以及接收数据之前的条件是否成立,然后一步一步往下查···还有个可能就是你发送和接收数据的波特率是否一致。
我弄了一下仿真,按照那个协议,rxd先给个低信号,然后再给数据,从波形图上看,状态转换正常,odata的值也有,但是下载到板子上就是不行
4# emakltuz 波特率都是按9600弄的,应该不会有问题
那你可以查下你的输入信号也就是接收的数据对么?仿真的时候有个低电平起始位的话,那你实际板子上的输入数据对吗?
7# emakltuz 我用“串口调试助手”输入数据,原来有一个接收模块,可以正确接收,只是代码看起来有点乱。
所以自己重新弄一个,现在这个模块基本上是按照那个模块的思路弄的
8# picassoye
首先确定两点,一就是你用别人的模块可以接收,那说明硬件方面没有问题;二就是UART模块一般都是来数据就接收了,你收不到说明你接收部分的状态机没有跳转,状态机的跳转需要的条件你是否符合,必要的时候你可以把他们引出来,还可以把状态机的状态编码引出来看停止在哪个状态。你自己可以仔细查查逻辑是否有遗漏的地方。我刚刚又尝试着看了下你的逻辑,很多语法都不大懂,SORRY了。
你原来的模块就是这样的思路?没有高倍率采样你怎么采得到正确的信号?你写的和UART的要求的差距很大
呵呵,谢谢你了,我再仔细看看
你说的有道理!
原来那个模块是开发板自带的代码,也没有采样,可能数据的准确率会有问题
我想先把功能实现了,然后再加进去数据采样的部分
原来这个模块是这样的,我用这个模块试了一下没问题,从仿真来看,感觉区别就是它的输出比改了以后的模块提前了半个多周期
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 14:53:51 04/15/2010
// Design Name:
// Module Name: rev
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module rev(
rst,
clk50,
rxd,
odata,
received_char
);
input rst;
input clk50;
input rxd;
output [7:0]odata;
output received_char;
reg rxd_reg;
reg [7:0]rev_char;
reg rev_check;
reg [2:0] REV_state;
reg [3:0] rev_bits_count;
reg [13:0] REV_counter;
reg received_char;
parameter DELAYCOUNT= 14'b01_0100_0101_0110; //5206+1+1=5208
parameter BITS_PER_CHAR=3'b110; //6+1+1=8
parameter REV_IDLE=3'b000,
REV_START=3'b001,
REV_BIT=3'b010,
REV_CHECK=3'b101,
REV_STOP=3'b100;
assign odata=rev_char;
always @ (posedge clk50)
begin
if(~rst)
begin
rxd_reg<=1;
end
else
begin
rxd_reg<=rxd;
end
end
//state machine
always @ (posedge clk50)
if(~rst)
begin
rev_char<=8'b0;
REV_counter<=DELAYCOUNT;
REV_state<=REV_IDLE;
rev_bits_count<=BITS_PER_CHAR;
received_char<=0;
end
else
case(REV_state)
REV_IDLE: begin
REV_counter<=DELAYCOUNT;
rev_bits_count<=BITS_PER_CHAR;
received_char<=0;
rev_check<=0;
rev_char<=8'b0;
if(~rxd_reg)
begin
REV_state<=REV_START;
end
end
REV_START: begin
if(REV_counter[13])
begin
REV_state<=REV_BIT;
REV_counter<=DELAYCOUNT;
end
else
REV_counter<=REV_counter-1;
end
REV_BIT: begin
if(REV_counter[13])
begin
REV_state<=REV_BIT;
REV_counter<=DELAYCOUNT;
if(rev_bits_count[3])
begin
REV_state<=REV_CHECK;
REV_counter<=DELAYCOUNT;
end
else
rev_bits_count<=rev_bits_count-1;
end
else
REV_counter<=REV_counter-1;
if(REV_counter==2500)
begin
rev_char[7:0]<={rxd_reg,rev_char[7:1]};
end
end
REV_CHECK: begin
if(REV_counter[13])
begin
REV_state<=REV_STOP;
REV_counter<=DELAYCOUNT;
received_char<=1;
end
else
REV_counter<=REV_counter-1;
if(REV_counter==2500)
begin
rev_check<=rxd_reg;
end
end
REV_STOP: begin
received_char<=0;
if(REV_counter[13])
begin
REV_state<=REV_IDLE;
REV_counter<=DELAYCOUNT;
end
else
REV_counter<=REV_counter-1;
end
default:
REV_state<=REV_IDLE;
endcase
endmodule
13# picassoye 哪位高人帮我看看
你有没有写的好一点的模块?贴一个我学习学习
邦定了
where...?
仿真才好快速分析,网上下的不要钱的东东多数是这样的,这样才能防什么也不会的人,盗取技术人员的利益,建义大家开放原代码时都这样做,说实话,我网上下过不少代码,有点知识,分析一下,多数好解决,防就是防什么也不会的人的.
仿真正确的话,就得考虑电器特性的问题了。
你用示波器看看,RX\TX端的信号与仿真波形是否一致。
为何不写成一级状态机,起始位数据位,校验位和停止位都在一个always里接收呢.
是没有没有高倍率采样,不知道是怎么采数的
向UART接口这种慢速接口协议最好还是做个滤波,因为你的眼跳变可能都要比你的时钟周期长的
这样能保证接入的数据是正确的,
剩下的就是注意采样要在数据的中间采样,保证数据的正确性,
能加个testbench方个仿真图上来吗这样好分析
下到板子上用signaltap看看那里除了问题。
看起来 貌似和我的问题是一样的,不知道那位大侠 可以解释原因
1# picassoye
如果你认为自己理解的协议和代码实现,仿真都没有问题的话,可否把实际信号测量出来看看逻辑是否和自己设想的一样。
如果不一样,可能是你自己的语法导致实现与仿真不一致;
如果一样,可能是对协议理解有问题,可否找台带UART协议的示波器或者逻辑分析仪测试一下?
也有可能是波特率什么的设置有问题;
也有可能主机串口设置或者电学上有问题;
一个一个排除好了。
谢谢大家的热心帮助
我找到了一个比较好的网站,讲串口的,但没有在板子上试过,贴上来一起研究研究
http://www.fpga4fun.com/SerialInterface.html
先问一下,是收不到数据,还是数据接受错误。
28# mosou 改了接收模块后出问题, 应该是接收模块的问题
chipscope或者其他的fpga的工具在板子上运行的时候down一下内部的波形,再找原因。
让我们帮你分析你的code,首先大家没那时间,也没那精力,只能给你提点建议啊之类的
