FPGA的串口发送

`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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值