如何使用RS-232发射器和接收器?
目录
前言
前面讲到了波特率的产生,发射器以及接收器:
如何把这些模块链接起来,实现一些功能呢?
这篇博文就是干这个事情的。
参考链接:https://www.fpga4fun.com/SerialInterface5.html
原文提供的思路已经很不错了。
我之前也写过一篇有发射器和接收器构成的一个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原理图,以便看出原理,以及这些模块是如何连接的:
从这幅原理图可以看出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原理图为:
话说链接是连接了,但是能不能正常工作呢?
第一步,写个测试代码验证一下呗。
设计二(回环)测试
测试代码很简单,直接用之前的 RS232 Receiver
-
`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
仿真效果很满意:
RxD_data_ready有效时,接收完毕,于此同时TxD_start有效,开始发送数据。
最后设计一的仿真自己做吧。
文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。
原文链接:reborn.blog.csdn.net/article/details/90612047
- 点赞
- 收藏
- 关注作者
评论(0)