| UART(即Universal Asynchronous Receiver Transmitter 通用異步收發(fā)器)是廣泛使用的串行數(shù)據(jù)傳輸協(xié)議。UART允許在串行鏈路上進(jìn)行全雙工的通信。---串行外設(shè)用到RS232-C 異步串行接口,一般采用專用的集成電路即UART 實(shí)現(xiàn)。如8250、8251、NS16450等芯片都是常見的UART器件,這類芯片已經(jīng)相當(dāng)復(fù)雜,有的含有許多輔助的模塊(如FIFO),有時(shí)我們不需要使用完整的UART的功能和這些輔助功能;蛘咴O(shè)計(jì)上用到了FPGA/CPLD器件,那么我們就可以將所需要的UART功能集成到FPGA內(nèi)部。使用VHDL將UART的核心功能集成,從而使整個(gè)設(shè)計(jì)更加緊湊、穩(wěn)定且可靠。本文應(yīng)用EDA技術(shù),基于FPGA/CPLD器件設(shè)計(jì)與實(shí)現(xiàn)UART。
一、 UART 簡(jiǎn)介
1 、UART 結(jié)構(gòu)
UART主要有由數(shù)據(jù)總線接口、控制邏輯、波特率發(fā)生器、發(fā)送部分和接收部分等組成。---功能包括微處理器接口,發(fā)送緩沖器(tbr)、發(fā)送移位寄存器(tsr)、幀產(chǎn)生、奇偶校驗(yàn)、并轉(zhuǎn)串、數(shù)據(jù)接收緩沖器(rbr)、接收移位寄存器(rsr)、幀產(chǎn)生、奇偶校驗(yàn)、串轉(zhuǎn)并。 圖1 是UART 的典型應(yīng)用。
 圖 1 2、 UART 的幀格式
UART 的幀格式如圖2 所示。
 圖 2 ---包括線路空閑狀態(tài)(idle,高電平)、起始位(start bit,低電平)、5~8位數(shù)據(jù)位(data bits)、校驗(yàn)位(parity bit,可選)和停止位(stop bit,位數(shù)可為1、1.5、2 位)。
---這種格式是由起始位和停止位來實(shí)現(xiàn)字符的同步。
&nb sp; --- UART 內(nèi)部一般有配置寄存器,可以配置數(shù)據(jù)位數(shù)(5~8 位)、是否有校驗(yàn)位和校驗(yàn)的類型、停止位的位數(shù)(1,1.5,2)等設(shè)置。
二、 UART 的設(shè)計(jì)與實(shí)現(xiàn)
1、 UART 發(fā)送器
發(fā)送器每隔16個(gè)CLK16時(shí)鐘周期輸出1位,次序遵循1位起始位、8位數(shù)據(jù)位(假定數(shù)據(jù)位為8位)、1位校驗(yàn)位(可選)、1位停止位。--- CPU何時(shí)可以往發(fā)送緩沖器tbr寫入數(shù)據(jù),也就是說CPU要寫數(shù)據(jù)到tbr時(shí)必須判斷當(dāng)前是否可寫,如果不判這個(gè)條件,發(fā)送的數(shù)據(jù)會(huì)出錯(cuò)。---數(shù)據(jù)的發(fā)送是由微處理器控制,微處理器給出wen 信號(hào),發(fā)送器根據(jù)此信號(hào)將并行數(shù)據(jù)din[70]鎖存進(jìn)發(fā)送緩沖器tbr[70],并通過發(fā)送移位寄存器tsr[70]發(fā)送串行數(shù)據(jù)至串行數(shù)據(jù)輸出端dout。在數(shù)據(jù)發(fā)送過程中用輸出信號(hào)tre作為標(biāo)志信號(hào),當(dāng)一幀數(shù)據(jù)發(fā)送完畢時(shí),tre信號(hào)為1,通知CPU在下個(gè)時(shí)鐘裝入新數(shù)據(jù)。---發(fā)送器端口信號(hào)如圖3 所示。
 圖 3 ---引入發(fā)送字符長(zhǎng)度和發(fā)送次序計(jì)數(shù)器length_no,實(shí)現(xiàn)的部分VHDL 程序如下。 --- if std_logic_vector(length_no) = “0001” then --- tsr <= tbr ; --- 發(fā)送緩沖器tbr 數(shù)據(jù)進(jìn)入發(fā)送移位寄存器tsr --- tre <= ''0'' ; --- 發(fā)送移位寄存器空標(biāo)志置“0” --- elsif std_logic_vector(length_no) = “0010” then --- dout <= ''0'' ; --- 發(fā)送起始位信號(hào)“0” --- elsif std_logic_vector(length_no) >= “0011” and std_logic_vector(length_no) <= “1010” then --- tsr <= ''0'' & tsr(7 downto 1); --- 從低位到高位進(jìn)行移位輸出至串行輸出端dout --- dout <= tsr(0) ; --- parity <= parity xor tsr(0) ; --- 奇偶校驗(yàn)--- elsif std_logic_vector(length_no) = “1011” then --- dout <= parity ; 校驗(yàn)位輸出--- elsif std_logic_vector(length_no) = |