`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 09:47:09 09/02/2022
// Design Name:
// Module Name: uart_tx
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module uart_tx(
input clk, //clock input
input rst_n, //asynchronous reset input, low active
input [7:0] now_tx_data, //data to send
input tx_data_enable, //data to be sent is valid
input [2:0] baud_set,
output reg finish_send, //正在发送
output reg rs232_tx_pin
);
reg [15:0]div_clk_cnt;//分频计数器
reg [13:0]bps_max_count; //分频计数最大值
reg [3:0] bit_cnt; //波特率计数时钟
reg [7:0] this_tx_data;
reg bps_clk; //波特率时钟
reg uart_TX_sending; //正在发送。
reg en_tx_data0;
reg en_tx_data1;
//波特率查找表 50M时钟的1个计数是20ns //5207=9600、2603=19200、1301=38400、867=57600、433=115200
always@(*)
begin
case(baud_set)
3'd0: bps_max_count = 5207;//(50_000_000/9600 - 1);
3'd1: bps_max_count = 2603;//(50_000_000/19200 - 1);
3'd2: bps_max_count = 1301;//(50_000_000/38400 - 1);
3'd3: bps_max_count = 867;//(50_000_000/57600 - 1);
3'd4: bps_max_count = 433;//(50_000_000/115200 - 1);
default: bps_max_count = 5207;//(50_000_000/9600 - 1);
endcase
end
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
en_tx_data0 <= 1’b0;
en_tx_data1 <= 1’b0;
end
else
begin
en_tx_data0 <= tx_data_enable;
en_tx_data1 <= en_tx_data0;
end
end
assign start_flag_posedge = (~en_tx_data1) & en_tx_data0;
//先寄存发送的数据
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
this_tx_data <= 0;
else if(start_flag_posedge)
this_tx_data <= now_tx_data;
else
this_tx_data <= this_tx_data;
end
//发送使能。
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
uart_TX_sending <= 0;
else if(start_flag_posedge)
uart_TX_sending <= 1;
else if(bit_cnt == 4'd11)
uart_TX_sending <= 0;
else
uart_TX_sending <= uart_TX_sending;
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
finish_send <= 0;
else if(start_flag_posedge == 1)//启动发送信号。
finish_send <= 0;
else if(bit_cnt == 4'd11)
finish_send <= 1;
else
finish_send <= finish_send;
end
//波特率计时器
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
div_clk_cnt <= 0;
else if(uart_TX_sending)//正在发送。
begin
if(div_clk_cnt == bps_max_count)
div_clk_cnt <= 0;
else
div_clk_cnt <= div_clk_cnt + 1'b1;
end
else
div_clk_cnt <= 0;
end
//波特率计时器,用于累计分频后的时钟脉冲
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
bit_cnt <= 0;
else if(bit_cnt == 4'd11)
bit_cnt <= 0;
else if(div_clk_cnt == 1)
bit_cnt <= bit_cnt + 1'b1;
else
bit_cnt <= bit_cnt;
end
//控制数据发送
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
rs232_tx_pin <= 1’b1;//复位时回到bit_cnt = 0的时刻
else if(uart_TX_sending)
begin
case(bit_cnt)
0: rs232_tx_pin <= 1’b1;
1: rs232_tx_pin <= 1’b0;
2: rs232_tx_pin <= this_tx_data[0];
3: rs232_tx_pin <= this_tx_data[1];
4: rs232_tx_pin <= this_tx_data[2];
5: rs232_tx_pin <= this_tx_data[3];
6: rs232_tx_pin <= this_tx_data[4];
7: rs232_tx_pin <= this_tx_data[5];
8: rs232_tx_pin <= this_tx_data[6];
9: rs232_tx_pin <= this_tx_data[7];
10: rs232_tx_pin <= 1’b1;
default: rs232_tx_pin <= 1’b1;
endcase
end
else
rs232_tx_pin <= 1’b1;
end
endmodule