版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
對(duì)項(xiàng)目進(jìn)行代碼重構(gòu)臨近公司放假,也好在年前對(duì)這次項(xiàng)目的一項(xiàng)總結(jié)(包括代碼)。剛分配到這份項(xiàng)目時(shí),我認(rèn)為自己可以完成這次的項(xiàng)目,但是在項(xiàng)目的開(kāi)發(fā)過(guò)程中,還是遇到許多的問(wèn)題,總的來(lái)說(shuō),分為以下幾點(diǎn):前期對(duì)項(xiàng)目的背景不是很清楚(我一開(kāi)始以為只要拿到項(xiàng)目就開(kāi)始Coding,完成項(xiàng)目,其實(shí)不是這樣);文檔寫(xiě)的不夠完善(只寫(xiě)了需求分析、概要設(shè)計(jì)、沒(méi)有數(shù)據(jù)庫(kù)設(shè)計(jì),因?yàn)槲募际谴娣旁赬ML文檔里);對(duì)使用的技術(shù)不會(huì)(操作RS232串口,以前在學(xué)校從來(lái)沒(méi)學(xué)過(guò)這些,當(dāng)然,也不需要學(xué)習(xí)這些。本人認(rèn)為,自己主動(dòng)去學(xué)和學(xué)校所教最大的區(qū)別在于主動(dòng)是有意識(shí)的去學(xué),而學(xué)校所教是被動(dòng)的);與老板(客戶)的溝通不夠,客戶那邊一有新的需求,就馬上換成新的需求,然后換來(lái)?yè)Q去,弄的心情很不爽,特別是一個(gè)項(xiàng)目需要分成好幾種類(lèi)型,比如,四川省的我要這種,福建省的我要那種,北京市的又是另外的,而且還是同時(shí)更新。所以改的比較痛苦,也很糾結(jié)。(現(xiàn)在已改用OO的方法);最重要的是我自己對(duì)技術(shù)看的太輕松了,我認(rèn)為技術(shù)會(huì)了就是會(huì)了,其實(shí)太天真了~~(其實(shí)是看個(gè)人的心態(tài)拉,我認(rèn)為自己還Ok)。所以,我一直在改變、進(jìn)步!好了,下面是項(xiàng)目中一個(gè)串口操作類(lèi)重構(gòu)后的Code。這里我專(zhuān)門(mén)寫(xiě)了一個(gè)類(lèi)來(lái)處理對(duì)串口的操作,主要是write、read,其中有用到包括delegate、event、lock、多線程。首先,實(shí)例化串行端口,有端口名稱(chēng)波特率奇偶校驗(yàn)位數(shù)據(jù)位停止位這些。然后在Program實(shí)例化這個(gè)串口操作類(lèi)。SettingClasssc=newSettingClass();publicclassSettingclass{///〈summary〉///實(shí)例化串行端口資源端口名稱(chēng)波特率奇偶校驗(yàn)位數(shù)據(jù)位停止位.///〈/summary〉
publicstaticSerialPortserPort=null;//聲明委托publicdelegatevoidInsertData(byte[]ByData);//聲明事件publicstaticeventInsertDataGetData;復(fù)制代碼寫(xiě)個(gè)構(gòu)造函數(shù),來(lái)處理串口對(duì)象的初始化///<summary>///構(gòu)造函數(shù),處理串口對(duì)象的初始化.///</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,請(qǐng)檢查.!\n"+ex.Message,"錯(cuò)誤警告");}}復(fù)制代碼我們還可以寫(xiě)個(gè)帶參的構(gòu)造函數(shù),用來(lái)后續(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,請(qǐng)檢查.!\n"+ex.Message,"錯(cuò)誤警告");}}復(fù)制代碼在操作serialport的時(shí)候,如果需要實(shí)行實(shí)時(shí)的監(jiān)聽(tīng)來(lái)自設(shè)備的數(shù)據(jù)包,那么,在SerialPort類(lèi)中有DataReceived事件,當(dāng)串口的讀緩存有數(shù)據(jù)到達(dá)時(shí)則觸發(fā)DataReceived事件。(這個(gè)在上一篇文章中有,這里只是提一下)///^summary〉///處理來(lái)自設(shè)備的數(shù)據(jù).事件.///</summary〉///緩存數(shù)組privatevoidserPort_DataReceived(objectsender,SerialDataReceivedEventArgse){try{//獲取緩沖區(qū)的字節(jié)個(gè)數(shù).intintToRead=serPort.BytesToRead;//聲明臨時(shí)數(shù)組存儲(chǔ)串口數(shù)據(jù).byte[]byteData=newbyte[intToRead];//讀取來(lái)自緩沖區(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){//開(kāi)啟新線程ThreadtnewThread(newThreadStart(ReturnBytaData));th.Start();//if(th.IsAlive)//{//th.Abort();//}}catprivatestaticreadonlyobject_syncLock=newobject();復(fù)制代碼在上面這個(gè)事件里面,可以看到我聲明了一個(gè)緩存數(shù)組來(lái)接收數(shù)據(jù),作用是:如果設(shè)備發(fā)包只發(fā)了一個(gè)、或者多個(gè)、又或者1個(gè)半,因?yàn)榘怯蒀ode+Length+Data+CRC組成,接收的時(shí)候怕只接收到了Code+Length,后面的沒(méi)接收到,那么這個(gè)buffer的用處就來(lái)了,可以把前面的包和后面的包拼接成一個(gè)完整的包,然后傳輸?shù)絝orm的接收函數(shù)里。設(shè)備發(fā)的數(shù)據(jù)包不可能只發(fā)一個(gè)Code+Length,后面在發(fā)一個(gè)Code+Length,規(guī)則協(xié)議和TCP傳輸原理一樣。下面的函數(shù)是用來(lái)處理從設(shè)備接收到的數(shù)據(jù)包,最后只返回Code和Data,返回Code是因?yàn)槲乙粋€(gè)界面上有不同的命令,但是會(huì)有相同的參數(shù),視情況而定。在這個(gè)函數(shù)中,也處理了buffer緩存,對(duì)設(shè)備的數(shù)據(jù)包進(jìn)行校驗(yàn)。note:下面代碼第19行,返回的是setok,返回的是成功的數(shù)據(jù)包格式,需要進(jìn)行處理。復(fù)制代碼1///<summary>2///校驗(yàn)從設(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//緩存里第一個(gè)數(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ù)是否真實(shí)if(bytelength==returnbytedata.Length一2){//得到高八位、低八位bytej1=returnbytedata[returnbytedata.Length-2];bytej2=returnbytedata[returnbytedata.Length-1];intsum=0;//校驗(yàn)高八位、低八位.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ù)制代碼最后面的是接收來(lái)自form傳過(guò)來(lái)的data.///<summary>///處理各個(gè)窗體傳來(lái)的數(shù)據(jù).各窗體只需要傳送命令+數(shù)據(jù)即可.///</summary>///<paramname="by"〉接收到的數(shù)據(jù).</param〉publicstaticvoidInsertserPortData(byte[]Data){try{//因?yàn)楦鞔绑w發(fā)來(lái)的數(shù)據(jù)不包括CRC校驗(yàn),所以長(zhǎng)度+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);//把檢驗(yàn)加到字節(jié)數(shù)組中.byteText[byteText.Length2-+=g;byteText[byteText.Length1-+=d;//寫(xiě)入串口.serPort.Write(byteText,byteText.Length);}catch{ }}復(fù)制代碼最后,在需要接收數(shù)據(jù)包的form里面注冊(cè)下這個(gè)事件。SettingClass.GetData+=newSettingClass.InsertData(SettingClass_GetData);下面的ByData是數(shù)據(jù)包(去除Length+CRC).voidSettingClass_GetData(byte[]ByData)
//處理接收到的數(shù)據(jù)包,顯示到界面里???}復(fù)制代碼這個(gè)項(xiàng)目對(duì)我的意義重大,我會(huì)一直對(duì)它進(jìn)行重構(gòu)下去。下次應(yīng)該就是用OO的方法來(lái)寫(xiě)文章了。這個(gè)項(xiàng)目是我今年畢業(yè)以來(lái)獨(dú)立負(fù)責(zé)的第一個(gè)項(xiàng)目。所以,幫助真的很大,在這里我非常感謝我的公司,相信我,給了我鍛煉的機(jī)會(huì),也很感謝我的同事FHW、LB、FBY、RJB等。操作串口通信類(lèi)(IO.Ports)-SerialPort公司項(xiàng)目接近尾部,從剛開(kāi)始接觸SeriaIPort到現(xiàn)在,用的最多算是它了。所以,現(xiàn)在做個(gè)總結(jié)。剛開(kāi)始接到這個(gè)項(xiàng)目的時(shí)候,就從沒(méi)接觸過(guò)SeriaIPort,不知道如何下手,像最基本的PortName(通信端口)、BaudRate(波特率)、Parity(奇偶校驗(yàn))、DataBits(數(shù)據(jù)位長(zhǎng)度)、StopBits(停止位數(shù))都不知道,后來(lái)網(wǎng)上google別人的經(jīng)驗(yàn),知道了最基本的用法,原來(lái)串口通信還需要下層的同事把協(xié)議寫(xiě)好,燒到硬件上去。串口的使用:1串口控件位于工具箱一組件一SerialPort,拖動(dòng)到窗體上,設(shè)置屬性(Name),命名。*-w乂打印GerisIPort:GerialPorE尿本心*-w乂打印GerisIPort:GerialPorE尿本心ODOr來(lái)自Micro-sQ-ftCorpor.NETComponentBaGkgroundWorkerDirertoryEntryDirectory£eartherErrorProuiderEuentLogFile-Sy5temWatcherHelpProviderMeEssgeQueuePerforinsnceCo□nter可在屬性處進(jìn)行設(shè)置,也可以在后臺(tái)代碼頁(yè)進(jìn)行手動(dòng)寫(xiě):需導(dǎo)入命名空間:usingSystem.IO.Ports;///〈summary〉///串行端口資源端口名稱(chēng)波特率奇偶校驗(yàn)位數(shù)據(jù)位停止位///〈/summary〉publicSerialPortport=newSerialPort("COM1",115200,Parity.None,8,StopBits.0ne);復(fù)制代碼設(shè)置好串行端口等屬性之后,便可以操作串口進(jìn)行通信了,如要對(duì)設(shè)備進(jìn)行全部開(kāi)啟操作。///<summary>/////設(shè)備全開(kāi)、關(guān)///</summary>protectedvoidAllOpenOrClose()try//打開(kāi)串口port.Open();//判斷是否選中開(kāi)if(chb_CheckAll.Checked==true)
{//用字節(jié)的形式發(fā)送數(shù)據(jù)全開(kāi)解釋?zhuān)簅rderl是控制命令,后面是2個(gè)byte的校驗(yàn)(高8位與低8位),0x00可以不寫(xiě),直接寫(xiě)成(byte)((order1)〉〉8)byte[]b={orderl,byte)((order1+0x00)>>8),(byte)(order1+0x00) };//把b數(shù)組中的數(shù)據(jù)以字節(jié)的形式寫(xiě)入串行端口port.Write(0:,,b.Length);//提示信息!lab_Message.Tex■"設(shè)備已經(jīng)全部打開(kāi)!";}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)閉串口記得開(kāi)啟端口之后一定要關(guān)閉,和ADO.NET的Connection對(duì)象一樣,用過(guò)之后必須關(guān)閉。port.Close();}catch(Exceptionex){//捕獲的異常信息MessageBox.Show(ex.Messag"提示");}復(fù)制代碼
2,如果要對(duì)設(shè)備的狀態(tài)進(jìn)行實(shí)時(shí)監(jiān)聽(tīng),有一個(gè)很好的事件,在SerialPort類(lèi)中有DataReceived事件,當(dāng)串口的讀緩存有數(shù)據(jù)到達(dá)時(shí)則觸發(fā)DataReceived事件,其中SerialPort.ReceivedBytesThreshold屬性決定了當(dāng)串口讀緩存中數(shù)據(jù)多少個(gè)時(shí)才觸發(fā)DataReceived事件,默認(rèn)為1。我們把串口的屬性定義在InitializeComponent()方法下面,(不會(huì)連這個(gè)方法都不知道把?!)。在頁(yè)面命名空間下的第一個(gè)方法,是VisualStudio設(shè)計(jì)器自動(dòng)生成的方法。publicSettingsTimePlay(){InitializeComponent();//串行端口號(hào)seriaSettingPlay.PortName"COM1";//波特率seriaSettingPlay.BaudRate=L5200;//奇偶校驗(yàn)位seriaSettingPlay.Parity=Parity.None;/
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 銀行內(nèi)部培訓(xùn)制度
- 酒店員工獎(jiǎng)懲激勵(lì)與反饋制度
- 超市員工績(jī)效考核及評(píng)價(jià)制度
- 2026年怎么開(kāi)藥店
- 2024-2025學(xué)年山西省晉城市部分學(xué)校高二下學(xué)期5月月考?xì)v史試題(解析版)
- 2026年網(wǎng)絡(luò)安全技術(shù)網(wǎng)絡(luò)攻擊與防御練習(xí)題集及答案
- 2026年會(huì)計(jì)職稱(chēng)考試寶典會(huì)計(jì)實(shí)務(wù)題庫(kù)及答案解析
- 2026年通信工程高級(jí)職稱(chēng)評(píng)審模擬題及答案解析
- 2026年舞臺(tái)藝術(shù)表演專(zhuān)業(yè)資質(zhì)考試題庫(kù)
- 2026年騰訊程序員招聘筆試題集
- 【必會(huì)】自考《管理學(xué)原理》13683備考題庫(kù)寶典-2025核心題版
- 建筑公司發(fā)票培訓(xùn)
- (2025年)qc培訓(xùn)考試試題(含答案)
- DBJ50-T-271-2017 城市軌道交通結(jié)構(gòu)檢測(cè)監(jiān)測(cè)技術(shù)標(biāo)準(zhǔn)
- 中醫(yī)醫(yī)院等級(jí)評(píng)審材料準(zhǔn)備全攻略
- 腫瘤科普宣傳課件
- T∕ZZB 0623-2018 有機(jī)溶劑型指甲油
- 70歲老年人三力測(cè)試能力考試題庫(kù)及答案
- CATL設(shè)備布線標(biāo)準(zhǔn)規(guī)范V6.01
- 110kV輸電線路防雷接地施工詳細(xì)方案
- 村醫(yī)積分制管理實(shí)施方案細(xì)則
評(píng)論
0/150
提交評(píng)論