引言
自1952 年第一臺數控機床誕生以來,數控系統已經歷了兩個階段和六代的發展。進入90 年代后,基于個人計算機(PC)的數控系統(簡稱PCNC)成為第六代數控系統的代表。作為CNC 發展的主要方向,PCNC 有成本低、開放性強、軟件開發環境完備、軟件資源豐富和良好的通訊功能等特點。從組成類型來看,目前“軟件NC”和“NC 嵌入PC”是PCNC的主流形式。所謂“軟件NC”,就是“CNC 的功能處理全產由PC 進行,并通過裝在PC 擴展插槽中的接口卡對伺服驅動進行控制。其優點是編程處理相當靈活,數控軟件的通用性強。缺點是實時處理比較困難,可靠性待進一步研究。目前,實時處理能力是制約PCNC 展的重要因素。在PC 的操作系統中,MS - DOS 是一個非實時單任務內核,Windows95 并不實時能系統的數控實時性能只能依賴系統設計和程序設計來保證。
1 數控軟件的實時性
PCNC 軟件系統一般都包括:讀取處理后的NC文件→譯碼→軌跡插補計算→伺服控制這樣一個基本的加工循環,在未運行完最后一條NC 語句前,該循環將一直進行。顯然,丙次循環之間總存在一定的時間間隔,而時間間隔的長短需要根據實際加工對實時性的要求來確定。
對于控制精度要求不高的情況可以直接用Windows的計時器計時,在達到設定的時間后,計時器發出WM-TIMER 消息到應用程序的消息對列中,如果將上述循環程序放在WM-TIMER 消息的處理函數中,就可以方便地實現定時。但這種方法存在兩個問題:一是WM-TIMER 消息的優先級比較低,只有當系統處理完消息隊列中優先級較高的消息后,才會處理WM-TIMER 消息;二是計時器是以PC 硬件的時間中斷次數來確定計時的長短,而時間中斷的周期是以系統電子釧的時間為基準,固定54.95ms。由此可見,計時器的實際地精度大于55ms,只能用于實時性求不高的場合。
大多數情況下,計時器都不能滿足要求。為了增強控制程序的實時性,可以采用軟件延時的方法,即在上述循環中放一段延時語句。對于毫秒級的延時精度,可通過調用Windows 的API 函數timeGetTime來實現,該函數采用了基于BIOS 的時間基準。以下是VC + + 中實現毫秒級延時的例子。
void deIaytime(int timdeIay) {DWORD m-timerI; m-timerI = timeGetTime() whiIe((timeGetTime() - m-timerI) < timdeIay ?。?/span>
timeGetTime 函數能實現毫秒級的延時,與計時器相比,時間精度得到了一定的提高。但毫秒級的時間精度并不能完全滿足數控加工的要求。為了進一步提高時間精度,可以通過執行循環程序來實現(如用for 語句)。但這種情況下,循環次數不僅與延時的時間長短有關,還與計算機的硬件配置(如主頻等)有直接聯系。所以這種方法的最大弊端就是程序的移植性很差。
如前所述,從時間精度的角度來看,計時器只能用于控制精度不高的場合,多數情況下需要用timeGetTime 函數或執行循環程序的方法。從獲得精確時間的方式來看,計時器以硬件中斷為基礎,不“獨占CPU”,而timeGetTime 函數和執行循環程序采用了延時的方法,程序在執行的過程中將“獨占CPU”。如果應用程序僅有一個線程,即用戶界面線程,一旦CPU 被“獨占”,程序將無法接收、處理用戶輸入的消息和事件,這顯然不能滿足設計要求,所以必須考慮引入多線程。(注:由于Windows 是基于消息的多任務操作系統,這里的“獨占CPU”并不表示一直完全占有CPU,而是表示在執行該線程的時間片內獨占CPU,而其它時間片CPU 并非由該線程占有。)
2 多線程
VisuaiC + + 中的線程分為用戶界面線程(UserImterface Thread)和工作者線程Worker Thread)。用戶界面線程的特點是擁有單獨的消息隊列,具有自已的窗口界面,能夠對用戶輸入的事件和消息做出響應。工作者線程一般用于處理后臺任務,僅由一個函數體實現,不處理窗口。
在擁有多個線程的應用程序中,當兩個或更我的線程同時訪問同一數據時,就會導致不可預知的結果,因此必須保持線程間的同點。Visuaic + + 中有四種同步方法:臨界段、信號燈、互斥量和事件。事件同步是通過將事件本身設置為有信號或無信號來通知其他線程某一操作已完成或尚未完成。下面以實現M01功能為例,介紹在數控軟件中使用多線程和事件同步的方法。
3 實現M01功能
M01—計劃程序停止。該指令的作用是:在操作面板上預先按下“任選停止”按鈕,當執行完M01指令之后,程序停止,主軸停轉,進給停止,冷卻工作者線程流程圖液關閉,加工停止。
如果不按“任選停止“按鈕,則M01指令無效。在加工停止后,如果重新按下“循環啟動”按鈕,則繼續加工。如果僅用用戶界面線程,當控制精度很高,采用了延時程序時, 循環指令將會“獨占CPU”,從而導致用戶界面線程不能處理用戶輸入的事件和消息,無法實現人機交互。解決的方法是將含有軌跡插補的循環指令放入一個工作者線程中,將各種實現人機交互的按鈕(如“任選停止”按鈕)放在用戶界面線程中。這樣,盡管工作者線程一直“忙” 個不停,但用戶界面線程卻“閑”著,能夠及時響應用戶輸入的事件和消息。當用戶界面線程接收到用戶輸入的事件和消息后,通過線程同步,就能使工作者線程實現預定的操作實現M01功能的具體方法如下:
首先在“任選停止”按鈕和“循環啟動”按鈕的ciick(單擊)事件的響應函數中分別設置某一事件有信號,然后在工作者線程的扦環體內檢測相應事件是否有信號,并根據檢測的結果做出相應的處理。需要做的工作是:定義兩個事件,創建一個工作者線程,并建立工作者線程的控制函數體。程序流程如圖所示,主要代碼如下:
其中,AfxBeginThread 為啟動工作者線程的全局函數,該函數創建并初始化CwindThread 對象、啟動并返回線程的地址。
控制函數用于定義線程。進入控制函數時,線程啟動;退出時,線程終止。以上控制函數中Deaiedatathread為控制函數名,參數param 是一個32 位值。該參數在創建線程對象時傳遞過來。工作者線程的控制函數體如下:
最后在“任選停止”按鈕和“循環啟動”按鈕的click(單擊) 事件的響應函數中分別設置gpauseevent 和g starteevent 有信號即可,可通過以下兩條語句實現。
g pauseevent. SetEvent(); / / 設置停止事件為有信號 g pauseevent. SetEvent(); / / 設置啟動事件為有信號
4 結束語
多線程和事件同步能有效地解決數控軟件實時控制中存在的“獨占CPU”的問題,實現人機交互。本文介紹了一種易于實現的簡便方法。
(審核編輯: 智匯胡妮)
分享