




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
對項目進(jìn)行代碼重構(gòu)臨近公司放假,也好在年前對這次項目的一項總結(jié)(包括代碼)。剛分配到這份項目時,我認(rèn)為自己可以完成這次的項目,但是在項目的開發(fā)過程中,還是遇到許多的問題,總的來說,分為以下幾點:前期對項目的背景不是很清楚(我一開始以為只要拿到項目就開始Coding,完成項目,其實不是這樣);文檔寫的不夠完善(只寫了需求分析、概要設(shè)計、沒有數(shù)據(jù)庫設(shè)計,因為文件都是存放在XML文檔里);對使用的技術(shù)不會(操作RS232串口,以前在學(xué)校從來沒學(xué)過這些,當(dāng)然,也不需要學(xué)習(xí)這些。本人認(rèn)為,自己主動去學(xué)和學(xué)校所教最大的區(qū)別在于主動是有意識的去學(xué),而學(xué)校所教是被動的);與老板(客戶)的溝通不夠,客戶那邊一有新的需求,就馬上換成新的需求,然后換來換去,弄的心情很不爽,特別是一個項目需要分成好幾種類型,比如,四川省的我要這種,福建省的我要那種,北京市的又是另外的,而且還是同時更新。所以改的比較痛苦,也很糾結(jié)。(現(xiàn)在已改用OO的方法);最重要的是我自己對技術(shù)看的太輕松了,我認(rèn)為技術(shù)會了就是會了,其實太天真了~~(其實是看個人的心態(tài)拉,我認(rèn)為自己還Ok)。所以,我一直在改變、進(jìn)步!好了,下面是項目中一個串口操作類重構(gòu)后的Code。這里我專門寫了一個類來處理對串口的操作,主要是write、read,其中有用到包括delegate、event、lock、多線程。首先,實例化串行端口,有端口名稱波特率奇偶校驗位數(shù)據(jù)位停止位這些。然后在Program實例化這個串口操作類。SettingClasssc=newSettingClass();publicclassSettingclass{///〈summary〉///實例化串行端口資源端口名稱波特率奇偶校驗位數(shù)據(jù)位停止位.///〈/summary〉
publicstaticSerialPortserPort=null;//聲明委托publicdelegatevoidInsertData(byte[]ByData);//聲明事件publicstaticeventInsertDataGetData;復(fù)制代碼寫個構(gòu)造函數(shù),來處理串口對象的初始化///<summary>///構(gòu)造函數(shù),處理串口對象的初始化.///</summary>publicSettingClass(){try{serPortnewSerialPort("COM1",9600,Parity.None,8,StopBits.One);serPort.DataReceivednewSerialDataReceivedEventHandler(serPort_DataReceived);serPort.Open();}catch(Exceptionex){System.Windows.Forms.MessageBox.Shdt未發(fā)現(xiàn)到串口COM1,請檢查.!\n"+ex.Message,"錯誤警告");}}復(fù)制代碼我們還可以寫個帶參的構(gòu)造函數(shù),用來后續(xù)選擇端口的初始化///<summary>///后續(xù)可以選擇COM端口初始化
///</summary〉///<paramname="portName"〉</param〉///<paramname="baudRate"〉</param〉///<paramname="parity"〉</param〉///<paramname="dataBits"〉</param〉///<paramname="stopBits"〉</param〉publicSettingClass(stringportName,intbaudRate,Parityparity,intdataBits,StopBitsstopBits){try{serPortnewSerialPort(portName,baudRate,parity,dataBits,stopBits);serPort.DataReceivednewSerialDataReceivedEventHandler(serPort_DataReceived);serPort.Open();}catch(Exceptionex){System.Windows.Forms.MessageBox.Shdt未發(fā)現(xiàn)到串口COM1,請檢查.!\n"+ex.Message,"錯誤警告");}}復(fù)制代碼在操作serialport的時候,如果需要實行實時的監(jiān)聽來自設(shè)備的數(shù)據(jù)包,那么,在SerialPort類中有DataReceived事件,當(dāng)串口的讀緩存有數(shù)據(jù)到達(dá)時則觸發(fā)DataReceived事件。(這個在上一篇文章中有,這里只是提一下)///^summary〉///處理來自設(shè)備的數(shù)據(jù).事件.///</summary〉///緩存數(shù)組privatevoidserPort_DataReceived(objectsender,SerialDataReceivedEventArgse){try{//獲取緩沖區(qū)的字節(jié)個數(shù).intintToRead=serPort.BytesToRead;//聲明臨時數(shù)組存儲串口數(shù)據(jù).byte[]byteData=newbyte[intToRead];//讀取來自緩沖區(qū)的數(shù)據(jù).serPort.Read(byteData”byteData.Length);byte[]bytedata=newbyte[byteData.Length];//把接收到的數(shù)據(jù)保存到緩存里for(inti=0;i<byteData.Length;i++){bytedata[i]+=byteData[i];buffer_list.Add(bytedata[i]);}lock(_syncLock){//開啟新線程ThreadtnewThread(newThreadStart(ReturnBytaData));th.Start();//if(th.IsAlive)//{//th.Abort();//}}catprivatestaticreadonlyobject_syncLock=newobject();復(fù)制代碼在上面這個事件里面,可以看到我聲明了一個緩存數(shù)組來接收數(shù)據(jù),作用是:如果設(shè)備發(fā)包只發(fā)了一個、或者多個、又或者1個半,因為包是由Code+Length+Data+CRC組成,接收的時候怕只接收到了Code+Length,后面的沒接收到,那么這個buffer的用處就來了,可以把前面的包和后面的包拼接成一個完整的包,然后傳輸?shù)絝orm的接收函數(shù)里。設(shè)備發(fā)的數(shù)據(jù)包不可能只發(fā)一個Code+Length,后面在發(fā)一個Code+Length,規(guī)則協(xié)議和TCP傳輸原理一樣。下面的函數(shù)是用來處理從設(shè)備接收到的數(shù)據(jù)包,最后只返回Code和Data,返回Code是因為我一個界面上有不同的命令,但是會有相同的參數(shù),視情況而定。在這個函數(shù)中,也處理了buffer緩存,對設(shè)備的數(shù)據(jù)包進(jìn)行校驗。note:下面代碼第19行,返回的是setok,返回的是成功的數(shù)據(jù)包格式,需要進(jìn)行處理。復(fù)制代碼1///<summary>2///校驗從設(shè)備得到的數(shù)據(jù)包3///</summary>4///<paramname="listbytedata"〉緩存數(shù)組</param〉5///<returns>去除length+crc的數(shù)據(jù)包</returns〉6publicvoidReturnBytaData()7{8try9{10//查詢緩存是否還存在完整數(shù)據(jù)包11while(bufferlist.Count>4)12{1314151617181920212223242526272829303132333435363738394041424344//緩存里第一個數(shù)據(jù)包//聲明需要返回的數(shù)據(jù)包byte[]returndata=newbyte[bytelength-1];if(bytelength!=101){//把緩存內(nèi)完整的數(shù)據(jù)包遍歷到字節(jié)數(shù)組byte[]returnbytedata=newbyte[bytelength+2];for(inti=0;i<buffer_list[1]+2;i++){returnbytedata[i]+=buffer_list[i];}//判斷數(shù)據(jù)包的數(shù)據(jù)是否真實if(bytelength==returnbytedata.Length一2){//得到高八位、低八位bytej1=returnbytedata[returnbytedata.Length-2];bytej2=returnbytedata[returnbytedata.Length-1];intsum=0;//校驗高八位、低八位.for(intj=0;j<returnbytedata.Length-2;j++){sum+=returnbytedata[j];}byteg=byte)(sum>>8);byted=byte)(sum);if(j1==g&&j2==d)4546474849ength)50515253545556575859606162636465h);666768697071727374//得至卩datadata=-crc,-code,-lengthintdatalength=returnbytedata.Length-4;byte[]byteData=newbyte[datalength];Array.Copy(returnbytedatayteData,0,datal//得到codebyte[]bytecode=newbyte[1];Array.Copy(returnbyte<dataytecode,0,1);//返回code+datafor(inti=0;i<bytecode.Length;i++){returndata[i]+=bytecode[i];}for(intn=0;n<datalength;n++){returndatH[r+斗byteData[n];}buffer_list.RemoveRa?ngH2(turnbytedata.Lengtif(GetData!=null){//綁定到事件GetData(returndata);}}else
2);76return;777879else8081return;828384else8586buffer_list.RemoveRangebuffer_list.Count);872);76return;777879else8081return;828384else8586buffer_list.RemoveRangebuffer_list.Count);87888990catch91復(fù)制代碼最后面的是接收來自form傳過來的data.///<summary>///處理各個窗體傳來的數(shù)據(jù).各窗體只需要傳送命令+數(shù)據(jù)即可.///</summary>///<paramname="by"〉接收到的數(shù)據(jù).</param〉publicstaticvoidInsertserPortData(byte[]Data){try{//因為各窗體發(fā)來的數(shù)據(jù)不包括CRC校驗,所以長度+2.byte[]byteText=newbyte[Data.Length+2];intsum=0;for(inti=0;i<Data.Length;i++){byteText[i]+=Convert.ToByte(Data[i]);}//遍歷sum的累加和,判斷高八位和低八位.for(intn=0;n<byteText.Length;n++){sum+=byteText[n];}//高八位.byteg=byte)(sum>>8);//低八位.byted=byte)(sum);//把檢驗加到字節(jié)數(shù)組中.byteText[byteText.Length2-+=g;byteText[byteText.Length1-+=d;//寫入串口.serPort.Write(byteText,byteText.Length);}catch{ }}復(fù)制代碼最后,在需要接收數(shù)據(jù)包的form里面注冊下這個事件。SettingClass.GetData+=newSettingClass.InsertData(SettingClass_GetData);下面的ByData是數(shù)據(jù)包(去除Length+CRC).voidSettingClass_GetData(byte[]ByData)
//處理接收到的數(shù)據(jù)包,顯示到界面里???}復(fù)制代碼這個項目對我的意義重大,我會一直對它進(jìn)行重構(gòu)下去。下次應(yīng)該就是用OO的方法來寫文章了。這個項目是我今年畢業(yè)以來獨立負(fù)責(zé)的第一個項目。所以,幫助真的很大,在這里我非常感謝我的公司,相信我,給了我鍛煉的機會,也很感謝我的同事FHW、LB、FBY、RJB等。操作串口通信類(IO.Ports)-SerialPort公司項目接近尾部,從剛開始接觸SeriaIPort到現(xiàn)在,用的最多算是它了。所以,現(xiàn)在做個總結(jié)。剛開始接到這個項目的時候,就從沒接觸過SeriaIPort,不知道如何下手,像最基本的PortName(通信端口)、BaudRate(波特率)、Parity(奇偶校驗)、DataBits(數(shù)據(jù)位長度)、StopBits(停止位數(shù))都不知道,后來網(wǎng)上google別人的經(jīng)驗,知道了最基本的用法,原來串口通信還需要下層的同事把協(xié)議寫好,燒到硬件上去。串口的使用:1串口控件位于工具箱一組件一SerialPort,拖動到窗體上,設(shè)置屬性(Name),命名。*-w乂打印GerisIPort:GerialPorE尿本心*-w乂打印GerisIPort:GerialPorE尿本心ODOr來自Micro-sQ-ftCorpor.NETComponentBaGkgroundWorkerDirertoryEntryDirectory£eartherErrorProuiderEuentLogFile-Sy5temWatcherHelpProviderMeEssgeQueuePerforinsnceCo□nter可在屬性處進(jìn)行設(shè)置,也可以在后臺代碼頁進(jìn)行手動寫:需導(dǎo)入命名空間:usingSystem.IO.Ports;///〈summary〉///串行端口資源端口名稱波特率奇偶校驗位數(shù)據(jù)位停止位///〈/summary〉publicSerialPortport=newSerialPort("COM1",115200,Parity.None,8,StopBits.0ne);復(fù)制代碼設(shè)置好串行端口等屬性之后,便可以操作串口進(jìn)行通信了,如要對設(shè)備進(jìn)行全部開啟操作。///<summary>/////設(shè)備全開、關(guān)///</summary>protectedvoidAllOpenOrClose()try//打開串口port.Open();//判斷是否選中開if(chb_CheckAll.Checked==true)
{//用字節(jié)的形式發(fā)送數(shù)據(jù)全開解釋:orderl是控制命令,后面是2個byte的校驗(高8位與低8位),0x00可以不寫,直接寫成(byte)((order1)〉〉8)byte[]b={orderl,byte)((order1+0x00)>>8),(byte)(order1+0x00) };//把b數(shù)組中的數(shù)據(jù)以字節(jié)的形式寫入串行端口port.Write(0:,,b.Length);//提示信息!lab_Message.Tex■"設(shè)備已經(jīng)全部打開!";}else{//用字節(jié)的形式發(fā)送數(shù)據(jù)全關(guān)byte[]b={order2,byte)((order2+0x00)>>8),(byte)(order2+0x00) };v.port.Write(0:},b.Length);lab_Message.Tex■"設(shè)備已經(jīng)全部關(guān)閉!";}//關(guān)閉串口記得開啟端口之后一定要關(guān)閉,和ADO.NET的Connection對象一樣,用過之后必須關(guān)閉。port.Close();}catch(Exceptionex){//捕獲的異常信息MessageBox.Show(ex.Messag"提示");}復(fù)制代碼
2,如果要對設(shè)備的狀態(tài)進(jìn)行實時監(jiān)聽,有一個很好的事件,在SerialPort類中有DataReceived事件,當(dāng)串口的讀緩存有數(shù)據(jù)到達(dá)時則觸發(fā)DataReceived事件,其中SerialPort.ReceivedBytesThreshold屬性決定了當(dāng)串口讀緩存中數(shù)據(jù)多少個時才觸發(fā)DataReceived事件,默認(rèn)為1。我們把串口的屬性定義在InitializeComponent()方法下面,(不會連這個方法都不知道把?!)。在頁面命名空間下的第一個方法,是VisualStudio設(shè)計器自動生成的方法。publicSettingsTimePlay(){InitializeComponent();//串行端口號seriaSettingPlay.PortName"COM1";//波特率seriaSettingPlay.BaudRate=L5200;//奇偶校驗位seriaSettingPlay.Parity=Parity.None;/
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 環(huán)保環(huán)評報告
- 中國家用通風(fēng)電器具制造行業(yè)分析報告
- 2024-2025學(xué)年高中生物第2章第5節(jié)細(xì)胞中的無機物課時精練含解析新人教版必修1
- 2024-2025學(xué)年高中歷史課時作業(yè)19羅馬人的法律人民版必修1
- 山東省某水產(chǎn)食品有限公司水產(chǎn)品精深加工項目可行性研究報告
- 太原硅酮密封膠項目可行性研究報告模板范本
- 2025年中國板材壓接機行業(yè)市場需求預(yù)測及投資戰(zhàn)略規(guī)劃報告
- 白銀項目可行性研究報告(立項申請報告)-圖文
- 三圈筆行業(yè)市場發(fā)展及發(fā)展趨勢與投資戰(zhàn)略研究報告
- 建筑類實習(xí)報告范文五
- 部編版三年級語文下冊第一單元《1.古詩三首-絕句》教案
- 小學(xué)三年級語文質(zhì)量分析課件
- 腹腔化療腫瘤課件
- 四川省成都市武侯區(qū)2022-2023學(xué)年七年級下學(xué)期期末英語試卷(含答案)
- 腦卒中患者護(hù)理查房
- 智能機器人與傳感器PPT完整全套教學(xué)課件
- 高效空調(diào)制冷機房智能控制系統(tǒng)技術(shù)規(guī)程
- 《動物王國開大會》說課PPT
- GB/T 42595-2023承壓設(shè)備修理基本要求
- 春玉米套種秋黃瓜技術(shù)
- 四年級下冊勞動技術(shù)教案
評論
0/150
提交評論