FPGA串列埠傳送程式碼分享
module uart_tx(
clk, /*系統時鐘*/
rst_n, /*系統復位*/
data_byte, /*待傳輸8bit數*/
send_en, /*傳送使能訊號*/
baud_set, /*波特率設定*/
rs232_tx, /*rs232訊號輸出*/
tx_down, /*傳送結束訊號*/
uart_state /*傳送狀態*/
);
input clk; /*系統時鐘*/
input rst_n; /*
input[7:0]data_byte; /*待傳輸8bit數*/
inputsend_en; /*傳送使能訊號*/
input[2:0]baud_set; /*波特率設定*/
output regrs232_tx; /*rs232訊號輸出*/
output regtx_down; /*傳送結束訊號*/
output reguart_state; /*傳送狀態*/
reg bps_clk; /*待發送bit位計數器控制器*/
reg[15:0]div_cnt; /*
reg[15:0]bps_DR; /*分頻計數最大值*/
reg[3:0]bps_cnt; /*待發送bit位計數器*/
reg[7:0]r_db; /*待傳輸8bit數資料寄存*/
localparamSTART_BIT = 1'b0; /*起始位*/
localparamSTOP_BIT = 1'b1; /*停止位*/
/*************************波特率設定部分******************/
/*波特率設定*/
[email protected](posedgeclk,negedge rst_n)begin
if(!rst_n)begin /*如果復位*/
bps_DR<= 16'd5207; /*預設波特率9600*/
end
elsebegin
case(baud_set)
0:bps_DR<= 16'd5207; /*9600*/
1:bps_DR<= 16'd2603; /*19200*/
2:bps_DR<= 16'd1301; /*38400*/
3:bps_DR<= 16'd867; /*57600*/
4:bps_DR<= 16'd433; /*115200*/
default:bps_DR<= 16'd5207;/*預設波特率9600*/
endcase
end
end
/*波特率分頻計數值控制*/
[email protected](posedgeclk,negedge rst_n)begin
if(!rst_n)begin /*如果系統復位*/
div_cnt <= 16'd0; /*分頻計數器清零*/
end
elseif(uart_state)begin/*如果處於傳送狀態*/
if(div_cnt== bps_DR)begin/*如果分頻計數器計數到設定波特率計數最大值*/
div_cnt<= 16'd0; /*分頻計數器清零*/
end
elsebegin
div_cnt<= div_cnt + 16'd1;/*分頻計數器計數值加加*/
end
end
end
/*********************一位元組資料傳送驅動部分***************/
/*待發送一位元組bit位計數器的控制器*/
[email protected](posedgeclk,negedge rst_n)begin
if(!rst_n)begin /*如果系統復位*/
bps_clk<= 1'b0; /*接發一位元組送據bit計數器控制器置0*/
end
elseif(div_cnt == 16'd1)begin/*如果分頻計數器值為1*/
bps_clk<=1'b1; /*接發一位元組送據bit計數器控制器置1*/
end
elsebegin
bps_clk<= 1'b0; /*接發一位元組送據bit計數器控制器置0*/
end
end
/*待發送一位元組bit位計數器*/
[email protected](posedgeclk,negedge rst_n)begin
if(!rst_n)begin
bps_cnt<= 4'd0; /*待發送一位元組bit位計數器置零*/
end
elseif(bps_cnt == 4'd11)begin /*一個位元組的時序完成*/
bps_cnt<= 4'd0; /*待發送一位元組bit位計數器置零*/
end
elseif(bps_clk)begin/*波特率時鐘狀態置1*/
bps_cnt<= bps_cnt + 1'b1;/*待發送一位元組bit位計數器加加*/
end
elsebegin
bps_cnt<= bps_cnt; /*狀態保持*/
end
end
/*傳送是否結束控制*/
[email protected](posedgeclk ,negedge rst_n)begin
if(!rst_n)begin /*如果復位*/
tx_down= 1'b0; /*傳送未完成*/
end
elseif(bps_cnt == 4'd11)begin/*一個位元組的時序完成*/
tx_down= 1'b1; /*傳送完成*/
end
else begin
tx_down= 1'b0; /*傳送未完成*/
end
end
/*傳送狀態控制時序*/
[email protected](posedgeclk,negedge rst_n)begin
if(!rst_n)begin /*如果復位*/
uart_state<= 1'b0; /*處於未傳送狀態*/
end
elseif(send_en)begin /*如果傳送使能*/
uart_state<= 1'b1; /*處於傳送狀態*/
end
elseif(bps_cnt == 4'd11)begin/*一個位元組的時序完成*/
uart_state<= 1'b0; /*處於未傳送狀態*/
end
end
/*將待發送資料傳入一位元組資料暫存器*/
[email protected](posedgeclk,negedge rst_n)begin
if(!rst_n)begin /*如果復位*/
r_db<= 8'd0; /*待傳輸資料暫存器清零*/
end
elseif(send_en)begin /*如果傳送使能*/
r_db<= data_byte; /*將待發送8bit資料送入待傳輸資料暫存器*/
end
elsebegin /*系統沒有復位同時沒有使能傳送*/
r_db= r_db; /*待傳輸資料保持*/
end
end
/*傳送一個位元組資料*/
[email protected](posedgeclk,negedge rst_n)begin
if(!rst_n)begin /*如果復位*/
rs232_tx <= 1'b1; /*輸出訊號置1*/
end
elsebegin
case(bps_cnt)/*一個位元組傳送計數時序*/
0:rs232_tx<= 1'b1;
1:rs232_tx<= START_BIT;
2:rs232_tx<= r_db[0];
3:rs232_tx<= r_db[1];
4:rs232_tx<= r_db[2];
5:rs232_tx<= r_db[3];
6:rs232_tx<= r_db[4];
7:rs232_tx<= r_db[5];
8:rs232_tx<= r_db[6];
9:rs232_tx<= r_db[7];
10:rs232_tx<= STOP_BIT;
default:rs232_tx<= 1'b1;
endcase
end
end
endmodule