目录

前言

设计一

设计二(回环)

设计二(回环)测试


前言

前面讲到了波特率的产生,发射器以及接收器:

如何把这些模块链接起来,实现一些功能呢?

这篇博文就是干这个事情的。

原文提供的思路已经很不错了。

我之前也写过一篇有发射器和接收器构成的一个RS232回环实验


设计一

好了进入正题:

这种设计允许从PC控制一些FPGA引脚(通过PC的串行端口)。

它在FPGA上创建8个输出(名为“GPout”的端口)。 GPout由FPGA接收的任何字符更新。
FPGA上还有8个输入(名为“GPin”的端口)。 每次FPGA接收到字符时都会发送GPin。
GP输出可用于从PC远程控制任何东西,可能是LED或咖啡机......

给出Verilog描述:

module serialGPIO(
    input clk,
    input RxD,
    output TxD,

    output reg [7:0] GPout,  // general purpose outputs
    input [7:0] GPin  // general purpose inputs
);

	wire RxD_data_ready;
	wire TxD_busy;
	wire [7:0] RxD_data;
asy_receiver RX(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));
always @(posedge clk) if(RxD_data_ready) GPout <= RxD_data;

asy_transmitter TX(.clk(clk), .TxD(TxD), .TxD_start(RxD_data_ready), .TxD_data(GPin), .TxD_busy(TxD_busy));

endmodule

调用的模块代码就不在粘贴一遍了,去其他博文里面找。

这里给出RTL原理图,以便看出原理,以及这些模块是如何连接的:

如何使用RS-232发射器和接收器?_sed

从这幅原理图可以看出RX与TX之间的连接关系,RX接收外部的串行输入,当接收完毕后,RXD_data_ready有效,作为后面同步寄存器的使能,延迟一拍后,通过GPout输出。

同时TX模块接收一个8位数据GPin,开始发送信号也为RxD_data_ready,也就是说,当RX模块接收完数据后,Tx就开始发送GPin。


设计二(回环)

如果将RxD_data直接作为TX的输入,则形成一个RS232回环:

module serialGPIO(
    input clk,
    input RxD,
    output TxD

//    output reg [7:0] GPout,  // general purpose outputs
//    input [7:0] GPin  // general purpose inputs
);

	wire RxD_data_ready;
	wire TxD_busy;
	wire [7:0] RxD_data;
asy_receiver RX(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));
//always @(posedge clk) if(RxD_data_ready) GPout <= RxD_data;

asy_transmitter TX(.clk(clk), .TxD(TxD), .TxD_start(RxD_data_ready), .TxD_data(RxD_data), .TxD_busy(TxD_busy));

endmodule

RTL原理图为:

如何使用RS-232发射器和接收器?_远程控制_02


话说链接是连接了,但是能不能正常工作呢?

第一步,写个测试代码验证一下呗。

设计二(回环)测试

测试代码很简单,直接用之前的

`timescale 1ns / 1ps
 
module serialGPIO_tb( 
    );
	
	
	reg clk;
	reg RxD;
	//wire RxD_data_ready;
	//wire [7 : 0] RxD_data;  // data received, valid only (for one clock cycle) when RxD_data_ready is asserted
	wire TxD;
	
	parameter DATA0 = 10'b1101001010; //从低位开始发送
//	parameter DATA1 = 10'b1010011010;
	reg [9:0] data_in;
	integer i;
	
	
	
	initial begin
		clk = 0;
		forever 
			#20 clk = ~clk;
	end
	
	
	initial begin
		data_in = DATA0;
		for(i = 0; i < 9; i = i + 1) begin
			#8700	
				RxD = data_in[i]; 
		end
		
		#26100
		
		for(i = 0; i < 9; i = i + 1) begin
			#8700	
				RxD = data_in[i];
 
		end
		
	//#10000 $stop;
	
	end
	
	serialGPIO u_serialGPIO(
	.clk(clk),
	.RxD(RxD),
	.TxD(TxD)	
	);
	
	
	
	
endmodule

仿真效果很满意:

如何使用RS-232发射器和接收器?_sed_03

如何使用RS-232发射器和接收器?_远程控制_04

如何使用RS-232发射器和接收器?_引脚_05

 

RxD_data_ready有效时,接收完毕,于此同时TxD_start有效,开始发送数据。

 


最后设计一的仿真自己做吧。