一、基础知识
二、程序
module uart_send()
input sys_clk,
input sys_rst_n,
input reg[7:0] uart_din,
input reg uart_en,
outputreg uart_txd
);
parameter CLK_FREQ = 50_000_000;
parameter UART_BPS = 115200;
parameter BPS_CNT = CLK_FREQ/UART_BPS;
reg uart_en_d0; //两次的目的是为了实现边沿检测
reg uart_en_d1;
reg tx_flag;
reg [3:0]tx_cnt;
reg [15:0]clk_cnt;
reg [7:0]tx_data;
wire en_flag;
assign en_flag = (~uart_en_d1) & uart_en_d0;
always @(posedge clk or negedge rst_n)begin //寄存两次是为了使用assign赋值语句检测上升沿
if(!sys_rst_n)begin //复位
uart_en_d0 <=1'b0;
uart_en_d1 <=1'b0;
end
else begin
uart_en_d0 <= uart_en;
uart_en_d1 <= uart_en_d0;
end
end
always @(posedge clk or negedge rst_n)begin
if(!sys_rst_n)
tx_data <=8'd0;
else if(en_flag)begin
tx_data <= uart_din;
else begin
tx_data <= tx_data;
end
end
always @(posedge clk or negedge rst_n)begin
if(!sys_rst_n)
tx_flag <= 1'b0;
else if(en_flag)
tx_flag <= 1'b1;
else if(tx_cnt == 4'd9) && (clk_cnt == BPS_CNT-1'b1)
tx_flag <= 1'b0;
end
endmodule
always @(posedge clk or negedge rst_n)begin
if(!sys_rst_n)
clk_cnt <= 16'd0;
else if(tx_flag)begin
if(clk_cnt <BPS_CNT-1'b1)
clk_cnt <= clk_cnt + 1'b1;
else
clk_cnt <=16'd0;
end
else
clk_cnt <=16'd0;
end
endmodule
always @(posedge clk or negedge rst_n)begin
if(!sys_rst_n)
tx_cnt <= 4'd0;
else if(tx_flag)begin
if(clk_cnt == BPS_CNT -1'b1)
tx_cnt <= tx_cnt +1'b1;
else
tx_cnt <= tx_cnt ;
end
else
tx_cnt <= 4'd0;
end
endmodule
always @(posedge clk or negedge rst_n)begin
if(!sys_rst_n)
urat_txd <= 1'b1;
else if(tx_flag && (clk_cnt == 16'd0))begin //在波特率周期刚开始把数据值赋值给txd
case(tx_cnt) //数据并转串
4‘d0 : uart_txd <= 1'b0; //表示起始位
4‘d1 : uart_txd_d1 <= tx_data[0];
4‘d2 : uart_txd_d1 <= tx_data[1];
4‘d3 : uart_txd_d1 <= tx_data[2];
4‘d4 : uart_txd_d1 <= tx_data[3];
4‘d5 : uart_txd_d1 <= tx_data[4];
4‘d6 : uart_txd_d1 <= tx_data[5];
4‘d7 : uart_txd_d1 <= tx_data[6];
4‘d8 : uart_txd_d1 <= tx_data[7];
4‘d9 : uart_txd <= 1'b1;
endcase
end
end
endmodule
endmodule