飞泉

【红色飓风Nano二代测评】串口发送模块

0
阅读(1606)

    串口发送模块的方式设计一个串口的发送模块。在顶层模块中,还调用了按钮模块,实现每次按下一个按钮,发送一个数据到电脑。

    串口模块的状态机设计:

IDLE:顶层控制模块发送了一个信号,通知串口模块发送数据,之后进入发送起始位状态,并且使能波特率发生器
START:这个时候把TXD 输出低电平,持续一个波特率周期
BITO-BIT7:输出需要发送的8bit 数据,每个数据持续一个波特率周期
STOP:由于本设计没有奇偶校验位,因为发送完数据后就发送停止位。把TXD 输出高持续一个波特率周期,之后进入IDLE 状态

代码如下:

module UartTxd (Clk,IsSta,Din,IsDone,Txd);
input Clk; // 时钟是输入
input IsSta; // 外步通知发送数据信号
input [7:0] Din; //需要发送的数据
output IsDone; //发送完成信号
output Txd; // 串口发送数据线
reg IsDone=0;
reg Txd=0;
reg [10:0] C1=0;
reg ClkEn=0;
reg Clkt=0;
always @ (posedge Clk ) //1 倍波特率发生器,波特率为38400;系统时钟50MHZ,分频系
数1302
if( ClkEn ) begin
if( C1< 11'd1301 )begin Clkt <= 11'd0; C1 <= C1 + 1'b1; end
else begin Clkt <= 1'b1; C1 <= 11'd0; end
end
else begin Clkt <= 1'b0; C1 <= 11'd0; end
reg IsSta1=0,IsSta2=0;
always @ (posedge Clk) begin //外部输入信号2 次寄存,消除亚稳态
IsSta1<=IsSta;IsSta2<=IsSta1;
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;
assign TxdUp = IsSta1 & (!IsSta2);
always @(posedge Clk) begin
case (s)
IDLE: //如果有需要发送的数据,寄存需要发送的数据,然后发送BIT0
begin
IsDone<=0;ClkEn<=0;Txd <=1;
if( TxdUp ) begin ClkEn<=1; s <= s +1'b1;end
end
START:
if( Clkt )begin Txd <=0;s <= s +1'b1;end
BIT0: //发送BIT0
if( Clkt )begin Txd <=Din[0];s <= s +1'b1;end
BIT1: //发送BIT1
if( Clkt )begin Txd <=Din[1];s <= s +1'b1;end
BIT2: //发送BIT2
if( Clkt )begin Txd <=Din[2];s <= s +1'b1;end
BIT3: //发送BIT3
if( Clkt )begin Txd <=Din[3];s <= s +1'b1;end
BIT4: //发送BIT4
if( Clkt )begin Txd <=Din[4];s <= s +1'b1;end
BIT5: //发送BIT5
if( Clkt )begin Txd <=Din[5];s <= s +1'b1;end
BIT6: //发送BIT6
if( Clkt )begin Txd <=Din[6];s <= s +1'b1;end
BIT7: //发送BIT7
if( Clkt )begin Txd <=Din[7];s <= s +1'b1;end
STOP: //发送停止为,之后转为状态0
if( Clkt )begin Txd <=1;s <= 0;IsDone<=1;end
default: s<=0;
endcase
end
endmodule


顶层模块:

module main(Clk,Txd,Sw1);
input Clk;
output Txd;
input Sw1;
wire Sw_IsDwon;
reg [7:0] Din =0;// 串口模块需要发送的数据
always @(posedge Clk)begin // 按钮每次按下一次后Din 加1
if(Sw_IsDwon) Din <= Din + 1'b1;
end
Button U0 (.Clk(Clk),.Sw(Sw1),.Sw_IsDwon(Sw_IsDwon)); //对按钮模块的封装
UartTxd U1 (.Clk(Clk),.IsSta(Sw_IsDwon),.IsDone(IsDone),.Din(Din),.Txd(Txd));
//send
endmodule

每个按钮的按下触发信号Sw_IsDwon 有效时,数据Din 自加1 ,由于按钮按下Sw_IsDwon触发信号连线到了串口发送模块的IsSta 信号,所以每次按下按钮后,也同时触发了串口的发送模块发送数据。

 实验数据如下: