串口的全程為串行接口,也稱為串行通信接口,是采用串行通信方式的擴展接口。與串口對應的并行接口,例如高速AD和DA,
這些都是用的并行接口,而且在編程也簡單一些。
串口有一下特點:
(1)通信線路簡單,只要一對傳輸線就可以實現(xiàn)雙向通信。
(2)布線簡單,成本低。
(3)通信距離長,可以實現(xiàn)數(shù)米到數(shù)千米的通信距離。
(4)傳輸速率慢。
常見的串口速率如4800 , 9600 , 115200bps,代表每秒鐘發(fā)送多少bit數(shù)據(jù),例如9600bps就代表1秒內(nèi)發(fā)送9600bit數(shù)據(jù)。

串口協(xié)議 :協(xié)議比較簡單,一般都是10位數(shù)據(jù),1個起始位 低電平 ,然后八個數(shù)據(jù)位,低位在前,一個奇偶校驗位,平時
一般不用,最后是一位停止位高電平,這樣一幀數(shù)據(jù)發(fā)送結束。
下面介紹一下我的程序框架:

整體框架分為兩個部分:一個是串口驅(qū)動部分 另一個是串口數(shù)據(jù)控制部分。串口驅(qū)動部分負責串口驅(qū)動和波特率的選擇,串口數(shù)據(jù)控制模塊
負責控制數(shù)據(jù)內(nèi)容的控制和發(fā)送速度的控制。

從上面時序圖可以看出,每10ms發(fā)送一幀數(shù)據(jù),這里data_en負責波特率驅(qū)動使能,uart_tx_end有兩個功能,一個是關閉data_en使能,另一個是給10ms計數(shù)器
清零。
/*----------------------------------------------------------------------- Date : 2017-09-03 Description : Design for uart_driver. -----------------------------------------------------------------------*/ module uart_tx_driver ( //global clock input clk , //system clock input rst_n , //sync reset //uart interface output reg uart_tx , //user interface input [1:0] bps_select , //波特率選擇 input [7:0] uart_data , input data_en , //發(fā)送數(shù)據(jù)使能 output reg uart_tx_end ); //-------------------------------- //Funtion : 參數(shù)定義 parameter BPS_4800 = 14'd10417 , BPS_9600 = 14'd5208 , BPS_115200 = 14'd434 ; reg [13:0] cnt_bps_clk ; reg [13:0] bps ; reg bps_clk_en ; //bps使能時鐘 reg [3:0] bps_cnt ; wire [13:0] BPS_CLK_V = bps >> 1 ; //-------------------------------- //Funtion : 波特率選擇 always @(posedge clk or negedge rst_n) begin if(!rst_n) bps <= 1'd0; else if(bps_select == 2'd0) bps <= BPS_115200; else if(bps_select == 2'd1) bps <= BPS_9600; else bps <= BPS_4800; end //-------------------------------- //Funtion : 波特率計數(shù) always @(posedge clk or negedge rst_n) begin if(!rst_n) cnt_bps_clk <= 1'd0; else if(cnt_bps_clk >= bps - 1 && data_en == 1'b0) cnt_bps_clk <= 1'd0; else cnt_bps_clk <= cnt_bps_clk + 1'd1; end //-------------------------------- //Funtion : 波特率使能時鐘 always @(posedge clk or negedge rst_n) begin if(!rst_n) bps_clk_en <= 1'd0; else if(cnt_bps_clk == BPS_CLK_V - 1) bps_clk_en <= 1'd1; else bps_clk_en <= 1'd0; end //-------------------------------- //Funtion : 波特率幀計數(shù) always @(posedge clk or negedge rst_n) begin if(!rst_n) bps_cnt <= 1'd0; else if(bps_cnt == 11) bps_cnt <= 1'd0; else if(bps_clk_en) bps_cnt <= bps_cnt + 1'd1; end //-------------------------------- //Funtion : uart_tx_end always @(posedge clk or negedge rst_n) begin if(!rst_n) uart_tx_end <= 1'd0; else if(bps_cnt == 11) uart_tx_end <= 1'd1; else uart_tx_end <= 1'd0; end //-------------------------------- //Funtion : 發(fā)送數(shù)據(jù) always @(posedge clk or negedge rst_n) begin if(!rst_n) uart_tx <= 1'd1; else case(bps_cnt) 4'd0 : uart_tx <= 1'd1; 4'd1 : uart_tx <= 1'd0; //begin 4'd2 : uart_tx <= uart_data[0];//data 4'd3 : uart_tx <= uart_data[1]; 4'd4 : uart_tx <= uart_data[2]; 4'd5 : uart_tx <= uart_data[3]; 4'd6 : uart_tx <= uart_data[4]; 4'd7 : uart_tx <= uart_data[5]; 4'd8 : uart_tx <= uart_data[6]; 4'd9 : uart_tx <= uart_data[7]; 4'd10 : uart_tx <= 1; //stop default : uart_tx <= 1; endcase end endmodule
/*-----------------------------------------------------------------------
Date : 2017-XX-XX
Description : Design for .
-----------------------------------------------------------------------*/
module uart_tx_control
(
//global clock
input clk , //system clock
input rst_n , //sync reset
//user interface
output reg [7:0] uart_data ,
output reg data_en ,
input uart_tx_end
);
//--------------------------------
//Funtion : 參數(shù)定義
parameter DELAY_10MS = 500_000 ;
reg [31:0] cnt_10ms ;
wire delay_10ms_done ;
//data define
reg [31:0] cnt_1s;
//--------------------------------
//Funtion : cnt_10ms
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_10ms <= 1'd0;
else if(cnt_10ms == DELAY_10MS - 1 && uart_tx_end == 1'd1)
cnt_10ms <= 1'd0;
else
cnt_10ms <= cnt_10ms + 1'd1;
end
assign delay_10ms_done = (cnt_10ms == DELAY_10MS - 1) ? 1'd1 : 1'd0;
//--------------------------------
//Funtion : data_en
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
data_en <= 1'd0;
else if(delay_10ms_done)
data_en <= 1'd1;
else if(uart_tx_end)
data_en <= 1'd0;
end
///////////////////////數(shù)據(jù)測試/////////////////////////////
//--------------------------------
//Funtion : cnt_1s
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt_1s <= 1'd0;
else if(cnt_1s == 49_999_999)
cnt_1s <= 1'd0;
else
cnt_1s <= cnt_1s + 1'd1;
end
//--------------------------------
//Funtion : uart_data
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
uart_data <= 1'd0;
else if(uart_data >= 10)
uart_data <= 1'd0;
else if(cnt_1s == 49_999_999)
uart_data <= uart_data + 1'd1;
end
endmodule
編輯:黃飛
?
電子發(fā)燒友App
















評論