資源描述:
《用vc實現(xiàn)多串口多線程工業(yè)控制》由會員上傳分享,免費在線閱讀,更多相關內容在行業(yè)資料-天天文庫。
1、用VC實現(xiàn)多串口多線程工業(yè)控制[串口通信??2009-05-0922:50??閱讀22???評論0?字號:大大?中中?小小?在中小型電站系統(tǒng)就地控制中,比如水電站中如果我們要進行各種設備控制的話,串口數(shù)量就可能比較多了,有的地方加上載波甚至可以達到10個以上,很多的解決方法是將某些功能設備并行接到一個串口上面盡量減少串口的數(shù)量,然后進行數(shù)據(jù)采集的時候采取環(huán)的方法進行。但是工業(yè)控制要求實時性比較高,比如報警和各種控制,如果不能在盡可能短的時間里面進行處理可能引發(fā)大的后果,我們覺得還是應該將各種不同設
2、備接入不同的串口,比如水電站中間各個機組的PLC和機組的調速器通訊等就接入不同串口。如果某個相同設備數(shù)量很多,如溫度裝置,有的1個發(fā)電機組可能超過20個溫度點,我們可以采用接入2個或者多個串口的方法處理?! 榱耸钩鯇W者能夠更容易看懂串口通訊的處理過程,我采用援助非洲剛果(布)姆古古魯水電站的溫度表為實例進行程序的分析。在我們這個項目中有4臺發(fā)電機組,每個機組溫度表有20個點。由于這個與上位機通訊串口安排極多,我們只能將20個溫度表并行接入串口進行通訊。在進行硬件通訊之前我們首先要看懂改硬件的通訊
3、協(xié)議?! ⊥ㄓ崊f(xié)議就是上位機向改外圍設備進行讀取數(shù)據(jù)和進行某種功能控制時候的一系列指令和外圍設備返回上位機的各數(shù)據(jù)位代表的意思。比如那個位是控制碼,哪個位是數(shù)據(jù),是什么數(shù)據(jù)等。 首先啟動VC新建一個給予SDI的工程,然后加入SerialPort類。由于要進行多串口通訊,我們需要對SerialPort進行一些簡單的修改,由于在與硬件通訊過程中一般通訊協(xié)議都采用BYTE類型數(shù)據(jù)傳送,我們可以將該類中間的發(fā)送和接收數(shù)據(jù)類型修改成為BYTE類型。我修改了下面部分內容,詳細改動請見附錄提供的SERIALP
4、ORT類。////Writeastringtotheport//voidCSerialPort::WriteToPort(BYTEbWriteBuffer[],intnWriteBufferSize){ assert(m_hComm!=0); intnSize=sizeof(bWriteBuffer)/sizeof(BYTE); m_nWriteBufferSize=nWriteBufferSize; for(inti=0;i5、er[i]=bWriteBuffer[i]; //seteventforwrite SetEvent(m_hWriteEvent);}...... 由于我們改串口接入了20臺溫度設備,在進行通訊的時候是通過發(fā)送某個地址的設備命令進行讀取數(shù)據(jù)。我們首先對硬件設置相應的地址,這里我們設置0到19號地址。采集的時候采用循環(huán)的方式從0號地址向19號地址進行讀取數(shù)據(jù)。當收到相應的數(shù)據(jù)包的時候我們進行相應的地址的數(shù)據(jù)解包處理。然后發(fā)送下一個地址的要數(shù)據(jù)命令。當?shù)刂窞樽詈笠慌_設備的時候我們將地址清0處理就
6、可以了。但是如果我們這個20臺設備中間某一個或者多個設備由于故障或者電源沒開的話,上述通訊就會出現(xiàn)問題,我們發(fā)送沒有運行的地址設備就會收不到相應的報文,我們就不會發(fā)送下一個地址的要數(shù)據(jù)命令,這是程序就會不走下去了。解決方法可以是我們從外部去判斷是否對當前地址的發(fā)送要數(shù)據(jù)命令和收到數(shù)據(jù)命令是否超時。如果超時就進行跳過然后發(fā)送下一個地址要數(shù)據(jù)命令。當出現(xiàn)規(guī)定幾個循環(huán)的時候進行該設備的采集參數(shù)清0等工作這個就可以隨自己定義考慮了。具體實現(xiàn)如下: 定義SERIALPORT類對象,創(chuàng)建線程進行通訊?!
7、SerialPortm_Ports;intnColtAddr,//這個用來存放當前采集設備地址。nColts;//這個用來存放當前緩沖區(qū)收到的字節(jié)數(shù)目HANDLEm_pThread;//外部控制線程BYTEm_RecBuff[1000];//接收緩沖區(qū)floatfVal[20];//處理解包內容,這里可以根據(jù)實際情況進行定義?! 哟诒O(jiān)視線程和外部控制線程nColtAddr=0;nColts=0;if(m_Ports.InitPort(this,1,4800,'N',8,1,EV_RXCHAR
8、
9、EV_RXFLAG,1024)){ this->m_Ports.StartMonitoring();啟動監(jiān)視線程 SetCommVal();發(fā)送第一臺設備數(shù)據(jù)命令} 下面是啟動外部控制線程unsignedintnDummy;m_pThread=(HANDLE)_beginthreadex(NULL,0,CommThread,this,CREATE_SUSPENDED,&nDummy);//開辟外部控制線程ResumeThread(m_pThread);運行線程 外部控制線程控