基于LabWindows/CVI的RS232串口通信的實現(xiàn)

? ? ? ?虛擬儀器(Virtual Instruments)是80年代末出現(xiàn)的概念,即在通用硬件平臺上通過更改軟件功能,設(shè)計出不同功能的測試儀器,能大幅縮短研發(fā)周期,降低成本。NI公司的LabWindows/CVI具有強大的圖形界面設(shè)計功能,以ANSIC為核心,提供了豐富的庫函數(shù)與儀器驅(qū)動。
? ? ? RS-232標(biāo)準(zhǔn)接口(又稱EIA RS-232)是常用的串行通信接口標(biāo)準(zhǔn)之一,它是由美國電子工業(yè)協(xié)會(EIA)聯(lián)合貝爾系統(tǒng)公司、調(diào)制解調(diào)器廠家及計算機終端生產(chǎn)廠家于1970年共同制定,其全名是“數(shù)據(jù)終端設(shè)備( DTE)和數(shù)據(jù)通信設(shè)備(DCE)之間串行二進制數(shù)據(jù)交換接口技術(shù)標(biāo)準(zhǔn)”。下面小編給大家介紹一下“rs232串口定義 ”。
? ? ? 一、rs232串口定義
? ? ? 在串行通訊時,要求通訊雙方都采用一個標(biāo)準(zhǔn)接口,使不同的設(shè)備可以方便地連接起來進行通訊。RS-232-C接口(又稱EIARS-232-C)是目前最常用的一種串行通訊接口。計算機串口(RS232)共有9個針腳,都是按順序排列,各個針腳的定義如下:
? ? ??? 1、針腳1的定義 :
? ? ?? ?載波檢測(DCD) ,接收線信號檢出(Received Line detection-RLSD)。
? ? ? ??2、針腳2 的定義:
? ? ? ?接受數(shù)據(jù)(RXD) ,為接收數(shù)據(jù)的引腳。
? ? ?? 3、針腳3 的定義:
? ? ? ?發(fā)出數(shù)據(jù)(TXD) ,為發(fā)送數(shù)據(jù)的引腳。
? ? ? ? 4、針腳4的定義:
? ? ? ?數(shù)據(jù)終端準(zhǔn)備好(DTR) ,數(shù)據(jù)終端就緒的首字母縮略詞。
? ? ? ?5、針腳5的定義:
? ? ?? 信號地線(SG)
? ? ? ? 6、針腳6的定義 :
? ? ? ?數(shù)據(jù)準(zhǔn)備好(DSR) ,當(dāng)調(diào)制/解調(diào)器啟動時,在經(jīng)過自身檢測后,用DSR來聲明已經(jīng)準(zhǔn)備就緒。
? ? ? ? 7、針腳7的定義 :
? ? ? ? 請求發(fā)送(RTS) ,取得發(fā)送信息。
? ? ? ??8、針腳8的定義:
? ? ? ?清除發(fā)送(CTS) ,清除數(shù)據(jù)。
? ? ? ? 9、針腳9的定義 :
? ? ? ?振鈴指示(RI) ,發(fā)出提示。

? ? ? ?二 、串口的相關(guān)函數(shù):
? ? ? ?串口是一種常見的通信總線技術(shù),其支持全雙工模式,且只支持一對一的訪問模式,大部分設(shè)備都支持串口通訊,可通過串口控制設(shè)備或采集數(shù)據(jù)。下面將介紹LabwindowsCVI對串口的支持。
? ? ? ?1、打開串口函數(shù)OpenComConfig,相關(guān)定義如下:
int OpenComConfig (int portNumber, char deviceName[], long baudRate, int parity, int dataBits, int stopBits, int inputQueueSize, int outputQueueSize);
——int portNumber? 需要開啟的串口號
——char deviceName[] 將要打開的串口號的名稱,比如串口號1,名稱為”COM1”
——long baudRate? 設(shè)置串口讀數(shù)的速度,波特率:110, 150, 300, 600,?? 1,200, 2,400, 4,800, 9,600, 14,400, 19,200, 28,800, 38,400, 56,000, 57,600, 115,200, 128,000, and 256,000,默認值為9600。
——int parity? 選擇串口的校驗?zāi)J剑?Default Value: 0—no parity;Valid Values:0 = no parity,1 = odd parity,2 = even parity,3 = mark parity,4 = space parity
——int dataBits? 數(shù)據(jù)位數(shù)?? Default Value: 7 data bits;Valid Values: 5,6,7 or 8 data bits
——int stopBits? 停止位? Default Value: 1 stop bit ;Valid Values: 1 or 2 stop bits
——int inputQueueSize?? 串口輸入的數(shù)據(jù)量,一般選擇的4,096
—— int outputQueueSize?? 串口輸出的數(shù)據(jù)量,一般選擇的4,096
? ? ? 2、串口關(guān)閉函數(shù)CloseCom
????? int CloseCom (int portNumber);
? ? ? int portNumber 是剛剛開啟的串口號。在串口使用完后,要即使對串口關(guān)閉,避免在后面使用的時候,再次打開錯誤!
? ? ? 3、設(shè)置超時函數(shù)SetComTime
???? ? int SetComTime (int portNumber, double timeoutSeconds);
????? int portNumber 為開啟的串口號
??? ??double timeoutSeconds 時間,單位為s
????? 此函數(shù)用在input/ouput數(shù)據(jù)的輸入輸出的時候,為讀取操作設(shè)定一個時間限制,如果在這個時間段中,如果讀取的數(shù)據(jù)位空,串口中數(shù)據(jù)為空的時候,沒有完成讀取,則時間溢出。
? ? ? 4、寫數(shù)據(jù)到串口ComWrt ,ComWrt Byte
? ?(1)int ComWrt (int portNumber, char buffer[], int count);
????? 功能:寫一串?dāng)?shù)據(jù)到開啟的串口的數(shù)據(jù)隊列中去。數(shù)據(jù)位字符的形式傳輸。
????? int portNumber 開啟的串口號;
????? char buffer[]存儲待傳輸?shù)臄?shù)據(jù);
????? int count 數(shù)據(jù)的長度
??????? 返回值:返回傳輸數(shù)據(jù)個數(shù)count表示傳輸成功,否則傳輸失敗或沒有傳輸完。
? ? ?(2)int ComWrtByte (int portNumber, int byte);
????? 功能:寫一個int byte數(shù)據(jù)到int portNumber串口中去。
????? 雖然寫的數(shù)據(jù)為int型,但是被傳輸出去的僅僅是int型數(shù)據(jù)的低8位,高8位字符自動屏蔽,為0。
? ? ? 5、讀取串口數(shù)據(jù)ComRd,ComRdByte
? ?(1)int ComRd (int portNumber, char buffer[], int count);
????? 功能:將串口portNumber的輸入隊列中讀取conut個數(shù)據(jù)到buffer中存儲,返回值:讀取正確返回數(shù)據(jù)的個數(shù)count,否則返回值錯誤!
? ?(2)int ComRdByte (int portNumber);
????? 功能:從串口號portNumber的輸入隊列中讀取一個數(shù)據(jù),并保存為int類型,讀取的為一個char型的數(shù)據(jù),即將8位的數(shù)據(jù)存在int型的低8位中。
? ? ? ? 三 、RS232串口編程實例:
? ? ? ? 利用LabWindows/CVI的RS-232函數(shù)庫進行串口應(yīng)用程序進行編程時,主要包括以下幾個步驟:首先要對串行口進行配置,然后利用該串行口進行收發(fā)數(shù)據(jù),程序結(jié)束之前應(yīng)當(dāng)關(guān)閉該串行口。本實例利用同步方式進行RS-232串口數(shù)據(jù)傳輸,實例所用的設(shè)備為γ輻射個人劑量當(dāng)量監(jiān)測儀,該設(shè)備通過micro usb接口數(shù)據(jù)線與計算機連接,程序前面板如下:

? ? ? ?通過單擊“開始測量”按鈕,設(shè)備測量的數(shù)據(jù)可以實時的顯示在上位機程序前面板上,主函數(shù)代碼如下:
int main (int argc, char *argv[])
{
??? if (InitCVIRTE (0, argv, 0) == 0)
????????? return -1;? /* out of memory */
??? if ((panelHandle = LoadPanel (0, "劑量率.uir", PANEL)) < 0)
????????? return -1;
??? OpenComConfig (3, "com3", 9600, 0, 8, 2, 512, 512);
??? SetCTSMode (3,LWRS_HWHANDSHAKE_OFF) ;
??? FlushInQ (3);
??? FlushOutQ (3);
??? menubar = GetPanelMenuBar (panelHandle);
??? Radio_ConvertFromTree ( panelHandle,? PANEL_RADIOGROUP);
??? GetCurrentDateTime (&currDateTime);
??? SetCtrlAttribute (panelHandle, PANEL_STRIPCHART, ATTR_XAXIS_OFFSET, currDateTime);
???
??? /*創(chuàng)建一個默認定時間隔為系統(tǒng)異步定時器精度的異步定時器,初始狀態(tài)為停止*/
??? TimerID1 = NewAsyncTimer(resolution1, -1, 0, AsyncTimerEventFunction1, 0);
??? TimerID2 = NewAsyncTimer(resolution2, -1, 0, AsyncTimerEventFunction2, 0);
???
??? GetAsyncTimerResolution(&resolution1);?
??? TimerID1 = NewAsyncTimer(resolution1, -1, 0, AsyncTimerEventFunction1, 0);
??? SetAsyncTimerAttribute (TimerID1, ASYNC_ATTR_INTERVAL, 1.0);
??? SetAsyncTimerAttribute (TimerID1, ASYNC_ATTR_ENABLED, 1);
???
??? GetAsyncTimerResolution(&resolution2);?
??? TimerID2 = NewAsyncTimer(resolution2, -1, 0, AsyncTimerEventFunction2, 0);
??? SetAsyncTimerAttribute (TimerID2, ASYNC_ATTR_INTERVAL, 1.0);
??? SetAsyncTimerAttribute (TimerID2, ASYNC_ATTR_ENABLED, 0);
??? SetCtrlAttribute (panelHandle, PANEL_Start, ATTR_DIMMED, 0);
??? SetCtrlAttribute (panelHandle, PANEL_Stop, ATTR_DIMMED, 0);
???
??? DisplayPanel (panelHandle);
??? RunUserInterface ();
??? CloseCom(3);
??? DiscardPanel (panelHandle);
??? return 0;
}
ComCallback函數(shù)部分代碼如下:

void CVICALLBACK ComCallback (int portNo, int eventMask,void *callbackData)
{
? ? double val=0;
??? char buffer[26]={0};
???
??? int i=0;
??? int len=0;
??? double buf1=0,buf2=0,buf3=0,buf4=0,buf=0;
??? int h=0,m=0,s=0;
??? int numLines;
?
??? char hour[6],minute[6],second[6],message[40]="";
??? char data[25]="";
??? char filename[260];
??? len=GetInQLen (3);
???
??? if(len)
??? {
??? ?? ComRd (3, buffer, 26);???
??? ??
??? ?? SetCtrlAttribute (panelHandle, PANEL_TIMER, ATTR_ENABLED, 1);
??? ??
??? ?? buf1=buffer[3]&0x0f;
?????? buf2=buffer[4]&0x0f;
?????? buf3=buffer[5]&0x0f;
?????? buf4=buffer[6]&0x0f;
??? ?? buf=buf1+buf2+buf3+buf4;
??? ?? val=buf;
??? ?? val=val/100;
??? ?? ????? ???
??? ?? datatemp[num-1]=val;
??? ?? PlotStripChartPoint (panelHandle,PANEL_STRIPCHART,val);
……
}
? ? ? 開始測量的代碼如下:
int CVICALLBACK Start (int panel, int control, int event,
? ?void *callbackData, int eventData1, int eventData2)
{
switch (event)
{
case EVENT_COMMIT:
? ? InstallComCallback (3, LWRS_RXCHAR, 0, '\0', ComCallback, 0);
? ? SetMenuBarAttribute (menubar, MENUBAR_MENU1_ITEM1, ATTR_DIMMED, 1);
? ? SetMenuBarAttribute (menubar, MENUBAR_MENU1_ITEM2, ATTR_DIMMED, 0);
? ? testing();
break;
}
return 0;
}
? ? ? ??四、結(jié)論
? ? ? ? 本文利用LabWindows/CVI開發(fā)平臺編寫了上位機PC程序,利用LabWindows/CVI實現(xiàn)串口通信,充分發(fā)揮了虛擬儀器開發(fā)的便捷功能,完成了實時性控制工作。相比于使用組態(tài)王等軟件,其功能更為豐富,并且可以充分利用多線程技術(shù),合理分配多個實時性任務(wù),保證多個并發(fā)任務(wù)順利執(zhí)行。