飞泉

【红色飓风Nano二代测评】串口接受模块设计

0
阅读(1891)

接收解码是对串口接收数据线的采样,这里采样时钟设置为16 倍的波特率。

接收模块采样分频系数=系统时钟/波特率/16-1

本设计采用38400 波特,系统时钟50MHZ 因此80=50000000/38400/16-1

状态机的设计:

IDLE:当采样到Rxd从高电平变为低电平后表示有起始位
START:等待一个波特率周期,是起始位持续时间
BITO-BIT7:采样需要接收的8bit 数据,每个数据持续一个波特率周期,采样在中间采样一次(这种方法抗干扰能力差,特别是工业场合)
STOP:由于本设计没有奇偶校验位,因为接收完数据后就接收停止位。等待一个波特率周期,之后进入IDLE 状态

module UartRxd (Clk,Dout,IsDone,Rxd);
input Clk; // 时钟是输入
output [7:0] Dout;//接收的数据
output IsDone;//接收完成信号
input Rxd;// 串口接收数据线
reg IsDone=0;
reg [7:0]Dout=0;
reg [6:0] C1=0;
reg ClkEn=0;
reg Clkt=0;
always @ (posedge Clk ) begin
if( ClkEn ) begin
if( C1< 7'd80 )begin Clkt <= 7'd0; C1 <= C1 + 1'b1; end
else begin Clkt <= 1'b1; C1 <= 7'd0; end
end
else begin Clkt <= 1'b0; C1 <= 7'd0; end
reg Rxd1=0,Rxd2=0;
always @ (posedge Clk) begin 
Rxd1<=Rxd;Rxd2<=Rxd1;
end
parameter IDLE = 0;//空闲状态
parameter START= 1;// 起始位状态
parameter BIT0 = 2;//发送数据BIT0
parameter BIT1 = 3;//发送数据BIT1
parameter BIT2 = 4;//发送数据BIT2
parameter BIT3 = 5;//发送数据BIT3
parameter BIT4 = 6;//发送数据BIT4
parameter BIT5 = 7;//发送数据BIT5
parameter BIT6 = 8;//发送数据BIT6
parameter BIT7 = 9;//发送数据BIT7
parameter STOP = 10;//发送停止位
reg [3:0]s=0;
reg [4:0]C2=0;
always @(posedge Clk) begin
case (s)
IDLE: 
begin
IsDone <= 0;ClkEn <= 0;C2 <= 0;
if( !Rxd2 ) begin ClkEn<=1; s <= s +1'b1;end
end
START://起始位
begin
if( Clkt ) C2 <= C2+1;
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end 
end
BIT0: //接收BIT0
begin
if( Clkt ) C2 <= C2+1;
if(C2 == 8) Dout[0]=Rxd2;//中间采样一次
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end
end
BIT1: //接收BIT1
begin
if( Clkt ) C2 <= C2+1;
if(C2 == 8) Dout[1]=Rxd2;//中间采样一次
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end
end
BIT2: //接收BIT2
begin
if( Clkt ) C2 <= C2+1;
if(C2 == 8) Dout[2]=Rxd2;//中间采样一次
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end
end
BIT3: //接收BIT3
begin
if( Clkt ) C2 <= C2+1;
if(C2 == 8) Dout[3]=Rxd2;//中间采样一次
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end
end
BIT4: //接收BIT4
begin
if( Clkt ) C2 <= C2+1;
if(C2 == 8) Dout[4]=Rxd2;//中间采样一次
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end
end
BIT5: //接收BIT5
begin
if( Clkt ) C2 <= C2+1;
if(C2 == 8) Dout[5]=Rxd2;//中间采样一次
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end
end
BIT6: //接收BIT6
begin
if( Clkt ) C2 <= C2+1;
if(C2 == 8) Dout[6]=Rxd2;//中间采样一次
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end
end
BIT7: //接收BIT7
begin
if( Clkt ) C2 <= C2+1;
if(C2 == 8) Dout[7]=Rxd2;//中间采样一次
if(C2 > 15) begin C2 <=0; s <= s +1'b1;end
end
STOP: 
begin
if( Clkt ) C2 <= C2+1;
if(C2 > 15) begin IsDone<=1; s <= s +1'b1;end
end
default: s<=0;
endcase
end
endmodule