概述
设计一个数据发送器,以每100ms以115200的波特率发送一个数据,每次发送的数据比前一个数据大一(计数器发01234……)
顶层测试发送模块
`timescale 1ns / 1ns
module uart_tx_test(
Clk,
Reset_n,
uart_tx
);
input Clk;
input Reset_n;
output uart_tx;
reg Send_Go;
reg [7:0]Data;
uart_byte_tx uart_byte_tx(
.Clk(Clk),
.Reset_n(Reset_n),
.Data(Data),
.Baud_set(3'd4),
.uart_tx(uart_tx),
.Tx_Done(Tx_Done),
.Send_Go(Send_Go)
);
reg [24:0]counter;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
counter <= 0;
else if(counter == 4999999)//100ms
counter <= 0;
else
counter <= counter + 1;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Send_Go <= 0;
else if(counter == 1)
Send_Go <= 1;
else
Send_Go <= 0;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Data <= 0;
else if(Tx_Done)
Data <= Data +1'b1;
endmodule
调用发送数据模块
module uart_byte_tx(
Clk,
Reset_n,
Data,
Baud_set,
uart_tx,
Tx_Done,
Send_Go
);
input [7:0]Data;
input Clk;
input Reset_n;
input Send_Go;
input [2:0]Baud_set;
output reg uart_tx;
output reg Tx_Done;
//Baud_set = 0 波特率 = 9600;
//Baud_set = 1 波特率 = 19200;
//Baud_set = 2 波特率 = 38400;
//Baud_set = 3 波特率 = 57600;
//Baud_set = 4 波特率 = 115200;
reg [17:0]bps_DR;
always@(*)
case(Baud_set)
0:bps_DR = 1000000000/9600/20;
1:bps_DR = 1000000000/9600/20/2;
2:bps_DR = 1000000000/9600/20/4;
3:bps_DR = 1000000000/9600/20/6;
4:bps_DR = 1000000000/9600/20/12;
default:bps_DR = 1000000000/9600/20;
endcase
reg Send_en;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Send_en <= 0;
else if(Send_Go)
Send_en <= 1;
else if(Tx_Done)
Send_en <= 0;
reg [7:0]r_Data;
always@(posedge Clk)
if(Send_Go)
r_Data <= Data;
else
r_Data <= r_Data;
wire bps_clk;
assign bps_clk = (dive_cnt == 1);//真正的波特率时钟,只在dive_cnt为1时为高电平
reg [17:0]dive_cnt;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
dive_cnt <= 0;
else if(Send_en)begin
if(dive_cnt == bps_DR - 1)
dive_cnt <= 0;
else
dive_cnt <= dive_cnt +1'b1;
end
else
dive_cnt <= 0;
reg [3:0]bps_cnt;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
bps_cnt <= 0;
else if(Send_en)begin
if(bps_clk)begin
if(bps_cnt == 11)
bps_cnt <= 0;
else
bps_cnt <= bps_cnt +1'b1;
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:uart_tx <= 0;
2:uart_tx <= r_Data[0];
3:uart_tx <= r_Data[1];
4:uart_tx <= r_Data[2];
5:uart_tx <= r_Data[3];
6:uart_tx <= r_Data[4];
7:uart_tx <= r_Data[5];
8:uart_tx <= r_Data[6];
9:uart_tx <= r_Data[7];
10:uart_tx <= 1;
11:uart_tx <= 1;
default:uart_tx <= 1;
endcase
end
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
Tx_Done <= 0;
else if((bps_clk == 1) && (bps_cnt == 10))
Tx_Done <= 1;
else
Tx_Done <= 0;
endmodule
测试模块仿真tb
`timescale 1ns / 1ns
module uart_tx_test_tb();
reg Clk;
reg Reset_n;
wire uart_tx;
uart_tx_test uart_tx_test(
.Clk(Clk),
.Reset_n(Reset_n),
.uart_tx(uart_tx)
);
initial Clk = 1;
always#10 Clk = ~Clk;
initial begin
Reset_n = 0;
#201;
Reset_n = 1;
#50000000;
end
endmodule
串口助手显示
一开始串口助手接受的数据全是00,但是时序仿真没有问题,历经了调低波特率,调低数据位都没有用,最后偶然间看到串口发送模块的86行与106行最后一个always块中Tx_Done重复赋值,将86行的Tx_Done赋值语句删掉or注释掉之后能够实现串口发送。
PS:开发板使用的小梅哥AX720,文章仅用于分享记录学习过程。
最后
以上就是魁梧白云为你收集整理的基于fpga实现uart串口通信的全部内容,希望文章能够帮你解决基于fpga实现uart串口通信所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复