01
UART基礎(chǔ)知識(shí)
通用異步收發(fā)傳輸器 (Universal Asynchronous Receiver/Transmitter),通常稱作UART。它將要傳輸?shù)?a href="http://wenjunhu.com/soft/special/" target="_blank">資料在串行通信與并行通信之間加以轉(zhuǎn)換。作為把并行輸入信號(hào)轉(zhuǎn)成串行輸出信號(hào)的芯片,UART通常被集成于其他通訊接口的連結(jié)上。
具體實(shí)物表現(xiàn)為獨(dú)立的模塊化芯片,或作為集成于微處理器中的周邊設(shè)備。一般是RS-232C規(guī)格的,與類似Maxim的MAX232之類的標(biāo)準(zhǔn)信號(hào)幅度變換芯片進(jìn)行搭配,作為連接外部設(shè)備的接口。在UART上追加同步方式的序列信號(hào)變換電路的產(chǎn)品,被稱為USART(Universal Synchronous Asynchronous Receiver Transmitter)。
1.1 早期串行通訊設(shè)備
早期的電報(bào)機(jī)器使用長(zhǎng)度可變的脈沖信號(hào)(摩斯電碼)進(jìn)行數(shù)據(jù)傳輸,后來(lái)出現(xiàn)的電傳打印機(jī)(teleprinters )使用5、6、7或8個(gè)數(shù)據(jù)位來(lái)表示各種字符編碼。隨著電傳打印機(jī)的普及,最終發(fā)展成為計(jì)算機(jī)外圍設(shè)備。
由于歷史的發(fā)展原因,早期在Unix終端是一個(gè)名字為ASR33的電傳打字機(jī),而電傳打字機(jī)的英文單詞為Teletype(或Teletypewritter),縮寫為TTY。因此,終端設(shè)備也被稱為tty設(shè)備。這就是TTY這個(gè)名稱的來(lái)源。
1.2 早期的芯片級(jí)UART
DEC(Digital Equipment Corporation)公司的Gordon Bell 為該公司的PDP系列計(jì)算機(jī)設(shè)計(jì)了第一個(gè)UART,不過(guò)體積龐大,UART的線路占據(jù)了整個(gè)電路板;后來(lái)DEC將串行線路單元的設(shè)計(jì)濃縮為早期的UART單芯片,以方便自己使用。西部數(shù)據(jù)(Western Digital)公司在1971年左右將其開發(fā)為第一個(gè)廣泛可用的UART單芯片 WD1402A。這是中型集成電路的早期產(chǎn)品。
DEC是美國(guó)一家計(jì)算機(jī)公司;Western Digital是美國(guó)計(jì)算機(jī)硬盤驅(qū)動(dòng)器制造商和數(shù)據(jù)存儲(chǔ)公司。
1.3 現(xiàn)代串行通訊設(shè)備
2000年開始,大多數(shù)IBM或者相關(guān)的計(jì)算機(jī)都刪除了其外部RS232的COM端口,將其替換為帶寬性能更加出色的USB端口;對(duì)于仍然需要RS-232串行COM端口的用戶,現(xiàn)在通常使用外部USB轉(zhuǎn)UART轉(zhuǎn)換器,常見的有CH340,Silicon Labs 210x的驅(qū)動(dòng)程序,現(xiàn)在很多處理器和芯片都內(nèi)置了UART。
02
UART傳輸協(xié)議
2.1 UART協(xié)議
在串口通信中,數(shù)據(jù)在1位寬的單條線路上進(jìn)行傳輸,一個(gè)字節(jié)的數(shù)據(jù)要分為8次,由低位到高位按順序一位一位的進(jìn)行傳送,這個(gè)過(guò)程稱為數(shù)據(jù)的"串行化(serialized)"過(guò)程。由于串口通信是一種異步通信協(xié)議,并沒有時(shí)鐘信號(hào)隨著數(shù)據(jù)一起傳輸,而且空閑狀態(tài)(沒有數(shù)據(jù)傳輸?shù)臓顟B(tài))的時(shí)候,串行傳輸線為高電平1,所以發(fā)送方發(fā)送一個(gè)字節(jié)數(shù)據(jù)之前會(huì)先發(fā)送一個(gè)低電平0,接收方收到這個(gè)低電平0以后就知道有數(shù)據(jù)要來(lái)了,準(zhǔn)備開始接收數(shù)據(jù)從而實(shí)現(xiàn)一次通信。串口通信的時(shí)序如下圖所示:
串口通信的規(guī)范如下:
1. 空閑狀態(tài)(沒有數(shù)據(jù)傳輸?shù)臓顟B(tài))下,串行傳輸線上為高電平1;
2. 發(fā)送方發(fā)送低電平0表示數(shù)據(jù)傳輸開始,這個(gè)低電平表示傳輸?shù)钠鹗嘉唬?/p>
3. 8-bit的數(shù)據(jù)位(1 Byte)是從最低位開始發(fā)送,最高位最后發(fā)送;
4. 數(shù)據(jù)位的最高位發(fā)送完畢以后的下一位是奇偶校驗(yàn)位,這一位可以省略不要,同時(shí),當(dāng)不發(fā)送奇偶校驗(yàn)位的時(shí)候接收方也相應(yīng)的不接收校驗(yàn)位;
5. 最后一位是停止位,用高電平1表示停止位。
下面以發(fā)送字節(jié)0x55為例來(lái)說(shuō)明整個(gè)的發(fā)送過(guò)程:
先把0x55轉(zhuǎn)化成二進(jìn)制為:01010101。顯然0x55的最低位bit 0是1,次低位bit 1是0,……..,最高位bit 7是0,由于串口是從最低位開始發(fā)送一個(gè)字節(jié),所以0x55各個(gè)位的發(fā)送順序是1-0-1-0-1-0-1-0,波形如下圖所示:
下面在給出一個(gè)波形,根據(jù)上面的規(guī)則也可以很容易判斷這是發(fā)送字節(jié)0x13的波形:
2.1.1 起始位
UART數(shù)據(jù)傳輸時(shí)在不傳輸數(shù)據(jù)時(shí)保持在高電平,當(dāng)開始傳輸數(shù)據(jù)時(shí),先發(fā)出1bit位寬的低電平,表示數(shù)據(jù)開始傳輸,即為起始位。
2.1.2 數(shù)據(jù)位
數(shù)據(jù)位包含正在傳輸?shù)膶?shí)際數(shù)據(jù),位寬可以為4bit到10bit,大多數(shù)情況下,數(shù)據(jù)首先從低有效位發(fā)送。
2.1.3 校驗(yàn)位
串口通信中的一種交錯(cuò)方式,通常有偶校驗(yàn)、奇校驗(yàn)、高校驗(yàn)和低校驗(yàn)四種檢錯(cuò)方式,沒有校驗(yàn)位也是可以的。
偶校驗(yàn):數(shù)據(jù)位加上校驗(yàn)位后,“1”的位數(shù)應(yīng)為偶數(shù);
奇校驗(yàn):數(shù)據(jù)位加上校驗(yàn)位后,“1”的位數(shù)應(yīng)為奇數(shù);
2.1.4 停止位
在數(shù)據(jù)發(fā)送結(jié)束后發(fā)送一位高電平用于停止標(biāo)識(shí)。
由于數(shù)據(jù)是在傳輸線上定時(shí)的,并且每一個(gè)設(shè)備有其自己的時(shí)鐘,很可能在通信中兩臺(tái)設(shè)備間出現(xiàn)了小小的不同步。因此停止位不僅僅是表示傳輸?shù)慕Y(jié)束,并且提供計(jì)算機(jī)校正時(shí)鐘同步的機(jī)會(huì)。適用于停止位的位數(shù)越多,不同時(shí)鐘同步的容錯(cuò)性越好,但是數(shù)據(jù)傳輸率同時(shí)也越慢。
3.1.5 波特率
串口數(shù)據(jù)的傳輸速度用波特率(bit/s)進(jìn)行衡量,常見的波特率有:9600、19200、38400、57600、115200。假設(shè)UART配置為1bit起始位,8bit數(shù)據(jù)位,沒有校驗(yàn)位,1bit停止位,那么9600bit/s的波特率可得出每一位數(shù)據(jù)的時(shí)間寬度為:T=1/9600*10=1.04ms,即每個(gè)字節(jié)(10bit數(shù)據(jù))傳輸需要1.04ms。同理可得各個(gè)波特率下數(shù)據(jù)位傳輸時(shí)間寬度。
2.2 UART傳輸過(guò)程
- 發(fā)送端數(shù)據(jù)總線將數(shù)據(jù)包并行傳輸給發(fā)送端UART;
- 發(fā)送端UART將起始位、奇偶校驗(yàn)位和停止位添加到數(shù)據(jù)包中;
- 接收端UART解析數(shù)據(jù)包數(shù)據(jù);
- 接收端UART將所解析的數(shù)據(jù)傳輸給接收端數(shù)據(jù)總線。
03
UART代碼實(shí)現(xiàn)
3.1 UART目標(biāo)實(shí)現(xiàn)功能
設(shè)計(jì)一個(gè)UART發(fā)送模塊和接收模塊,具體要求如下:
- 設(shè)計(jì)一個(gè)UART發(fā)送模塊,該模塊接收一個(gè)8位輸入數(shù)據(jù)并采用UART協(xié)議發(fā)送,UART 采用10位傳輸協(xié)議,即一位起始位,8位數(shù)據(jù)位,一位終止位。發(fā)送數(shù)據(jù)時(shí)先發(fā)低位數(shù)據(jù),最后發(fā)高位數(shù)據(jù)。要求波特率為1K。模塊的定義如下:
module uart_tx (
clk_40k, //clock signal, 40kHz
rst_n, //reset signal, active low
din, //the input data which will be sent by the UART module, 8 bit width
send_start,//the start enable signal, active high, the width is one clock period
bit_out //the serial output data
);
- 設(shè)計(jì)一個(gè)UART接收模塊,模塊的定義如下:
module uart_rx (
clk_40k, //clock signal, 40kHz
rst_n, //reset signal, active low
bit_in, //the input serial bit,
dout_vld,//the output valid signal, active high,the dout is valid when this signal is high.
dout //received data, 8 bit width
);
- 設(shè)計(jì)一個(gè)testbench,對(duì)發(fā)送模塊和接收模塊進(jìn)行測(cè)試,測(cè)試過(guò)程如下,testbench產(chǎn)生一個(gè)隨機(jī)數(shù),然后啟動(dòng)uart_tx模塊發(fā)送至uart_rx模塊,當(dāng)uart_rx模塊接收到有效數(shù)據(jù)后,自動(dòng)判斷接收的數(shù)據(jù)是否正確。
3.2 Verilog代碼
1. 發(fā)送模塊 (uart_tx):
module uart_tx (
clk_40k,//clock signal, 40kHz
rst_n, //reset signal, active low
din,//the input data which will be sent by the UART module, 8 bit width
send_start,//the start enable signal, active high, the width is one clock period
bit_out//the serial output data
);
input [7:0] din;
input clk_40k;
input rst_n;
input send_start;
output bit_out;
reg flag;
reg tx_flag;
reg [6:0] cnt;
reg [5:0] tx_cnt;
reg [9:0] din_temp;
//flag: 發(fā)送過(guò)程flag始終拉高
always @ (posedge clk_40k)
begin
if(~rst_n)
flag <= 1'b0;
else if(send_start == 1'b1)
flag <= 1'b1;
else if(tx_flag == 1'b1)
flag <= 1'b0;
end
//tx_flag: 發(fā)送結(jié)束tx_flag拉高
always @ (posedge clk_40k)
begin
if(~rst_n)
tx_flag <= 1'b0;
else if(flag == 1'b1 && din_temp[0] == 1'b0)
tx_flag <= 1'b1;
else if(tx_cnt == 7'd10)
tx_flag <= 1'b0;
end
//cnt: 發(fā)送數(shù)據(jù)計(jì)數(shù),clk_40k分頻至1k波特率對(duì)傳輸數(shù)據(jù)進(jìn)行計(jì)數(shù)
always @ (posedge clk_40k)
begin
if(~rst_n)
cnt <= 7'b0;
else if(tx_flag == 1'b1 && cnt != 7'd39)
cnt <= cnt + 1'b1;
else
cnt <= 7'b0;
end
always @ (posedge clk_40k)
begin
if(~rst_n)
tx_cnt <= 6'b0;
else if(tx_flag == 1'b1 && cnt == 7'd39)
tx_cnt <= tx_cnt + 1'b1;
else if(tx_flag == 1'b0)
tx_cnt <= 6'b0;
end
//din_temp: 8bit數(shù)據(jù)移位操作,串行輸出
always @ (posedge clk_40k)
begin
if(~rst_n)
din_temp <= 10'b1111111111;
else if(flag == 1'b1 || send_start == 1'b1)
din_temp <= {1'b1,din,1'b0};
else if(tx_flag == 1'b1 && cnt == 7'd39)
din_temp <= {1'b1,din_temp[9:1]};
end
assign bit_out = din_temp[0];
endmodule
-
uart
+關(guān)注
關(guān)注
22文章
1237瀏覽量
101429 -
通訊接口
+關(guān)注
關(guān)注
2文章
80瀏覽量
16190 -
異步收發(fā)傳輸器
+關(guān)注
關(guān)注
0文章
10瀏覽量
6349
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論