首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于Verilog下的串口通信实验(转)(2)

基于Verilog下的串口通信实验(转)(2)

http://blog.sina.com.cn/s/blog_6202cb4101010cc3.html
//================================数据接收模块==========================================module uart_rx(
     clk,
     rst_n,
     bps_start,
     clk_bps,
     rs232_rx,
     rx_data,
     rx_int,
     led
     );
inputclk;   //时钟
inputrst_n;  //复位
inputrs232_rx; //接收数据信号
inputclk_bps;  //高电平时为接收信号中间采样点
outputbps_start; //接收信号时,波特率时钟信号置位
output [7:0] rx_data;//接收数据寄存器
outputrx_int;  //接收数据中断信号,接收过程中为高
output [7:0] led;
reg [7:0] led;
regrs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;//接收数据寄存器
wire neg_rs232_rx;//表示数据线接收到下沿

always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
   rs232_rx0<= 1'b0;
   rs232_rx1<= 1'b0;
   rs232_rx2<= 1'b0;
   rs232_rx3<= 1'b0;
  end
  
  else begin
   rs232_rx0<= rs232_rx;
   rs232_rx1<= rs232_rx0;
   rs232_rx2<= rs232_rx1;
   rs232_rx3<= rs232_rx2;
  end
end
assign neg_rs232_rx = rs232_rx3& rs232_rx2 & ~rs232_rx1& ~rs232_rx0;//串口传输线的下沿标志
reg bps_start_r;
reg [3:0] num;//移位次数
regrx_int;  //接收中断信号

always @(posedge clk or negedgerst_n)
  if(!rst_n)begin
   bps_start_r<=1'bz;
   rx_int<= 1'b0;
  end
  elseif(neg_rs232_rx) begin//
  bps_start_r<=1'b1;  //启动串口,准备接收数据
   rx_int<=1'b1;   //接收数据中断使能
  end
  elseif(num==4'd12) begin //接收完有用的信号,
   bps_start_r<=1'b0;  //接收完毕,改变波特率置位,方便下次接收
   rx_int<=1'b0;   //接收信号关闭
  end
  
  assign bps_start= bps_start_r;
  
  reg [7:0]rx_data_r;//串口数据寄存器
  reg [7:0]rx_temp_data;//当前数据寄存器
  
  always @(posedgeclk or negedge rst_n)
   if(!rst_n)begin
     rx_temp_data<= 8'd0;
     num<= 4'd0;
     rx_data_r<= 8'd0;
   end
   elseif(rx_int) begin //接收数据处理
    if(clk_bps)begin
     num<= num+1'b1;
     case(num)
       4'd1:rx_temp_data[0] <= rs232_rx;
       4'd2:rx_temp_data[1] <= rs232_rx;
       4'd3:rx_temp_data[2] <= rs232_rx;
       4'd4:rx_temp_data[3] <= rs232_rx;
       4'd5:rx_temp_data[4] <= rs232_rx;
       4'd6:rx_temp_data[5] <= rs232_rx;
       4'd7:rx_temp_data[6] <= rs232_rx;
       4'd8: rx_temp_data[7]<= rs232_rx;
       default:;
     endcase
     led<= rx_temp_data;
    end
    elseif(num==4'd12) begin
     num<=4'd0;   //数据接收完毕
     rx_data_r<= rx_temp_data;
    end         
   end
  assign rx_data =rx_data_r;
endmodule
//=================================数据发送模块=========================================
module uart_tx(
     clk,
     rst_n,
     bps_start,
     clk_bps,
     rs232_tx,
     rx_data,
     rx_int
    );

input clk;
input rst_n;
input clk_bps;//中间采样点
input [7:0] rx_data;//接收数据寄存器
input rx_int;//数据接收中断信号
output rs232_tx;//发送数据信号
output bps_start;//发送信号置位

regrx_int0,rx_int1,rx_int2;//信号寄存器,捕捉下降沿
wireneg_rx_int;    //下降沿标志

always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
   rx_int0<= 1'b0;
   rx_int1<= 1'b0;
   rx_int2<= 1'b0;
  end
  else begin
   rx_int0 <= rx_int;
   rx_int1 <= rx_int0;
   rx_int2 <= rx_int1;
  end
end

  assign neg_rx_int= ~rx_int1 & rx_int2;//捕捉下沿
  
  reg [7:0]tx_data;//待发送数据
  regbps_start_r;
  regtx_en;//发送信号使能,高有效
  reg [3:0]num;

always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
   bps_start_r<= 1'bz;
   tx_en<= 1'b0;
   tx_data<= 8'd0;
  end
  elseif(neg_rx_int) begin//当检测到下沿的时候,数据开始传送
   bps_start_r<= 1'b1;
   tx_data<= rx_data;
   tx_en<= 1'b1;
  end
  elseif(num==4'd11) begin
   bps_start_r<= 1'b0;
   tx_en<= 1'b0;
  end
end

assign bps_start = bps_start_r;

reg rs232_tx_r;
always @(posedge clk or negedge rst_n)begin
  if(!rst_n)begin
   num<=4'd0;
   rs232_tx_r<= 1'b1;
  end
  else if(tx_en)begin
   if(clk_bps)begin
    num<=num+1'b1;
    case(num)
      4'd0:rs232_tx_r <= 1'b0;//起始位
      4'd1:rs232_tx_r <= tx_data[0];//数据位 开始
      4'd2:rs232_tx_r <= tx_data[1];
      4'd3:rs232_tx_r <= tx_data[2];
      4'd4:rs232_tx_r <= tx_data[3];
      4'd5:rs232_tx_r <= tx_data[4];
      4'd6:rs232_tx_r <= tx_data[5];
      4'd7:rs232_tx_r <= tx_data[6];
      4'd8:rs232_tx_r <= tx_data[7];
      4'd9:rs232_tx_r <= 1'b1;//数据结束位,1位
      default:rs232_tx_r <= 1'b1;
    endcase
   end
   elseif(num==4'd11)
    num<=4'd0;//发送完成,复位
  end
end
assign rs232_tx =rs232_tx_r;
endmodule
继承事业,薪火相传
返回列表