版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、工控程序設(shè)計1學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理2學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理2.2.1 學(xué)習(xí)要點 1.知識點:SerialPort類實例的構(gòu)造,接收串口數(shù)據(jù)的方法,接收超時異常處理,HSDZC電能綜合測試儀的數(shù)據(jù)格式,數(shù)據(jù)幀片段的緩存方法 2.技能點:應(yīng)用程序工程和SerialPort對象的創(chuàng)立,串口數(shù)據(jù)接收,接收數(shù)據(jù)的緩存和數(shù)據(jù)幀的提取2.2.2 任務(wù)描述 某些串口設(shè)備能夠定時、主動地向上位機(jī)發(fā)送數(shù)據(jù),處于上位機(jī)端的工業(yè)控制程序,需要獲取串口收到的數(shù)據(jù)并進(jìn)行分析和處理。利用.NET Framework 2.0及更高版本提供的SerialPort類可以比較方便地在C#應(yīng)用程
2、序中實現(xiàn)串口通信功能。從編程的角度看,串口數(shù)據(jù)的接收就是利用SerialPort對象的Read或ReadByte方法將操作系統(tǒng)存放在串口輸入緩沖區(qū)中的數(shù)據(jù)讀入到一個字節(jié)數(shù)組中。 該教學(xué)情景通過串口數(shù)據(jù)接收、接收數(shù)據(jù)的緩存、數(shù)據(jù)幀的提取、浮點數(shù)解碼這幾個實施步驟,到達(dá)使用SerialPort對象接收單個串口設(shè)備(下位機(jī))數(shù)據(jù)的目的。 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理2.2.3 相關(guān)知識 1 SerialPort類實例的構(gòu)造 SerialPort類是從.NET Framework 2.0版本開始提供的一個串口控制類,該類包含在System.IO.Ports命名空間中,使用該類的實例可以翻開
3、串口,并發(fā)送數(shù)據(jù)。 通過構(gòu)造函數(shù)可以產(chǎn)生SerialPort類的實例,SerialPort類的構(gòu)造函數(shù)在定義時進(jìn)行了重載,表2.2.1中列出了這些重載構(gòu)造函數(shù)的接口定義: 表2.2.1 SerialPort類的構(gòu)造函數(shù)定義表2.2.1 SerialPort類的構(gòu)造函數(shù)定義構(gòu)造函數(shù)的接口定義功能說明public SerialPort();使用默認(rèn)屬性值創(chuàng)建SerialPort類的新實例,其中數(shù)據(jù)位數(shù)的默認(rèn)值為 8,校驗位的默認(rèn)值為 None,停止位的默認(rèn)值為 1,默認(rèn)端口名稱為 COM1。學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理public SerialPort(string portName)
4、; 使用指定的端口名稱初始化 SerialPort 類的新實例,其它參數(shù)采用默認(rèn)值 public SerialPort(string portName, int baudRate); 使用指定的端口名稱和波特率初始化 SerialPort 類的新實例,其它參數(shù)采用默認(rèn)值 public SerialPort(string portName, int baudRate, Parity parity); 使用指定的端口名稱、波特率和奇偶校驗位初始化 SerialPort 類的新實例,其它參數(shù)采用默認(rèn)值 public SerialPort(string portName, int baudRate,
5、Parity parity, int dataBits); 使用指定的端口名稱、波特率、校驗位和數(shù)據(jù)位初始化 SerialPort 類的新實例,其它參數(shù)采用默認(rèn)值 public SerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits); 使用指定的端口名稱、波特率、奇偶校驗位、數(shù)據(jù)位和停止位初始化SerialPort 類的新實例 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 除了在構(gòu)造SerialPort類實例的時候可以對端口名稱、波特率、奇偶校驗位、數(shù)據(jù)位和停止位進(jìn)行設(shè)置外,
6、構(gòu)造好SerialPort類實例后,還可以通過PortName、BaudRate、Parity、DataBits、StopBits屬性對這些參數(shù)進(jìn)行修改,因此構(gòu)造SerialPort類實例的程序書寫形式比較靈活。 2 串口的翻開和關(guān)閉SerialPort類中與串口翻開和關(guān)閉相關(guān)的成員如下: (1)Open方法Open方法翻開新的串口連接,該方法不帶參數(shù),接口定義如下:public void Open() (2)Close方法Close方法關(guān)閉已經(jīng)翻開的串口連接,該方法不帶參數(shù),接口定義如下:public void Close()學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 (3)IsOpen屬性通
7、過IsOpen屬性可以獲知串口當(dāng)前是否為翻開狀態(tài),返回一個bool類型的值,該屬性只讀,接口定義如下: public bool IsOpen get; 串口不能重復(fù)進(jìn)行翻開和關(guān)閉操作,在翻開或關(guān)閉串口前,都要使用該屬性檢查串口是否已經(jīng)處于翻開或已經(jīng)處于關(guān)閉狀態(tài),以免引發(fā)異常。 3 接收串口數(shù)據(jù)的方法 (1)ReadByte方法 SerialPort類的ReadByte方法可以從串口接收緩沖區(qū)中讀取一個字節(jié),該方 法的接口定義是: public int ReadByte(); 該方法從串口接收緩沖區(qū)中讀取一個字節(jié),要和ReadTimeout屬性配合使用。當(dāng)調(diào)用ReadByte方法時,如果接收緩沖
8、區(qū)中沒有數(shù)據(jù),則程序被阻塞,直到緩沖區(qū)中有數(shù)據(jù)或到達(dá)ReadTimeout屬性指定讀取數(shù)據(jù)超時的毫秒數(shù),程序才能繼續(xù)運(yùn)行。學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 ReadByte方法返回一個int類型的值,在實際應(yīng)用時,要將返回值強(qiáng)制轉(zhuǎn)換為byte類型。 (2)Read方法Read方法從串口接收緩沖區(qū)中讀取多個字節(jié),該方法的接口定義是: public int Read(byte buffer, int offset, int count); 該方法試圖從接收緩沖區(qū)中讀取count個字節(jié),并寫入字節(jié)數(shù)組buffer中,寫入的起始位置是offset,執(zhí)行后返回實際讀取的字節(jié)數(shù)。例如,現(xiàn)在接收緩沖
9、區(qū)中只有6個字節(jié),但count參數(shù)值為10,則返回值為6。 在實際應(yīng)用時,通常先通過SerialPort對象的BytesToRead屬性獲得接收緩沖區(qū)中已有的字節(jié)數(shù),并根據(jù)該屬性值來設(shè)置count參數(shù)。和ReadByte方法不同的是,調(diào)用Read方法時,不管接收緩沖區(qū)中有無數(shù)據(jù),都不會對應(yīng)用程序的當(dāng)前線程造成阻塞。學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理4 接收超時異常處理 當(dāng)使用ReadByte方法從接收緩沖區(qū)中讀取一個字節(jié)時,如果下位機(jī)發(fā)送過來的數(shù)據(jù)沒有在ReadTimeout規(guī)定的時間內(nèi)到達(dá),則會引發(fā)TimeoutException,應(yīng)用程序可以捕獲該異常,并作相應(yīng)處理。下面的測試程序說
10、明了超時異常處理的方法:SerialPort sp;private void btnStart_Click (object sender, EventArgs e) byte firstByte; sp.ReadExisting(); /清空接收緩沖區(qū),準(zhǔn)備接收數(shù)據(jù) sp.ReadTimeout = 10000; /10秒內(nèi)沒有收到回復(fù)數(shù)據(jù),將捕獲到異常 try firstByte = (byte)sp.ReadByte(); /同步讀?。ǔ绦蛟诖吮蛔枞?t1.Text = firstByte.ToString(X2); /顯示在文本框t1中 catch (TimeoutException
11、ex) /捕獲到接收超時異常 t1.Text = ex.Message; /在t1中顯示異常信息 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 圖2.2.1 接收超時異常測試 如上圖所示,在點擊“開始按鈕后,程序被阻塞,此時窗口對鼠標(biāo)和鍵盤的輸入都不響應(yīng)。為了有足夠操作時間,SerialPort對象sp的ReadTimeout屬性為10000毫秒(10秒)。在10秒時間內(nèi),測試者可以通過串口測試程序發(fā)送一個或多個字節(jié)過來,此時程序結(jié)束阻塞狀態(tài)繼續(xù)運(yùn)行,并在文本框中顯示接收到的第1個字節(jié);如果10秒內(nèi)沒有數(shù)據(jù)到達(dá),則引發(fā)TimeoutException。 假設(shè)上位機(jī)程序要一直等待,可以把ReadTi
12、meout屬性的值設(shè)置為-1,但在實際應(yīng)用中一般不這樣做。學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理5 HSDZC電能綜合測試儀的數(shù)據(jù)格式 HSDZC電能綜合測試儀在鉆機(jī)性能測試系統(tǒng)中用于輸入功率、輸出功率以及功率因素(參見引言介紹)。該設(shè)備提供兩種電腦測量方式,在儀表提示“測量方式時,可以分別按“顯示1和“顯示2進(jìn)入。 在測量方式1的情況下測試儀每秒通過RS-232接口發(fā)送1組數(shù)據(jù),長度46字節(jié)。信號格式:開始4字節(jié)均為FFH,后續(xù)每三個字節(jié)構(gòu)成一個浮點數(shù)值,分別表示I1、U1、I2、U2、I3、U3,以及功率因數(shù)、視在功率、效率、輸入功率、無功功率、負(fù)載率、輸出功率、轉(zhuǎn)速,共14個數(shù)據(jù)。 在
13、測量方式2的情況下測試儀也是每秒通過RS-232接口發(fā)送1組數(shù)據(jù),長度30字節(jié)。信號格式:開始3字節(jié)均為12H、34H、56H,后續(xù)每三個字節(jié)構(gòu)成一個浮點數(shù)值,分別表示I1、U1、P1、I2、U2、P2、I3、U3、P3,共9個數(shù)據(jù)。 上位機(jī)在和HSDZC電能綜合測試儀進(jìn)行通信時,不需要向設(shè)備寫入數(shù)據(jù),而是被動地讀取設(shè)備發(fā)送過來的數(shù)據(jù)。下面的相關(guān)知識將進(jìn)一步介紹對已接收到數(shù)據(jù)的存儲和處理方法。學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理構(gòu)成浮點數(shù)值的3個字節(jié)含義是:第1字節(jié)(B1)為尾數(shù)低位,第2字節(jié)(B2)為尾數(shù)高位,第3字節(jié)(B3)為階碼指數(shù)。其中階碼指數(shù)各位的含義如表2.2.2所示: 表2.
14、2.2 階碼指數(shù)字節(jié)中各位的含義D7 D6 D5-D0 數(shù)值符號:0為正,1為負(fù) 階碼符號:0為正,1為負(fù) 階碼數(shù)值 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 尾數(shù)B的值在0到1之間,計算公式是: 下面的HexToFloat函數(shù)描述了將3個字節(jié)轉(zhuǎn)換為浮點數(shù)的算法:private float HexToFloat(byte B1, byte B2, byte B3) float f, B, n; /B:尾數(shù) n:階碼指數(shù) B = (B2 * 256 + B1) / 65536F; if (B3 & 0 x80) != 0) /如果D7為1,等價于 if(B3=128) B = -B; B3 =
15、(byte)(B3 & 0 x7F); /等價于B3=(byte)(B3-128) if (B3 & 0 x40) != 0) /如果D6為1 B3 = (byte)(B3 & 0 xBF); n = -B3; else n = B3; f = B * (float)Math.Pow(2, n); /B乘以2的n次方 return f;學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理6 數(shù)據(jù)幀片段的緩存方法 (1)使用集合類存儲接收數(shù)據(jù) 在通信過程中,數(shù)據(jù)幀表示由多個字節(jié)構(gòu)成的,具有一定格式,表示完整語意的一組數(shù)據(jù)。例如,在和HSDZC電能綜合測試儀進(jìn)行通信時,如果測試儀工作在測量方式1,則一幀數(shù)據(jù)的
16、長度為46個字節(jié)(包含起始標(biāo)志和14個數(shù)值)。 在系統(tǒng)實際運(yùn)行中,下位機(jī)向上位機(jī)發(fā)送數(shù)據(jù)時,可能會將數(shù)據(jù)幀分為幾個片段依次發(fā)送,或者在一次接收到的數(shù)據(jù)中包含了不止一幀數(shù)據(jù)。上位機(jī)必須提供一個字節(jié)的集合來對接收到的數(shù)據(jù)進(jìn)行緩存(暫存),在確認(rèn)接收完畢一幀數(shù)據(jù)后,再進(jìn)行進(jìn)一步的分析和處理。 .NET Framework 2.0以上版本提供了List類來實現(xiàn)集合元素管理。List類支持泛型,在存取byte類型的集合元素時無需進(jìn)行“裝箱和“拆箱操作,比使用ArrayList效率高。學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 List類提供了豐富的方法來對集合中的元素進(jìn)行操作,表2.2.3列出了List類
17、的常用方法,表中的例子建立在如下定義的根底上: byte b; byte ba; List li = new List(); /創(chuàng)立List類的實例li,元素類型為byte 表2.2.3 List類的常用方法方法的接口定義 功能說明 示 例 public void Add(T item); 在集合末尾添加元素item li.Add(b); 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理public void AddRange( IEnumerable collection); 在集合末尾添加另一個集合collection li.AddRange(ba); public void Insert(int
18、 index, T item); 在index位置插入元素item li.Insert(0,b) public void InsertRange(int index, IEnumerable collection); 在index位置插入另一個集合collection li.InsertRange(0,ba) public void RemoveAt(int index); 刪除下標(biāo)位置index處的元素 li.RemoveAt(2); public void RemoveRange(int index, int count); 刪除從下標(biāo)位置index開始的count個元素 li.Remov
19、eRange(2,3); public void Clear(); 刪除集合中的所有元素 li.Clear(); 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理public T thisint index get; set; 獲取或設(shè)置下標(biāo)為index的元素值 li3=b;b=li3; public int IndexOf(T item); 自左向右查找值為item的第一個元素,返回其下標(biāo) idx=li.IndexOf(0 x7F); public int IndexOf(T item, int index); 從下標(biāo)位置index開始,自左向右查找值為item的第一個元素,返回其下標(biāo) idx=li
20、.IndexOf(0 x7F,3); public int LastIndexOf(T item);自右向左查找值為item的第一個元素,返回其下標(biāo) idx=li.LastIndexOf (0 x7F);public int LastIndexOf (T item, int index); 從下標(biāo)位置index開始,自右向左查找值為item的第一個元素,返回其下標(biāo) idx=li.LastIndexOf (0 x7F,3); 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 (2)集合大小的設(shè)置 為了保證集合中任何時候能容納一個完整的數(shù)據(jù)幀,集合中能容納的字節(jié)數(shù)量應(yīng)為數(shù)據(jù)幀長度的兩倍。集合中的數(shù)據(jù)采取隊
21、列形式進(jìn)行處理,新來的數(shù)據(jù)從隊尾進(jìn),如果原有數(shù)據(jù)字節(jié)數(shù)加上新接收字節(jié)數(shù)超過集合的最大容量,則將隊首的部份數(shù)據(jù)刪除。圖2.2.2展示數(shù)據(jù)入隊和出隊的過程: L-隊列總?cè)萘?N-原有字節(jié)數(shù) M-新接收字節(jié)數(shù) (1)隊列剩余空間能容納新接收數(shù)據(jù) L-隊列總?cè)萘?N-原有字節(jié)數(shù) M-新接收字節(jié)數(shù) (2)隊列剩余空間能容納新接收數(shù)據(jù) 圖2.2.2 新接收數(shù)據(jù)的緩存學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理2.2.4 任務(wù)實施 1應(yīng)用程序工程的創(chuàng)立 串口通信應(yīng)用程序的開發(fā)在Visual Studio集成開發(fā)環(huán)境中進(jìn)行,首先創(chuàng)立一個基于C#語言的“Windows應(yīng)用程序工程,名為“ReceiveData,并存
22、放在工作目錄“F:SerialPort下,如圖2.2.3所示:學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 2 SerialPort對象的創(chuàng)立 創(chuàng)立SerialPort對象可以通過添加控件和編寫代碼兩種方式,添加控件的方式相對簡單,適合初學(xué)者練習(xí);編寫代碼的方式具有較強(qiáng)的靈活性,可以把SerialPort對象對串口的操作細(xì)節(jié)隱藏起來,與數(shù)據(jù)編碼、解碼等功能一起封裝為一個功能完整的串口通信模塊。 (1)通過添加控件創(chuàng)立SerialPort對象在“工具箱中展開“組件選項卡,選擇“SerialPort組件(如圖 2.2.4),用鼠標(biāo)拖動到設(shè)計視圖中的窗口上。由于SerialPort是不可見組件,所以不直
23、接出現(xiàn)在窗體上,而是出現(xiàn)在窗口下方,如圖2.2.5所示。該操作的實質(zhì)是在窗體設(shè)計器的源代碼(文件名Form1.Designer.cs)中添加了如下代碼:private System.IO.Ports.SerialPort serialPort1;this.serialPort1 = new System.IO.Ports.SerialPort(ponents);實質(zhì)上是定義并實例化了一個名為serialPort1的SerialPort對象。 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 (2)編寫代碼創(chuàng)立SerialPort對象 切換到代碼視圖,在Form1.cs中編寫上述代碼同樣可以創(chuàng)立Seri
24、alPort對象。首先在最前面引入System.IO.Ports命名空間: using System.IO.Ports; 然后定義SerialPort類的對象sp,作為Form1類的私有成員: private SerialPort sp; 最后在Form1類的構(gòu)造函數(shù)中創(chuàng)立對象: public Form1() InitializeComponent(); sp = new SerialPort(); 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 2.2.4 選擇SerialPort組件學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 2.2.5 將SerialPort組件參加窗體中當(dāng)然,工程實踐中,Ser
25、ialPort對象不一定在窗體類中定義。如果工程代碼量大,可以專門建立一個負(fù)責(zé)串口通信和調(diào)度的類,在里面定義一個或多個SerialPort對象作為該類的成員。學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理3 串口數(shù)據(jù)的接收 在下面的程序中,當(dāng)點擊“開始接收按鈕時,程序調(diào)用SerialPort對象的ReadByte方法,阻塞當(dāng)前線程,并開始接收下位機(jī)發(fā)送的數(shù)據(jù)。如果在10秒內(nèi)接收到數(shù)據(jù),則將接收到的數(shù)據(jù)以十六進(jìn)制方式顯示在文本框中,否則在文本框中顯示“操作超時異常提示。 在編寫程序之前,先在系統(tǒng)中安裝虛擬串口對COM1和COM2,本程序連接COM1,串口測試程序連接COM2。程序界面如以下圖: 圖2.
26、2.6 串口數(shù)據(jù)的接收學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理其中文本框名字為t1,按鈕名字為btnStart,對應(yīng)的后臺代碼如下:private SerialPort sp;private void Form1_Load(object sender, EventArgs e) sp = new SerialPort(COM1, 9600, Parity.None, 8, StopBits.One); sp.Open();private void Form1_FormClosing(object sender, FormClosingEventArgs e) if (sp != null &
27、sp.IsOpen) sp.Close(); /關(guān)閉串口private void btnStart_Click(object sender, EventArgs e) byte first; byte tmp; sp.ReadTimeout = 10000; /10秒內(nèi)沒有收到回復(fù)數(shù)據(jù),將捕獲到異常 try學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 first = (byte)sp.ReadByte(); /同步讀?。ǔ绦蛟诖吮蛔枞?tmp = new bytesp.BytesToRead + 1; tmp0 = first; sp.Read(tmp, 1, tmp.Length - 1);
28、/讀取剩余字節(jié)到tmp數(shù)組中 /接收的數(shù)據(jù)以十六進(jìn)制形式顯示在文本框t1中 t1.Text = CCheck.BinaryToHexString(tmp); catch (TimeoutException ex) t1.Text = ex.Message; /在文本框t1中顯示異常信息 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理/以下代碼包含在CCheck類中:public class CCheck /字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串 public static string BinaryToHexString(byte buff) StringBuilder tmp = new StringBui
29、lder(); for (int i = 0; i buff.Length; i+) tmp.Append(buffi.ToString(X2) + ); return tmp.ToString().Trim(); 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 該程序在點擊“開始接收按鈕后會停止對用戶輸入的響應(yīng),這是因為調(diào)用ReadByte方法造成當(dāng)前線程被阻塞,直到下位機(jī)發(fā)送的數(shù)據(jù)到達(dá),或接收超時才解除阻塞。 實際操作時,先運(yùn)行該程序,再翻開串口測試工具,并連接COM2,在測試工具中輸入一些數(shù)據(jù),做好發(fā)送的準(zhǔn)備工作。在程序點擊“開始接收按鈕后,立即切換到串口測試工具,并點擊“發(fā)送按鈕,就可以在程
30、序中看到發(fā)送過來的數(shù)據(jù)?!鞍l(fā)送操作要在10秒內(nèi)完成,否則會引起“接收超時異常。4接收數(shù)據(jù)的緩存和數(shù)據(jù)幀的提取 (1)創(chuàng)立數(shù)據(jù)接收隊列 CRecvBuf是一個用于緩存接收數(shù)據(jù)的類,利用List類來實現(xiàn)。在創(chuàng)立該類的實例時,要指定參數(shù)maxLength,表示隊列的總?cè)萘浚磮D2.2.1中的參數(shù)L)。每當(dāng)接收到一段數(shù)據(jù),就調(diào)用Add方法將收到的數(shù)據(jù)添加到隊列中,Add方法中判斷添加數(shù)據(jù)后字節(jié)數(shù)是否超過maxLength,并將超出部份從隊首刪除。學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理class CRecvBuf public List li; public int maxLength; public
31、 CRecvBuf(int maxLength) li = new List(); this.maxLength = maxLength; public void Add(byte b) if (b.Length maxLength) throw new Exception(接收到的數(shù)據(jù)量超出緩沖區(qū)長度); li.AddRange(b); if (li.Count maxLength) li.RemoveRange(0, li.Count - maxLength); 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理(2) 使用數(shù)據(jù)接收隊列 當(dāng)HSDZC電能綜合測試儀工作在“測量方式2的情況下,使用下面
32、的程序可以接收數(shù)據(jù),并使用前面設(shè)計的CRecvBuf類的實例緩存接收到的數(shù)據(jù),再從中提取出一個完整數(shù)據(jù)幀。程序運(yùn)行界面如圖2.2.7: 2.2.7 利用隊列緩存接收數(shù)據(jù)學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 當(dāng)按下“開始按鈕時,上位機(jī)準(zhǔn)備接收數(shù)據(jù),等待時間為10秒,此時通過串口測試程序按HSDZC電能綜合測試儀工作在“測量方式2時的數(shù)據(jù)格式,向上位機(jī)發(fā)送一個數(shù)據(jù)片段。上位機(jī)采用3個步驟處理接收數(shù)據(jù):第1步接收到下位機(jī)發(fā)送的數(shù)據(jù);第2步將接收的數(shù)據(jù)添加到隊列中;第3步從隊列中根據(jù)起始標(biāo)志和約定數(shù)據(jù)長度提取出一個完整的數(shù)據(jù)幀,后臺代碼如下:private SerialPort sp;privat
33、e CRecvBuf recvBuf;private void btnStart_Click(object sender, EventArgs e) byte firstByte; byte tmp; sp.ReadTimeout = 10000; /10秒內(nèi)沒有收到回復(fù)數(shù)據(jù),將捕獲到異常 try firstByte = (byte)sp.ReadByte(); /讀取第1個回復(fù)字節(jié)(程序在此被阻塞)學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 tmp = new bytesp.BytesToRead + 1; tmp0 = firstByte; sp.Read(tmp, 1, tmp.Lengt
34、h - 1); /讀取剩余字節(jié)到tmp數(shù)組中 t1.Text = CCheck.BinaryToHexString(tmp); /接收數(shù)據(jù)顯示在文本框t1中 recvBuf.Add(tmp); /添加接收數(shù)據(jù)到隊列中 /顯示隊列中的全部數(shù)據(jù) t2.Text = CCheck.BinaryToHexString(recvBuf.getAllData(); /提取一個完整的數(shù)據(jù)幀 tmp = getBlock(recvBuf.li); if (tmp != null) t3.Text = CCheck.BinaryToHexString(tmp); /顯示在文本框t3中 else t3.Text = ; 學(xué)習(xí)情景2.2 串口設(shè)備數(shù)據(jù)的接收和處理 catch (TimeoutExc
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 浙江宇翔職業(yè)技術(shù)學(xué)院《公路工程定額原理與計價》2023-2024學(xué)年第一學(xué)期期末試卷
- 浙江工業(yè)職業(yè)技術(shù)學(xué)院《采購過程演練》2023-2024學(xué)年第一學(xué)期期末試卷
- 反諧振阻抗比較小的原因
- 中國傳媒大學(xué)《計算機(jī)電子電路基礎(chǔ)》2023-2024學(xué)年第一學(xué)期期末試卷
- 長治醫(yī)學(xué)院《劇場品牌管理》2023-2024學(xué)年第一學(xué)期期末試卷
- 云南司法警官職業(yè)學(xué)院《體育-臺球》2023-2024學(xué)年第一學(xué)期期末試卷
- 企業(yè)內(nèi)部知識分享平臺構(gòu)建方案
- 保險行業(yè)數(shù)字營銷模板
- 拿破侖歷史名人人物介紹
- 中考誓師大會學(xué)生發(fā)言稿
- 小學(xué)數(shù)學(xué)二年級100以內(nèi)連加連減口算題
- 建設(shè)單位如何做好項目管理
- 三年級上遞等式計算400題
- 一次性餐具配送投標(biāo)方案
- 2024年原發(fā)性肝癌中醫(yī)診療指南
- 2024醫(yī)療建筑韌性設(shè)計導(dǎo)則
- 軍隊文職半年述職報告
- 鑄牢中華民族共同體意識-考試復(fù)習(xí)題庫(含答案)
- 2024年浙江首考高考選考生物試卷試題真題(含答案詳解)
- 天津市紅橋區(qū)2023-2024學(xué)年七年級上學(xué)期期末地理試題
- 西門子數(shù)字化工廠-數(shù)字化車間-先進(jìn)制造技術(shù)
評論
0/150
提交評論