UART(通用異步收發(fā)器)是廣泛使用的串行數(shù)據(jù)傳輸協(xié)議。UART允許在串行鏈路上進(jìn)行全雙工的通信。專(zhuān)用的UART集成電路如8250,8251,NS16450等已經(jīng)相當(dāng)復(fù)雜,有些含有許多輔助的模塊(如FIF0),在實(shí)際應(yīng)用中,往往只需要用到UART的幾個(gè)基本功能,使用專(zhuān)用芯片會(huì)造成資源浪費(fèi)和成本提高,我們可以將所需要的UART功能集成到FPGA內(nèi)部,從而簡(jiǎn)化了整個(gè)系統(tǒng)電路,提高了可靠性、穩(wěn)定性和靈活性。
l 、UART簡(jiǎn)介
基本的UART通信只需要兩條信號(hào)線(RXD,TXD)就可以完成數(shù)據(jù)的相互通信,接收與發(fā)送是全雙工形式,其中TXD是UART發(fā)送端,RXD是UART接收端。UART的基本特點(diǎn)是:在信號(hào)線上有2種狀態(tài),可分別用邏輯1(高電平)和邏輯0(低電平)來(lái)區(qū)分。在發(fā)送器空閑時(shí),數(shù)據(jù)線應(yīng)保持在邏輯高電平狀態(tài)。發(fā)送器是通過(guò)發(fā)送起始位而開(kāi)始一個(gè)字符傳送,起始位使數(shù)據(jù)線處于邏輯0狀態(tài),提示接收器數(shù)據(jù)傳輸即將開(kāi)始。數(shù)據(jù)位一般為8位一個(gè)字節(jié)的數(shù)據(jù)(也有6位、7位的情況),低位(LSB)在前,高位(MSB)在后。校驗(yàn)位一般用來(lái)判斷接收的數(shù)據(jù)位有無(wú)錯(cuò)誤,一般是奇偶校驗(yàn)。停止位在最后,用以標(biāo)志一個(gè)字符傳送的結(jié)束,它對(duì)應(yīng)于邏輯1狀態(tài)。UART數(shù)據(jù)幀格式如表1所示。
2 、UART功能實(shí)現(xiàn)
基于FPGA的UART由3個(gè)子模塊組成:波特率發(fā)生器模塊;發(fā)送模塊;接收模塊。
2.1 波特率發(fā)生器模塊
波特率發(fā)生器實(shí)際上就是一個(gè)分頻器。波特率發(fā)生器的功能是產(chǎn)生和RS-232通信所采用的波特率同步的時(shí)鐘,這樣才能按照RS-232串行通信的時(shí)序要求進(jìn)行數(shù)據(jù)接收或發(fā)送。實(shí)現(xiàn)波特率時(shí)鐘的基本思路就是設(shè)計(jì)一個(gè)計(jì)數(shù)器,該計(jì)數(shù)器工作在速度很高的系統(tǒng)時(shí)鐘下,當(dāng)計(jì)數(shù)到某數(shù)值時(shí)將輸出置為高電平,再計(jì)數(shù)一定數(shù)值后將輸出置為低電平,如此反復(fù)就能得到所需的波特率時(shí)鐘。例如FPGA的系統(tǒng)時(shí)鐘為50MHz,RS-232通信的波特率為9600,則波特率時(shí)鐘的每個(gè)周期約相當(dāng)于5208個(gè)系統(tǒng)時(shí)鐘的周期。假如要得到占空比為50%的波特率時(shí)鐘,只要使計(jì)數(shù)器在計(jì)數(shù)到5208 50%=2604時(shí)將輸出置為高電平,之后在計(jì)數(shù)到5208時(shí)輸出低電平并重新計(jì)數(shù),就能得到和9600波特率同步的時(shí)鐘。
波特率發(fā)生器VHDL實(shí)現(xiàn)的關(guān)鍵代碼如下:
entity baud is
Port (clk,resetb:in std_logic;
bclk:out std_logic);
end baud;
architecture Behavioral of baud is
begin
process(clk,resetb)
variable cnt:integer;
begin
if resetb=‘1’ then cnt:=0; bclk《=‘0’; --復(fù)位
elsif rising_edge(clk) then
if cnt》=208 then cnt:=0; bclk《=‘1’; --設(shè)置分頻系數(shù)
else cnt:=cnt+1; bclk《=‘0’;
end if;
end if;
end process;
end Behavioral;
2.2 發(fā)送模塊
在發(fā)數(shù)據(jù)寄存器被寫(xiě)入一幀數(shù)據(jù)之后,發(fā)送過(guò)程被啟動(dòng)。發(fā)送過(guò)程啟動(dòng)后,發(fā)送串行移位寄存器被啟動(dòng)。同時(shí)發(fā)送使能標(biāo)志被清空。首先發(fā)送的是起始位,同時(shí)啟動(dòng)發(fā)數(shù)據(jù)計(jì)算器,記錄發(fā)送數(shù)據(jù)的個(gè)數(shù)。根據(jù)工作模式寄存器的要求,將要發(fā)送的一幀數(shù)據(jù)串行發(fā)送出去,如果需要校驗(yàn),則產(chǎn)生校驗(yàn)位并發(fā)送出去。最后需要發(fā)送的是停止位,根據(jù)停止位個(gè)數(shù)的要求,發(fā)送停止位。最后設(shè)置發(fā)送完畢標(biāo)志位。圖2為發(fā)送模塊狀態(tài)機(jī)示意圖。
圖2 發(fā)送狀態(tài)機(jī)示意圖
發(fā)送模塊VHDL程序關(guān)鍵代碼如下:
architecture Behavioral of transfer is
type states is (x_idle,x_start,x_wait,x_shift,x_stop); --定義各子狀態(tài)
signal state:states:=x_idle;
signal tcnt:integer:=0;
begin
process(bclkt,resett,xmit_cmd_p,txdbuf) --主控時(shí)序、組合進(jìn)程
variable xcnt16:std_logic_vector(4 downto 0):=“00000”; --定義中間變量
variable xbitcnt:integer:=0;
variable txds:std_logic;
begin
if resett=‘1’ then state《=x_idle; txd_done《=‘0’; txds:=‘1’; --復(fù)位
elsif rising_edge(bclkt) then
case state is
when x_idle=》 --狀態(tài)1,等待數(shù)據(jù)幀發(fā)送命令
if xmit_cmd_p=‘1’ then state《=x_start; txd_done《=‘0’;
else state《=x_idle;
end if;
when x_start=》 --狀態(tài)2,發(fā)送信號(hào)至起始位
if xcnt16》=“01111” then state《=x_wait; xcnt16:=“00000”;
else xcnt16:=xcnt16+1; txds:=‘0’; state《=x_start;
end if;
when x_wait=》 --狀態(tài)3,等待狀態(tài)
if xcnt16》=“01110” then
if xbitcnt=framlent then state《=x_stop; xbitcnt:=0;
else state《=x_shift;
end if;
xcnt16:=“00000”;
else xcnt16:=xcnt16+1; state《=x_wait;
end if;
when x_shift=》txds:=txdbuf(xbitcnt); xbitcnt:=xbitcnt+1; state《=x_wait; --狀態(tài)4,將待發(fā)數(shù)據(jù)進(jìn)行并串轉(zhuǎn)換
when x_stop=》 --狀態(tài)5,停止位發(fā)送狀態(tài)
if xcnt16》=“01111” then
if xmit_cmd_p=‘0’ then state《=x_idle; xcnt16:=“00000”;
else xcnt16:=xcnt16; state《=x_stop;
end if; txd_done《=‘1’;
else xcnt16:=xcnt16+1; txds:=‘1’; state《=x_stop;
end if;
when others=》state《=x_idle;
end case;
end if;
txd《=txds;
end process;
end Behavioral;
UART發(fā)送器的仿真波形如圖3所示。
2.3 接收模塊
在接收數(shù)據(jù)寄存器被讀出一幀數(shù)據(jù)或系統(tǒng)開(kāi)始工作之后,接收過(guò)程被啟動(dòng)。接收過(guò)程啟動(dòng)之后,等待檢測(cè)起始位。檢測(cè)到有效的起始位后,根據(jù)高于數(shù)據(jù)速率的時(shí)鐘同步開(kāi)始接收數(shù)據(jù)。根據(jù)數(shù)據(jù)位數(shù)的設(shè)定,計(jì)數(shù)器統(tǒng)計(jì)接收位數(shù)。一幀數(shù)據(jù)接收完畢之后,如果使用校驗(yàn)位,則檢測(cè)校驗(yàn)位,否則接收停止位。停止位接收完畢,則設(shè)定接收狀態(tài)寄存器中接收完畢寄存器,同時(shí)產(chǎn)生接收中斷,通知控制器讀取。接收狀態(tài)機(jī)的實(shí)現(xiàn)與發(fā)送部分類(lèi)似,限于篇幅,在這里不再敘述。
在具體實(shí)現(xiàn)接收部分電路的時(shí)候,我們采用的是基于高速多倍率采樣的方法。比如將采樣速率設(shè)置在三倍信息速率上,就是以三倍于波特率的頻率對(duì)接收引腳Rx進(jìn)行采樣,這樣既保證檢測(cè)到“起始位”,又可以調(diào)整采樣的時(shí)間間隔。將有效數(shù)據(jù)位的采樣點(diǎn)控制在碼元的中間1/3處,最大限度地減少誤碼,提高接收的準(zhǔn)確性。圖4是該方法的示意圖,在圖中為了分析方便,將起始位和部分?jǐn)?shù)據(jù)位放大,把每個(gè)信息位分為三等份,每等份的時(shí)間寬度設(shè)為T(mén)S 。以三倍頻對(duì)信息位進(jìn)行采樣時(shí),每個(gè)信息位都將可能被采樣到三次。當(dāng)處于空閑狀態(tài)并檢測(cè)起始位時(shí),盡管每次具體的采樣點(diǎn)會(huì)在S0區(qū)。檢測(cè)到起始位低電平后,間隔4×TS時(shí)間,正好是第一位數(shù)據(jù)位的中間1/3部分S1區(qū),即箭頭所指部位。此后的數(shù)據(jù)位、校驗(yàn)位和停止位的采樣間隔都是3×TS,當(dāng)所有采樣點(diǎn)均落在碼元的中間1/3部分時(shí),采樣數(shù)據(jù)最可靠。
3 、結(jié)束語(yǔ)
用FPGA實(shí)現(xiàn)UART功能,可以減小系統(tǒng)的面積,降低系統(tǒng)的功耗,提高系統(tǒng)的穩(wěn)定性,這種硬件軟件化的方法已經(jīng)成為當(dāng)今電子設(shè)計(jì)領(lǐng)域中的主導(dǎo)趨勢(shì)。在實(shí)際應(yīng)用中,我們將文中實(shí)現(xiàn)的UART電路作為一個(gè)功能塊嵌入到一個(gè)FPGA實(shí)現(xiàn)的數(shù)據(jù)采集與處理系統(tǒng)中,成功地實(shí)現(xiàn)了和遠(yuǎn)端PC機(jī)間的異步串行通信。實(shí)驗(yàn)證明了該UART電路設(shè)計(jì)簡(jiǎn)單、工作穩(wěn)定。
本文作者創(chuàng)新觀點(diǎn):本文將UART系統(tǒng)結(jié)構(gòu)進(jìn)行了模塊化分解,使之適應(yīng)自頂向下的設(shè)計(jì)方法,并采用狀態(tài)機(jī)對(duì)核心電路部分進(jìn)行了描述,使控制邏輯直觀簡(jiǎn)單,大幅度提高了設(shè)計(jì)效率,特別是對(duì)接收電路采用了高速多倍率采樣法進(jìn)行實(shí)現(xiàn),降低了誤碼率,使采樣數(shù)據(jù)更為可靠。
責(zé)任編輯:gt
評(píng)論
查看更多