原创 串口接收 V8

2012-7-24 15:21 929 10 10 分类: FPGA/CPLD

 

/**
  ******************************************************************************
  * @file     rx_rs232_v8.v
  * @author   西殿源
  * @version  V8
  * @date     07/20/2012
  * @brief    RS232串口接收模块
  * @info  1. 合并检测模块
     2. 规范端口名,变量名,代码风格
     3. 状态机分段处理
  ******************************************************************************
  */


module rx_rs232_v8(
 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_samp,
// 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_samp;
 reg [8:0] baud_cnt;   //
 reg [3:0] sample_cnt;  //
 reg [3:0] bit_cnt;
// 
 
 reg [2: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_samp = ( (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_samp) 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 ;
   end
  else ***_ro <= NO;
 end
 
 
// //  修改后后之方案二 (稳定) 
 always @(clk_samp) begin
  if(sample_cnt == 4'd9) begin
   if(bit_reg_in1+bit_reg_in2+rx_in>1) data_temp[bit_cnt] = 1'b1;
   else data_temp[bit_cnt] = 1'b0;
   end
  else ;
 end
 
////    修改后之方案一  (稳定)
//  case(sample_cnt)
//   7 : weig_cnt[2] = rx_in;
//   8 : weig_cnt[1] = rx_in;
//   9 : weig_cnt[0] = rx_in;
//   14 : begin
//    
//    if((weig_cnt[2]+ weig_cnt[1]+weig_cnt[0])> 1) data_temp[bit_cnt] = 1'b1;
//    else data_temp[bit_cnt] = 1'b0;
//    end
//   default : ;
//  endcase
// end
// 
////  修改前 (不稳定) 
//  case(sample_cnt)
//   7 : weig_cnt = rx_in;
//   8 : weig_cnt = weig_cnt + rx_in;
//   9 : weig_cnt = weig_cnt + rx_in;
//   15 : begin
//    
//    if(weig_cnt> 1) data_temp[bit_cnt] = 1'b1;
//    else data_temp[bit_cnt] = 1'b0;
//    end
//   default : ;
//  endcase
// end
 
 
 
endmodule


 
 
 
 
 
 
 
 
 
 
 

PARTNER CONTENT

文章评论0条评论)

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