基于FPGA的串口发送实验
1、串口通信模块设计的目的是用来发送数据,因此需要设计一个数据输入端口
2、串口通信,支持不同的波特率,因此需要设计一个波特率设置端口
3、串口通信的本质就是将8位的并行数据通过一根数据线,在不同的时刻传输并行数据的不同位,通过多个时刻,最终将8位并行数据全部传出
4、串口通信以1位的低电平标志串行传输的开始,待8位数据传输完成之后,再以1位的高电平标志传输的结束
5、控制信号,控制并转串模块什么时候工作。什么时候一个数据发送完成?须有一个开始信号,以及一个发送完成信号
仿真波形
本文程序存在一定的小缺陷 完整程序请参考FPGA入门学习笔记(九)
设计文件程序
`timescale 1ns / 1ns
module UART(
input Clk,
input Reset_N,
input [7:0]Data,
input Send_EN,
input [2:0]Baud_Set,
output reg UART_TX,
output reg Tx_Done
);
// Baud_Set BaudRate
// 0 9600
// 1 19200
// 2 38400
// 3 57600
// 4 115200
reg [17:0]bps_DR;
parameter Time = 32'd1000000000;
always@(*)
case(Baud_Set)
0: bps_DR = Time/9600/20;
1: bps_DR = Time/19200/20;
2: bps_DR = Time/38400/20;
3: bps_DR = Time/57600/20;
4: bps_DR = Time/115200/20;
default: bps_DR = Time/9600/20;
endcase
reg [17:0]div_cnt;
always @(posedge Clk or negedge Reset_N)
if(!Reset_N)
div_cnt <= 0;
else if(Send_EN)begin
if(div_cnt == bps_DR - 1)
div_cnt <= 0;
else
div_cnt <= div_cnt + 1'd1;
end
else
div_cnt <= 0;
wire bps_clk;
assign bps_clk = (div_cnt == 1);
reg [3:0] bps_cnt;
always @(posedge Clk or negedge Reset_N)
if(!Reset_N)
bps_cnt <= 0;
else if(Send_EN)begin
if(div_cnt == 1)begin
if(bps_cnt == 11)
bps_cnt <= 0;
else
bps_cnt <= bps_cnt + 1'd1;
end
end
else
bps_cnt <= 0;
always @(posedge Clk or negedge Reset_N)
if(!Reset_N)begin
UART_TX <= 1'b1;
Tx_Done <= 0;
end
else begin
case (bps_cnt)
1: begin UART_TX <= 0;Tx_Done <= 0;end
2: UART_TX <= Data[0];
3: UART_TX <= Data[1];
4: UART_TX <= Data[2];
5: UART_TX <= Data[3];
6: UART_TX <= Data[4];
7: UART_TX <= Data[5];
8: UART_TX <= Data[6];
9: UART_TX <= Data[7];
10: UART_TX <= 1;
11:begin UART_TX <= 1;Tx_Done <= 1;end
default: UART_TX <= UART_TX;
endcase
end
endmodule
仿真文件程序
`timescale 1ns/1ns
module UART_tb();
reg Clk;
reg Reset_N;
reg [7:0]Data;
reg Send_EN;
reg [2:0]Baud_Set;
wire UART_TX;
wire Tx_Done;
UART UART_test(
.Clk(Clk),
.Reset_N(Reset_N),
.Data(Data),
.Send_EN(Send_EN),
.Baud_Set(Baud_Set),
.Tx_Done(Tx_Done),
.UART_TX(UART_TX)
);
initial Clk = 0;
always #10 Clk <= !Clk;
initial begin
Reset_N = 0;Data = 0;Send_EN = 0;Baud_Set = 4;
#201;
Reset_N = 1;
#100;
Data = 8'h75;Send_EN = 1;
#20;
@(posedge Tx_Done)Send_EN = 0;
#20000;
Data = 8'h69;Send_EN = 1;
#20;
@(posedge Tx_Done)Send_EN = 0;
#20000;
Send_EN = 0;
$stop;
end
endmodule