原创 串口接收 V6

2012-7-24 15:18 955 10 10 分类: FPGA/CPLD

/**
  ******************************************************************************
  * @file     rx_rs232_v6.v
  * @author   西殿源
  * @version  V6
  * @date     07/20/2012
  * @brief    RS232串口接收模块
  * @info  1. 合并检测模块
     2. 规范端口名,变量名,代码风格
     3. 稳定
  ******************************************************************************
  */


module rx_rs232_v6(
 output reg[7:0] dat_ro,  //串行接收,并行输出
 output reg ***_ro,   //接收成功标志,脉宽一个clk周期
// output reg bit_reg_in1,
// output reg bit_reg_in2,
// output reg bit_reg_in3,
// output reg bit_reg_in4,
// output reg chk_en,
// output reg samp_en,
// output star_chk,
// output flag_start,
// output clk_w,
// output reg [8:0] baud_cnt,
// output reg [3:0] sample_cnt,
// output reg [3:0] bit_cnt,
 input clk,      //输入时钟,1MZ
 input rst_n,     //低电平复位
 input rx_in      //串行数据输入
 );

 parameter START = 4'd0;
 parameter DAT0  = 4'd1;
 parameter DAT1  = 4'd2;
 parameter DAT2  = 4'd3;
 parameter DAT3  = 4'd4;
 parameter DAT4  = 4'd5;
 parameter DAT5  = 4'd6;
 parameter DAT6  = 4'd7;
 parameter DAT7  = 4'd8;
 parameter VRFY  = 4'd9;
 parameter STOP  = 4'd10;
 parameter FLAG  = 4'd11;
 parameter IDLE  = 4'd12;
 parameter YES  = 1'b1;
 parameter NO  = 1'b0;
 parameter BAUD = 9600;
 parameter XTAL = 1000000;
 
 //////////flag/////////
 reg bit_reg_in1;//输入缓冲级
 reg bit_reg_in2;//输入缓冲级
 reg bit_reg_in3;//输入缓冲级
 reg bit_reg_in4;//输入缓冲级
 reg chk_en;
 reg samp_en;
 wire star_chk;
 wire flag_start;
 wire clk_w;
 reg [8:0] baud_cnt;   //
 reg [3:0] sample_cnt;  //
 reg [3:0] bit_cnt;
// 
 
 reg [1:0] weig_cnt;
 
 reg [9:0] data_temp;
 
 
 /////////////////波特率相关//////////////
 reg verify_reg;
 parameter baud_para = 5;//324 325
 reg baud_adj;
 
 
 //每比特采16个点
 always @(posedge clk,negedge rst_n) begin
  if(!rst_n) begin
   baud_adj<=0;
   baud_cnt<=0;
   end
  else if(baud_cnt==baud_para+baud_adj) begin
   baud_adj<=~baud_adj;
   baud_cnt<=0;
   end
  else begin
   baud_cnt<=baud_cnt+9'b1;
   end
 end
    
 //串口协议,启动位检测
 
 //检测启动位 1100
 assign star_chk=((~bit_reg_in1)&(~bit_reg_in2)&bit_reg_in3&bit_reg_in4)? YES:NO;
 
 //使能位采样,仅在当前位总线空闲且检测到启动位时使能,脉宽一个clk周期
 assign flag_start=((chk_en==YES)&&(star_chk==YES)&&(baud_cnt==1))? YES:NO;
        //忽略启动?   //下降沿检测,仅
              //维持一个clk周期
 
 
 //采样时钟,脉宽一个clk周期,脉间距6-7个clk周期
 assign clk_w = ( (baud_cnt==2) && (samp_en==YES) );
 
 always @(posedge clk,negedge rst_n) begin
  if(!rst_n) begin
   chk_en <= YES;   //使能启动位检测
   samp_en <= NO;   //除能信号采样
   end
  else if(flag_start) begin
   chk_en <= NO;  //忽略启动位检测
   samp_en <= YES;  //使能信号采样
   end
  else if(***_ro == YES) begin
   chk_en <= YES;
   samp_en <= NO;
   end
  else if(baud_cnt == 0) begin
   bit_reg_in1<=rx_in;
   bit_reg_in2<=bit_reg_in1;
   bit_reg_in3<=bit_reg_in2;
   bit_reg_in4<=bit_reg_in3;
   end
  else ;
 end
 
 always @(posedge clk,negedge rst_n) begin
  if(!rst_n) begin
   data_temp <= 10'd0;
   ***_ro <= NO;
   dat_ro <= 8'd0;
   end
  else if(flag_start) begin
   sample_cnt <= 4'd1;
   bit_cnt <= 4'd0;
   end
  else if(clk_w) begin
   sample_cnt <= sample_cnt + 4'd1;
   if(sample_cnt == 4'd15) begin
    if(bit_cnt == 4'd9) begin
     ***_ro <= YES;
     dat_ro <= data_temp[8:1];
     end
    else bit_cnt <= bit_cnt + 4'd1;
    end
   else ;
   case(sample_cnt)
    7 : weig_cnt <= rx_in;
    8 : weig_cnt <= weig_cnt + rx_in;
    9 : weig_cnt <= weig_cnt + rx_in;
    14 : begin
     if(weig_cnt > 1) data_temp[bit_cnt] <= 1'b1;
     else data_temp[bit_cnt] <= 1'b0;
     end
    default : ;
   endcase
   end
  else ***_ro <= NO;
 end
 
endmodule


 
 
 
 
 
 
 
 
 
 
 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
10
关闭 站长推荐上一条 /3 下一条