分享

串口发送模块

 ruguoyouyuan 2014-02-21
module Uart_tr(
Sys_clk,  //全局时钟
Sys_reset,//全局复位
//Tx_Clk,   //发送模块接收波特率
Rc_Date, //输入,接收并行8位数据
Tx_Start,//输入,传输开始使能
Tx_out,  //输出,数据输出
Tx_busy, //输出,传输忙标志
Tx_ready,//准备好标志
Tx_Clk   //波特率时钟
);
input Sys_clk,Sys_reset;
input [7:0] Rc_Date;
input Tx_Start;
output Tx_out;
output Tx_busy;
output Tx_ready;
output Tx_Clk;
reg Tx_out_r;
//reg Tx_out;
//reg Tx_busy;
reg  [3:0] state;
reg [7:0] Rc_Dater;
parameter idle=4'b0000;
parameter startbite=4'b1001;  //开始位
parameter bite0=4'b0001; //bite0
parameter bite1=4'b0010; //bite1
parameter bite2=4'b0011; //bite2
parameter bite3=4'b0100; //bite3
parameter bite4=4'b0101; //bite4
parameter bite5=4'b0110; //bite5
parameter bite6=4'b0111; //bite6
parameter bite7=4'b1000; //bite7
parameter stopbite1=4'b1010;//停止位1 
parameter stopbite2=4'b1011;//停止位2
wire Tx_ready=(state==idle); //状态空闲时准备好
assign  Tx_busy=~Tx_ready; //空闲时Tx_busy=0
//波特率产生1
parameter  ClkFrequency = 25000000;  // 时钟频率-25 MHz
parameter  Baud = 115200;            // 串口波特率-115200 
parameter BaudGeneratorAccWidth = 16;
reg       [BaudGeneratorAccWidth:0] BaudGeneratorAcc;
wire [BaudGeneratorAccWidth:0] BaudGeneratorInc =((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4);
wire Tx_Clk = BaudGeneratorAcc[BaudGeneratorAccWidth];
always @(posedge Sys_clk or negedge Sys_reset)
   if(~Sys_reset)
      BaudGeneratorAcc <= 0;
 else if(Tx_busy) //关键的一句使Tx_Clk与Rc_Dater同步
    BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc;
 
// 接收缓存的处理
always@(posedge Sys_clk or negedge Sys_reset) 
      if(!Sys_reset) Rc_Dater=8'b00000000;
else if(Tx_Start&Tx_ready)
      Rc_Dater=Rc_Date; 
//主程序
always@(posedge Sys_clk or negedge Sys_reset) begin
        if(!Sys_reset)begin Tx_out_r=1'b1;
                     state=idle;         //注意state要初始化
// Tx_Start=0;
 end
// else if(Tx_Start) begin   //注意错误,Tx_start只是一个开始信号,如总线从1变到零的下降沿
//         case(state)
//     idle:state<=bite0
 else begin
      case(state[3:0])
     idle:if(Tx_Start) state<=startbite;
startbite:if(Tx_Clk) begin state<=bite0; Tx_out_r=1'b0;end
 bite0:if(Tx_Clk) begin state<=bite1; Tx_out_r=Rc_Dater[0];end
 bite1:if(Tx_Clk) begin state<=bite2; Tx_out_r=Rc_Dater[1];end
 bite2:if(Tx_Clk) begin state<=bite3; Tx_out_r=Rc_Dater[2];end
 bite3:if(Tx_Clk) begin state<=bite4; Tx_out_r=Rc_Dater[3];end
 bite4:if(Tx_Clk) begin state<=bite5; Tx_out_r=Rc_Dater[4];end
 bite5:if(Tx_Clk) begin state<=bite6; Tx_out_r=Rc_Dater[5];end
 bite6:if(Tx_Clk) begin state<=bite7; Tx_out_r=Rc_Dater[6];end
 bite7:if(Tx_Clk) begin state<=stopbite1; Tx_out_r=Rc_Dater[7];end
      stopbite1:if(Tx_Clk) begin state<=stopbite2; Tx_out_r=1'b1;end
   stopbite2:if(Tx_Clk) begin state<=idle;          Tx_out_r=1'b1;end
  default:if(Tx_Clk) state<=idle;
endcase
end
end
   
 
assign Tx_out=Tx_out_r;//注意不要忘了assign
endmodule 
 

txtbench:
module Uart_tr_vlg_tst();
reg [7:0] Rc_Date;
reg Sys_clk;
reg Sys_reset;
reg Tx_Start;
// wires                                               
wire Tx_busy;
wire Tx_out;  
wire Tx_ready; 
reg [7:0] Rc_dater;                    
Uart_tr i1 (
.Rc_Date(Rc_Date),
.Sys_clk(Sys_clk),
.Sys_reset(Sys_reset),
.Tx_Start(Tx_Start),
.Tx_busy(Tx_busy),
.Tx_out(Tx_out),
.Tx_ready(Tx_ready),
.Tx_Clk(Tx_Clk)
);
parameter SysClkCycle=40;
initial                                                
begin                                                  
Sys_clk=0;
Sys_reset=0;
Tx_Start=1;
Rc_Date=8'b0; 
#(SysClkCycle*2) Sys_reset=1;
#(SysClkCycle*2) Tx_Start=0;
#(SysClkCycle*2) Tx_Start=1;
# (SysClkCycle*900000) $stop;                  
end                                                    
always        
begin                                                  
#(SysClkCycle/2) Sys_clk<=~Sys_clk;  
                                         
end
always@(posedge Tx_ready)  Rc_Date<=Rc_Date+1;
endmodule

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多