FPGA入门串口接收

FPGA串口接收

在Quartus II中,使用In system sources and probes editor工具,查看由PC端发送到UART接收模块接收到的数据.

串口接收模块

在这里插入图片描述
Rs232_rx为PC端发送给FPGA的数据,Data将发送的数据提供给电脑查看。Bps_set选择波特率。
将接收到的数据每一字节分为16份,读取中间6位的和,大于3的字节为1,小于3的字节为0。
在这里插入图片描述
将UART_TX模块加入到uart_data_rx工程中。

module UART_RX(  //串口接收模块
  Clk,
  Rst_n,
  Rs232_rx,
  Bps_set,
  
  Data_out,
  Done_rx
);

input Clk;
input Rst_n;
input Rs232_rx;
input [2:0]Bps_set;
output reg [7:0]Data_out;
output reg Done_rx;

reg [8:0]bps_max;//计数值
reg  now_reg0,rs232_rx_now;  //同步寄存器  消除亚稳态
reg  data_reg0,data_reg1;  //数据寄存器 判断高低电平
wire  low;
reg en_data;
reg  [8:0]bps_con; //bps_clk时钟计数器
reg bps_clk;
reg [7:0]bps_count;
reg [2:0]Data[7:0];   //共有8个Data数据每一个Data数据有3位 例如110
reg [2:0]start_bite;
reg [2:0]stop_bite;

//查找表选择计数值
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n)
  bps_max <= 9'b0;
 else begin
   case(Bps_set)
	 0: bps_max <= 9'd324;           //波特率9600
	 1: bps_max <= 9'd162;           //波特率19200
	 2: bps_max <= 9'd80;            //波特率38400
	 3: bps_max <= 9'd53;            //波特率57600
	 4: bps_max <= 9'd26;            //波特率115200
    default : bps_max <= 9'd324;
   endcase
 end
   //消除亚稳态
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n) begin
  now_reg0 <= 0;  
  rs232_rx_now <= 0;
end
 else begin
    now_reg0 <=  Rs232_rx;
    rs232_rx_now <= now_reg0;
 end 
 
//判断低电平
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n) begin
  data_reg0 <= 0;
  data_reg1 <= 0;
 end 
   else  begin  
  	 data_reg0 <= rs232_rx_now;
    data_reg1 <= data_reg0;     	
end
 	 
assign low = !data_reg0 & data_reg1;
//使能开始计数
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n) 
  bps_con <= 9'b0;
  else  
   if(en_data) begin 
	  if(bps_con == bps_max)
	   bps_con <= 9'b0;
	  else bps_con <= bps_con + 1'b1;
	end else  
	  bps_con <= 9'b0;
//产生波特率时钟
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n)
  bps_clk <= 0;
   else if(bps_con ==9'b1)
    bps_clk <= 1'b1;
	  else bps_clk <= 1'b0;
//计数波特率时钟
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n)
  bps_count <= 8'b0;
  else if((bps_count == 8'd159) || ((bps_count == 8'd12) && (start_bite >2)))
   bps_count <= 8'b0;
	 else if(bps_clk)
	  bps_count <= bps_count + 1'b1;
   
//产生Done_rx计数满信号
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n)
  Done_rx <= 1'b0;
 else if(bps_count == 8'd159)
  Done_rx <= 1'b1;
 else Done_rx <= 1'b0;
 
 //将Data的值给Data_out输出查看
always @(posedge Clk or  negedge Rst_n)
  if(!Rst_n)
    Data_out <= 8'b0;
 else if(bps_count == 8'd159) begin
    Data_out[0] <=  Data[0][2];   //如果中间6位数值和加起来大于3(100.101.110)第3位数值将大于1,由此可以将第3位的值直接传给Data_out数据 
    Data_out[1] <=  Data[1][2]; 
    Data_out[2] <=  Data[2][2]; 
    Data_out[3] <=  Data[3][2]; 
	 Data_out[4] <=  Data[4][2]; 
	 Data_out[5] <=  Data[5][2];
    Data_out[6] <=  Data[6][2];     
	 Data_out[7] <=  Data[7][2]; 	 
 end
 
//将Data的中间6位数据累加
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n)begin
  start_bite <= 3'b0;
  Data[0] <= 3'b0;
  Data[1] <= 3'b0;
  Data[2] <= 3'b0;
  Data[3] <= 3'b0;
  Data[4] <= 3'b0;
  Data[5] <= 3'b0;
  Data[6] <= 3'b0;
  Data[7] <= 3'b0;
  stop_bite  <= 3'b0;
 end   else  if(bps_clk)
  begin   
         case(bps_count)
         0:begin
		   	start_bite <= 3'b0;
	      	Data[0] <= 3'b0;
			   Data[1] <= 3'b0;
				Data[2] <= 3'b0;
				Data[3] <= 3'b0;
				Data[4] <= 3'b0;
				Data[5] <= 3'b0;
				Data[6] <= 3'b0;
				Data[7] <= 3'b0;
				stop_bite  <= 3'b0;			
           end
	      6,7,8,9,10,11: start_bite <= start_bite + rs232_rx_now; 		 
			22,23,24,25,26,27: Data[0] <= Data[0] + rs232_rx_now; 
		   38,39,40,41,42,43: Data[1] <= Data[1] + rs232_rx_now;   
		   54,55,56,57,58,59: Data[2] <= Data[2] + rs232_rx_now;
			70,71,72,73,74,75: Data[3] <= Data[3] + rs232_rx_now;
         86,87,88,89,90,91: Data[4] <= Data[4] + rs232_rx_now;
         102,103,104,105,106,107: Data[5] <= Data[5] + rs232_rx_now;
			118,119,120,121,122,123: Data[6] <= Data[6] + rs232_rx_now;
         134,135,136,137,138,139: Data[7] <= Data[7] + rs232_rx_now;
			150,151,152,153,154,155: stop_bite <= stop_bite + rs232_rx_now; 
        default : begin
		      start_bite <= start_bite;
	      	Data[0] <= Data[0];
			   Data[1] <= Data[1];
				Data[2] <= Data[2];
				Data[3] <= Data[3];
				Data[4] <= Data[4];
				Data[5] <= Data[5];
				Data[6] <= Data[6];
				Data[7] <= Data[7];
				stop_bite  <= stop_bite;			
		  end 
  endcase
    end
 
//判断是否完成接收或无开始错误,产生使能信号
always @(posedge Clk or negedge Rst_n)
 if(!Rst_n)
	 en_data <= 1'b0;
  else if(low)
    en_data <= 1'b1;	 
 else if(Done_rx ||((bps_count == 8'd12) && (start_bite >2)))
   en_data <= 1'b0;
  else en_data <= en_data;	 
  
endmodule 
串口接收仿真模块

将UART_TX 模块添加到工程中。

`timescale 1ns/1ns
`define clk_period 20
module uart_rx_tb;

    reg Clk;
    reg Rst_n;
    reg [2:0]Bps_set;
	 reg Con_en;
	 reg [7:0]Data_in;
	 wire  Rs232_tx;
	 wire  Done_tx;
	 wire  Uart_state;
	 
    wire [7:0]Data;
    wire Done_rx;
	 
UART_TX UART_TX0( //发送模块
   .Clk(Clk),
	.Rst_n(Rst_n),
	.Bps_set(Bps_set),
	.Con_en(Con_en),
	.Data_in(Data_in),   //将数据传送到发送模块
	.Rs232_tx(Rs232_tx),    //发送Data_in数据给接收模块
	.Done_tx(Done_tx),       //发送完成标志位
	.Uart_state(Uart_state) 
  );

uart_data_rx uart_data_rx0(  //串口接收模块
  .Clk(Clk),
  .Rst_n(Rst_n),
  .Rs232_rx(Rs232_tx),  
  .Bps_set(Bps_set),
  .Data_out(Data),  //将接收到的信号发送出来
  .Done_rx(Done_rx)
);

initial Clk = 1;
always #(`clk_period/2) Clk = ~Clk;


 initial begin
  Rst_n = 1'b0;
  Data_in = 8'b0;
  Con_en = 1'b0;
  Bps_set = 3'd4;
  #(`clk_period*20+1);
  Rst_n = 1'b1;
 #(`clk_period*20+1);
  Data_in = 8'hae;
  Con_en = 1'b1;
 #(`clk_period);
 Con_en = 1'b0;
 
 
 @(posedge Done_tx)
  #(`clk_period*2000);
   Data_in = 8'h5b;
   Con_en = 1'b1;
   #(`clk_period);
   Con_en = 1'b0;
	 
 @(posedge Done_tx)
	#(`clk_period*2000);
	$stop;
 end
endmodule 
仿真结果

在这里插入图片描述

顶层模块
module uart_top(
  Clk,
  Rst_n,
  Rs232_rx
	);
	
	input Clk;
	input Rst_n;
	input Rs232_rx;
   reg [7:0]Data_r;
	wire [7:0]Data;
	wire Done_rx;

uart_data_rx uart_data_rx1(  //串口接收模块
  .Clk(Clk),
  .Rst_n(Rst_n),
  .Rs232_rx(Rs232_rx),  
  .Bps_set(3'b0),
  
  .Data_out(Data),  //将接收到的信号发送出来
  .Done_rx(Done_rx)
);
	
is is0 (
	.probe(Data_r),
	.source()
	);

always @(posedge Clk or negedge Rst_n)
 if(!Rst_n)
  Data_r <= 0 ;
  else if(Done_rx)
   Data_r <= Data;
  else 
	Data_r <= Data_r;  
	
	
endmodule 
使用tool工具

在这里插入图片描述
时时将接收到的数据展示到PC端。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值