詳解串行通信協(xié)議及其FPGA實現(xiàn),5000字先馬后看
詳解串行通信協(xié)議及其FPGA實現(xiàn),5000字先馬后看
\\\插播一條:
自己在今年整理一套單片機單片機相關(guān)論文800余篇
論文制作思維導(dǎo)圖
原理圖+源代碼+開題報告+正文+外文資料
想要的同學(xué)私信找我。
前言
好久沒更新博客了,這篇文章寫寫停停,用了近一周的時間,終于寫完了。本篇文章介紹,串口協(xié)議數(shù)據(jù)幀格式、串行通信的工作方式、電平標(biāo)準(zhǔn)、編碼方式及Verilog實現(xiàn)串口發(fā)送一個字節(jié)數(shù)據(jù)和接收一個字節(jié)數(shù)據(jù)。
對于MCU串口的發(fā)送接收,可能就是1行代碼就能實現(xiàn)串口的發(fā)送和接收:
STM32的串口接收和發(fā)送
//STM32發(fā)送1個字節(jié)USART_SendData(USART1,'A');while(USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_TXE)==RESET);
//STM32接收1個字節(jié):uint8_tRes;while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);Res=USART_ReceiveData(USART1);
51單片機的發(fā)送和接收
//51單片機發(fā)送1個字節(jié)SBUF='A;while(!TI);TI=0;
//51單片機接收1個字節(jié):charRes;if(RI){
Res=SBUF;
RI=0;}
更方便一點的,通過重寫C庫fput函數(shù)和fgetc函數(shù),還可以實現(xiàn)printf直接重定向到串口,用來輸出一些調(diào)試信息再方便不過了。
STM32實現(xiàn)輸入輸出重定向到串口發(fā)送接收
//可重定向printf函數(shù)intfputc(intch,FILE*f){
USART_SendData(DEBUG_USARTx,(uint8_t)ch);
while(USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_TXE)==RESET);
return(ch);}//可重定向scanf函數(shù)intfgetc(FILE*f){
while(USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_RXNE)==RESET);
return(int)USART_ReceiveData(DEBUG_USARTx);}
而MCU上的串口是半導(dǎo)體廠商預(yù)先設(shè)計好的,幾乎是MCU的標(biāo)配,高度集成,使用起來十分方便,但是串口的引腳基本上是固定的,不可以更改。對于硬件橡皮泥——FPGA來說,需要使用HDL從底層串口數(shù)據(jù)幀來實現(xiàn),可以直接在任意一個引腳實現(xiàn)串口功能。為了用Verilog HDL實現(xiàn)標(biāo)準(zhǔn)的串口通訊協(xié)議,我們有必要先來詳細了解一下串口通訊協(xié)議。
串口數(shù)據(jù)幀格式
波特率
波特率,即比特率(Baud rate),即通信雙方“溝通的語言”,通信雙方要設(shè)置為一樣的波特率才可以正常通信。表示每秒發(fā)送的二進制位數(shù),即傳輸1位的時間是:1/波特率秒,如,波特率9600bps,即每秒傳輸9600bit,那么每一位的時間為:1/9600 s = 104.1666us,常用的波特率有:4800/9600/115200/12800等等,也可以根據(jù)需要自定義波特率大小,如1M或者3M,但是有的PC或者USB-TTL模塊不支持太高速度的波特率,常用的USB-TTL芯片有:CH340,CP2102,PL2103,FT232等,其中FT232HL芯片最大支持12M的波特率,當(dāng)然價格也比其他芯片高一些。
起始位和停止位
數(shù)據(jù)幀從起始位開始,到停止位結(jié)束。起始信號用邏輯0表示,而停止位是用邏輯1表示,一般有0.5位、1位、1.5位或2位停止位,常用的一般是1位停止位,只要通信雙方約定一致即可。
數(shù)據(jù)位
起始位之后,緊跟著的是數(shù)據(jù)位,低位(LSB)在前,高位(MSB)在后,一般有5位、6位、7位和8位數(shù)據(jù)位,常用的是8位數(shù)據(jù)位,因為一個字節(jié)正好是8位。
校驗位
校驗位一般用來判斷接收的數(shù)據(jù)位有無錯誤,校驗方法有:奇校驗(odd)、偶校驗(even)、0校驗(space)、1校驗(mark)及無校驗(noparity)。奇校驗要求有效數(shù)據(jù)和校驗位中“1”的個數(shù)為奇數(shù),比如一個8位長的有效數(shù)據(jù)為:01101001,此時共有4個“1”,為達到奇數(shù)個"1"的效果,校驗位為“1”,讓“1”的個數(shù)變成5個(奇數(shù))。偶校驗剛好相反,要求有效數(shù)據(jù)和校驗位的“1”數(shù)量為偶數(shù),則此時為達到偶校驗效果,校驗位為“0”。而0校驗,即校驗位總是為“0”,1校驗校驗位總是為“1”。奇偶校驗邏輯相反,01校驗邏輯相反。一般是奇偶校驗或者是無校驗位。
奇偶校驗的Verilog實現(xiàn)
在Verilog中奇偶校驗的計算非常簡單,根據(jù)奇偶校驗的原理,偶校驗為數(shù)據(jù)位各位異或,奇校驗是偶校驗取反,通過使用單目運算符的縮減功能,可以非常簡單的計算奇偶校驗位:
input[7:0]data_in,//需要發(fā)送的8位數(shù)據(jù)wireeven_bit;//偶校驗位 =各位異或wireodd_bit;//奇校驗位 = ~偶校驗位assigneven_bit=^data_in;//一元約簡運算符,等效于data_in[0] ^ data_in[1] ^ .....assignodd_bit=~even_bit;
wirePOLARITY_BIT=even_bit;//偶校驗
關(guān)于波特率允許的誤差
經(jīng)過我的實際測試,波特率是有一定的容錯范圍的,例如,STM32配置成115200波特率,每10ms發(fā)送一個30字節(jié)的字符串,串口芯片用的CH340,上位機波特率設(shè)置成113000-121000也可以接收,無亂碼,差不多正負2000的波特率,這容錯范圍也太大了,當(dāng)然如果發(fā)送頻率太快,數(shù)據(jù)量太大,誤碼率肯定會大大增加,所以還是建議通信雙方使用同樣的波特率以減少誤差。
串口數(shù)據(jù)的實際波形
使用串口上位機連接USB-TTL模塊,發(fā)送一個字節(jié)數(shù)據(jù):1位停止位+8位數(shù)據(jù)位+1位奇校驗位+1位停止位,使用示波器的單次觸發(fā)功能,可以在USB-TTL模塊的TX引腳測得串口協(xié)議數(shù)據(jù)的實際波形,你知道這發(fā)送的是什么字符嗎?
一個字符的實際波形
兩個字符的實際波形
單工、半雙工、全雙工、異步和同步的區(qū)別
在介紹串口的電平標(biāo)準(zhǔn)之前,先來了解一下串行通信的工作方式,即單工、半雙工、全雙工,異步和同步的區(qū)別。
單工
單工,即數(shù)據(jù)傳輸只在一個方向上傳輸,只能你給我發(fā)送或者我給你發(fā)送,方向是固定的,不能實現(xiàn)雙向通信,如:室外天線電視、調(diào)頻廣播等。
半雙工
半雙工比單工先進一點,傳輸方向可以切換,允許數(shù)據(jù)在兩個方向上傳輸,但是某個時刻,只允許數(shù)據(jù)在一個方向上傳輸,可以基本雙向通信,如:對講機,IIC通信。
全雙工
比半雙工更先進的是全雙工,允許數(shù)據(jù)同時在兩個方向傳輸。發(fā)送和接收完全獨立,在發(fā)送的同時可以接收信號,或者在接收的同時可以發(fā)送。它要求發(fā)送和接收設(shè)備都要有獨立的發(fā)送和接收能力,如:電話通信,SPI通信,串口通信。
同步和異步的區(qū)別
串行通信可以分為兩種類型,一種叫同步通信,另一種叫異步通信。
簡單的說,就是同步通信需要時鐘信號,而異步通信不需要時鐘信號。
·同步:發(fā)送方發(fā)出數(shù)據(jù)后,等接收方發(fā)回響應(yīng)以后才發(fā)下一個數(shù)據(jù)包的通訊方式。
·異步:發(fā)送方發(fā)出數(shù)據(jù)后,不等接收方發(fā)回響應(yīng),接著發(fā)送下個數(shù)據(jù)包的通訊方式。
SPI和IIC為同步通信,UART為異步通信,而USART為同步&異步通信。
·USART:通用同步和異步收發(fā)器
·UART:通用異步收發(fā)器
即USART支持同步和異步收發(fā),而UART只支持異步收發(fā)。
如STM32的串口工作在同步模式時,即智能卡模式時,就需要連接同步時鐘引腳。
常用的串行通信協(xié)議/電平標(biāo)準(zhǔn)
TTL電平
即普通MCU芯片輸出的串口電平,如各MCU輸出的串口信號就是TTL電平。低電平為0-GND,高電平為1-VCC,標(biāo)準(zhǔn)的數(shù)字電路邏輯。特點是速度快,延遲低,但是功耗大。基本上用于板內(nèi)兩個芯片之間短距離通信。
RS232
RS232是工業(yè)上常用的串口標(biāo)準(zhǔn),無論是PLC的232接口,還是工控機上的串口,輸出的串口電平都是232電平標(biāo)準(zhǔn),232標(biāo)準(zhǔn)采用負邏輯電平,即-15~-3v為邏輯1,+3~+15為邏輯0,這里的電平是指RX和TX相對于GND的電壓,可見無論在電壓范圍還是電壓極性上都和TTL不同,顯然這兩種電平不能直接連接,需要使用MAX232類似的電平轉(zhuǎn)換芯片,對兩種電平進行互相轉(zhuǎn)換,全雙工,傳輸距離一般控制在20m以內(nèi),原因是RS-232屬單端信號傳送,存在共地噪聲和不能抑制共模干擾等問題。
RS485
在要求通信距離為幾十米到上千米時,廣泛采用RS-485串行總線標(biāo)準(zhǔn)。RS-485采用平衡發(fā)送和差分接收,因此具有抑制共模干擾的能力。加上總線收發(fā)器具有高靈敏度,能檢測低至200mV的電壓,故傳輸信號能在千米以外得到恢復(fù)。 RS-485采用半雙工工作方式,任何時候只能有一點處于發(fā)送狀態(tài),因此,發(fā)送電路須由使能信號加以控制。RS-485用于多點互連時非常方便,可以省掉許多信號線。應(yīng)用RS-485可以聯(lián)網(wǎng)構(gòu)成分布式系統(tǒng),其允許最多并聯(lián)32臺驅(qū)動器和32臺接收器。
RS422
RS-422和RS-485電路原理基本相同,都是以差分方式發(fā)送和接受,不需要數(shù)字地線。RS-422通過兩對雙絞線可以全雙工工作收發(fā)互不影響,而RS485只能半雙工工作,發(fā)收不能同時進行,但它只需要一對雙絞線。RS422和RS485在19kpbs下能傳輸1200米。RS-422的電氣性能與RS-485完全一樣。主要的區(qū)別在于:RS-422有4根信號線:兩根發(fā)送(Y、Z)、兩根接收(A、B)。由于RS-422的收與發(fā)是分開的所以可以同時收和發(fā)(全雙工)。
串行通信的編碼方式
RZ編碼
RZ編碼也成為歸零碼,歸零碼的特性就是在一個周期內(nèi),用二進制傳輸數(shù)據(jù)位,在數(shù)據(jù)位脈沖結(jié)束后,需要維持一段時間的低電平。如圖:
上圖表示的是單極性歸零碼,即低電平表示0,正電平表示1。對于雙極性歸零碼來說,則是高電平表示1,負電平表示0。如下圖所示:
NRZ編碼
NRZ編碼也成為不歸零編碼,也是我們最常見的一種編碼,即正電平表示1,低電平表示0。它與RZ碼的區(qū)別就是它不用歸零,也就是說,一個周期可以全部用來傳輸數(shù)據(jù),這樣傳輸?shù)膸捑涂梢酝耆谩?/span>
NRZI編碼
NRZI編碼的全稱為反向不歸零編碼,這種編碼方式集成了前兩種編碼的優(yōu)點,即既能傳輸時鐘信號,又能盡量不損失系統(tǒng)帶寬。對于USB2.0通信的編碼方式就是NRZI編碼。其實NRZI編碼方式非常的簡單,即信號電平翻轉(zhuǎn)表示0,信號電平不變表示1。例如想要表示00100010(B),則信號波形如下圖所示:
例如有一段數(shù)據(jù)為:1111 1111 (B)要發(fā)送,則整個傳輸線上的電平狀態(tài)是這樣的:
Manchester編碼
曼徹斯特編碼,又稱數(shù)字雙向碼、分相碼或相位編碼(PE),是一種常用的的二元碼線路編碼方式。常用在以太網(wǎng)通信,列車總線控制,工業(yè)總線等領(lǐng)域。在曼徹斯特編碼中,每一位的中間有一跳變,位中間的跳變既作時鐘信號,又作數(shù)據(jù)信號;從高到低跳變表示“0”,從低到高跳變表示“1”。其中非常值得注意的是,在每一位的"中間"必有一跳變,根據(jù)此規(guī)則,可以得出曼徹斯特編碼波形圖的畫法。例如:傳輸二進制信息0,若將0看作一位,我們以0為中心,在兩邊用虛線界定這一位的范圍,然后在這一位的中間畫出一個電平由高到低的跳變。后面的每一位以此類推即可畫出整個波形圖。舉個圖例吧,若要表示數(shù)據(jù)1001 1010(B),則信號波形圖如下圖所示:
曼徹斯特編碼方式也如前面所說,雖然傳輸了時鐘信號,但也損失了一部分的帶寬,主要表現(xiàn)在相鄰相同數(shù)據(jù)上。但對于高速數(shù)據(jù)來說,這種編碼方式無疑是這幾種編碼方式中最優(yōu)的,相比NRZI編碼,曼徹斯特編碼不存在長時間信號狀態(tài)不變導(dǎo)致的時鐘信號丟失的情況,所以在這種編碼方式在以太網(wǎng)通信中是十分常用的。
串行和并行哪個速度快?
串口,即串行通信接口,與之對應(yīng)的是并行接口。在實際時鐘頻率比較低的情況下,并口因為可以同時傳輸若干比特,速率確實比串口快。但是,隨著技術(shù)的發(fā)展,時鐘頻率越來越高,當(dāng)時鐘頻率提高到一定的程度時,并行接口因為有多條并行且緊密的導(dǎo)線,導(dǎo)線之間的相互干擾越來越嚴(yán)重。而串口因為導(dǎo)線少,線間干擾容易控制,況且加上差分信號的加持,抗干擾性能大大提升,因此可以通過不斷提高時鐘頻率來提高傳輸速率,這就是為什么現(xiàn)在高速傳輸都采用串行方式的原因。例如常見的USB、SATA、PCIe、以太網(wǎng)等。
如果有人問關(guān)于串行傳輸與并行傳輸誰更好的問題,你也許會脫口而出:串行通信好!但是,串行傳輸之所以走紅,是由于將單端信號傳輸轉(zhuǎn)變?yōu)椴罘中盘杺鬏?,并提升了控制器工作頻率的原因,而“在相同頻率下并行通信速度更高”這個基本道理是永遠不會錯的,通過增加位寬來提高數(shù)據(jù)傳輸率的并行策略仍將發(fā)揮重要作用。當(dāng)然,前提是有更好的措施來解決并行傳輸過程中的種種問題。
標(biāo)準(zhǔn)串口協(xié)議的Verilog實現(xiàn)
基于Verilog實現(xiàn)標(biāo)準(zhǔn)串口協(xié)議發(fā)送8位數(shù)據(jù):起始位 + 8位數(shù)據(jù)位 +校驗位 +停止位 = 11位,每1位的時間是16個時鐘周期,所以輸入時鐘應(yīng)該為:波特率*16,帶Busy忙信號輸出。實現(xiàn)方法比較簡單,數(shù)據(jù)幀的拼接、計數(shù)器計時鐘周期,每16個時鐘周期輸出一位數(shù)據(jù)即可。
串口發(fā)送1個字節(jié)實現(xiàn)
/*串口協(xié)議發(fā)送:起始位 + 8位數(shù)據(jù)位 +校驗位 +停止位 = 11位 * 16 = 176個時鐘周期clk頻率 =波特率 * 16*/
moduleuart_tx_8bit(
//inputinputclk,//UART時鐘=16*波特率inputrst_n,input[7:0]data_in,//需要發(fā)送的數(shù)據(jù)inputtrig,//上升沿發(fā)送數(shù)據(jù)//outputoutputbusy,//高電平忙:數(shù)據(jù)正在發(fā)送中outputregtx//發(fā)送數(shù)據(jù)信號);
reg[7:0]cnt;//計數(shù)器regtrig_buf;regtrig_posedge_flag;// reg trig_negedge_flag;regsend;
reg[10:0]data_in_buf;//trig上升沿讀取輸入的字節(jié),拼接數(shù)據(jù)幀wireodd_bit;//奇校驗位 = ~偶校驗位wireeven_bit;//偶校驗位 =各位異或wirePOLARITY_BIT=even_bit;//偶校驗// wire POLARITY_BIT = odd_bit; //奇校驗assigneven_bit=^data_in;//一元約簡,= data_in[0] ^ data_in[1] ^ .....assignodd_bit=~even_bit;assignbusy=send;//輸出的忙信號//起始位+8位數(shù)據(jù)位+校驗位+停止位 = 11位 * 16 = 176個時鐘周期parameterCNT_MAX=176;
always@(posedgeclk)begin
if(!rst_n)
begin
trig_buf0;
trig_posedge_flag0;
// trig_negedge_flag end
else
begin
trig_buftrig;
trig_posedge_flag(~trig_buf)&trig;//在trig信號上升沿時產(chǎn)生1個時鐘周期的高電平// trig_negedge_flag /在trig信號下降沿時產(chǎn)生1個時鐘周期的高電平endend
always@(posedgeclk)begin
if(!rst_n)
send0;
elseif(trig_posedge_flag&(~busy))//當(dāng)發(fā)送命令有效且線路為空閑時,啟動新的數(shù)據(jù)發(fā)送進程send1;
elseif(cnt==CNT_MAX)//一幀資料發(fā)送結(jié)束send0;end
always@(posedgeclk)begin
if(!rst_n)
data_in_buf11'b0;
elseif(trig_posedge_flag&(~busy))//只讀取一次數(shù)據(jù),一幀數(shù)據(jù)發(fā)送過程中,改變輸入無效data_in_buf{1'b1,POLARITY_BIT,data_in[7:0],1'b0};//數(shù)據(jù)幀拼接end
always@(posedgeclk)begin
if(!rst_n)
cnt0;
elseif(!send||cnt>=CNT_MAX)
cnt0;
elseif(send)
cntcnt+1;end
always@(posedgeclk)begin
if(!rst_n)
tx1;
elseif(send)
begin
case(cnt)//1位占用16個時鐘周期0:txdata_in_buf[0];//低位在前,高位在后16:txdata_in_buf[1];//bit0,占用第16~31個時鐘32:txdata_in_buf[2];//bit1,占用第47~32個時鐘48:txdata_in_buf[3];//bit2,占用第63~48個時鐘64:txdata_in_buf[4];//bit3,占用第79~64個時鐘80:txdata_in_buf[5];//bit4,占用第95~80個時鐘96:txdata_in_buf[6];//bit5,占用第111~96個時鐘112:txdata_in_buf[7];//bit6,占用第127~112個時鐘128:txdata_in_buf[8];//bit7,占用第143~128個時鐘144:txdata_in_buf[9];//發(fā)送奇偶校驗位,占用第159~144個時鐘160:txdata_in_buf[10];//發(fā)送停止位,占用第160~167個時鐘CNT_MAX:tx1;//無空閑位default:;
endcase
end
elseif(!send)
tx1;end
endmodule
仿真波形
串口接收1個字節(jié)實現(xiàn)
串口接收部分的實現(xiàn),涉及到串口數(shù)據(jù)的采樣,對于MCU來說,不同單片機集成外設(shè)的處理方式有所不同,具體采樣原理可以參考內(nèi)核的Reference Manual。以傳統(tǒng)51內(nèi)核為例,按照所設(shè)置的波特率,每個位時間被分為16個時間片。UART接收器會在第7、8、9三個時間片進行采樣,按照三取二的邏輯獲得該位時間內(nèi)的采樣結(jié)果。其它一些類型的單片機則可能會更加嚴(yán)苛,例如有些工業(yè)單片機會五取三甚至七取五(設(shè)置成抗干擾模式時)。
本程序中采用的中間值采樣,即取16個時鐘周期中的中間位作為當(dāng)前的采樣值。
//Verilog實現(xiàn)串口協(xié)議接收,帶錯誤指示,校驗錯誤和停止位錯誤/*16個時鐘周期接收1位,中間采樣*/modulemy_uart_rx(
inputclk,//采樣時鐘inputrst_n,inputrx,//UART數(shù)據(jù)輸入outputreg[7:0]dataout,//接收數(shù)據(jù)輸出outputregrx_ok,//接收數(shù)據(jù)有效,高說明接收到一個字節(jié)outputregerr_check,//數(shù)據(jù)出錯指示outputregerr_frame//幀出錯指示);
reg[7:0]cnt;reg[10:0]dataout_buf;
regrx_buf;regrx_negedge_flag;regreceive;
wirebusy;wireodd_bit;//奇校驗位 = ~偶校驗位wireeven_bit;//偶校驗位 =各位異或wirePOLARITY_BIT;//本地計算的奇偶校驗// wire polarity_ok;// assign polarity_ok = (POLARITY_BIT == dataout_buf[9]) ? 1 : 0; //校驗正確=1,否則=0assignbusy=rx_ok;assigneven_bit=^dataout;//一元約簡,= data_in[0] ^ data_in[1] ^ .....assignodd_bit=~even_bit;assignPOLARITY_BIT=even_bit;//偶校驗// assign POLARITY_BIT = odd_bit; //奇校驗parameterCNT_MAX=176;
//rx信號下降沿標(biāo)志位always@(posedgeclk)begin
if(!rst_n)
begin
rx_buf0;
rx_negedge_flag0;
end
else
begin
rx_bufrx;
rx_negedge_flagrx_buf&(~rx);
endend//在接收期間,保持高電平always@(posedgeclk)begin
if(!rst_n)
receive0;
elseif(rx_negedge_flag&&(~busy))//檢測到線路的下降沿并且原先線路為空閑,啟動接收數(shù)據(jù)進程receive1;//開始接收數(shù)據(jù)elseif(cnt==CNT_MAX)//接收數(shù)據(jù)完成receive0;end//起始位+8位數(shù)據(jù)位+校驗位+停止位 = 11位 * 16 = 176個時鐘周期always@(posedgeclk)begin
if(!rst_n)
cnt0;
elseif(!receive||cnt>=CNT_MAX)
cnt0;
elseif(receive)
cntcnt+1;end//校驗錯誤:奇偶校驗不一致always@(posedgeclk)begin
if(!rst_n)
err_check0;
elseif(cnt==152)
begin
// if(POLARITY_BIT == rx)if(POLARITY_BIT!=dataout_buf[9])//奇偶校驗正確err_check1;//鎖存// else// err_check endend//幀錯誤:停止位不為1always@(posedgeclk)begin
if(!rst_n)
err_frame0;
elseif(cnt==CNT_MAX)
begin
if(dataout_buf[10]!=1)//停止位err_frame1;
// else// err_frame /如果沒有接收到停止位,表示幀出錯endend
always@(posedgeclk)begin
if(!rst_n)
dataout11'h00;
elseif(receive)
begin
// if(rx_ok)if(cnt>=137)
dataoutdataout_buf[8:1];//數(shù)據(jù)位:8-1位// else if(!rx_ok)// dataout endend
always@(posedgeclk)begin
if(!rst_n)
rx_ok0;
elseif(receive)
begin
if(cnt>=137)//137-169rx_ok1;
else
rx_ok0;
end
else
rx_ok0;end
//起始位+8位數(shù)據(jù)+奇偶校驗位+停止位 = 11 * 16 = 176位always@(posedgeclk)begin
if(!rst_n)
dataout_buf8'h00;
elseif(receive)
begin
case(cnt)//中間采樣8'd8:dataout_buf[0]rx;//起始位=08'd24:dataout_buf[1]rx;//LSB低位在前8'd40:dataout_buf[2]rx;
8'd56:dataout_buf[3]rx;
8'd72:dataout_buf[4]rx;
8'd88:dataout_buf[5]rx;
8'd104:dataout_buf[6]rx;
8'd120:dataout_buf[7]rx;
8'd136:dataout_buf[8]rx;//MSB高位在后8'd152:dataout_buf[9]rx;//奇偶校驗位8'd168:dataout_buf[10]rx;//停止位=1default:;
endcase
endend
endmodule
【文章福利】:小編整理了一些個人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!~點擊綠色通訊軟件搜索airuimcu加入。