




已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
控制卡應(yīng)用編程技巧幾招(1)發(fā)布日期:2009-7-13 10:45:23 瀏覽次數(shù):4764 聲明一下,寫下這些編程技巧,即不是什么祖?zhèn)髅丶膊皇鞘裁幢貧⒄谢蚪^招,在此只為方便同仁們在編程控制軟件時,對此可以進(jìn)行適當(dāng)?shù)恼遄谩R韵抡宫F(xiàn)的編程思想及奉上的源代碼都非常簡易,但并不是隨手寫寫,可都是經(jīng)過實踐的。若沒有成功經(jīng)驗作后盾,我也就沒有必要在此打字練五筆了。 事實上,正如一個編程大師所言(Michael Abrash),當(dāng)你的軟件正常而且有效率的運行起來時,好像一切都是那么顯而易見。故,在此,我仍堅持那句編程口號,將事情變得越簡單越好,越簡單就越有效率,越穩(wěn)定。 在以下的介紹中,我將盡可能的展示本人的編程思想,最大可能的給出知其然也知其所然的解釋。若你有更好的見解,希望能得到你的指正。人長大了明顯標(biāo)志就是變得不太負(fù)責(zé),而且不敢承認(rèn)自己還需要努力,害怕面對自己的錯誤。若是這樣,放心,我還沒長大。因為我無法保證我能面面俱到。 關(guān)于源代碼的閱讀,需要讀者有一定的C+編程基礎(chǔ),至少對以下表示形式不會產(chǎn)生誤解: const char *pString; /指定pString邦定的數(shù)據(jù)不能被修改 char * const pString; /指定pString的地址不能被修改 const char * const pString; /含上面兩種指定功能 當(dāng)然,隨便提醒一下,這些源代碼若需要加入你的軟件工程當(dāng)中,還需要作一些調(diào)整和修改,因此,這些源代碼實質(zhì)上稱為偽代碼也可以,之所以展現(xiàn)它們,是讓程序員們有個可視化的快感,特別是那些認(rèn)為源代碼就是一切的程序員。 同時,為了提高針對性,大部分控制卡調(diào)用的函數(shù)會明確指出是邦定哪些卡的,實際應(yīng)用時,程序員可自行選擇,以體現(xiàn)一下自己的智商是可以寫寫軟件的。 一、 控制卡類的單一實例實現(xiàn) 把控制卡類作一個類來處理,幾乎所有C+程序員都為舉雙手表示贊同,故第一個什么都沒有的偽代碼就此產(chǎn)生,如下表現(xiàn): class CCtrlCard public: Function public: attrib 于是,用這個CctrlCard可以產(chǎn)生n多個控制卡實例,只要內(nèi)存足夠。然而,針對現(xiàn)實世界,情況并不那么美好。通常情況下,PC機(jī)內(nèi)只插同種類型的控制卡1到2張,在通過調(diào)用d1000_board_init或d3000_board_init函數(shù)時,它們會負(fù)責(zé)返回有效卡數(shù)nCards,然后從0-nCards*4 - 1自行按排好軸數(shù)。初始化函數(shù)就是C+的new或malloc的操作,取得系統(tǒng)的資源,但是控制卡的資源與內(nèi)存不一樣,取得資源后必需要釋放才可以再次獲取,即控制卡資源是唯一的。 既然控制卡資源是唯一的,那么最好Cctrlcard產(chǎn)生的實例也是唯一的,這樣,我們可以方便的需要定義一個全局變量即可: CctrlCard g_Dmcard; 在其它需要調(diào)用的地方,進(jìn)行外部呼叫: extern CctrlCard g_DmcCard; 以上方法實在太簡單了,很多人都會開心起來。實質(zhì)上,方法還有很多,即然可以產(chǎn)生n多對實例,我們的核心是只要保證調(diào)用board_init函數(shù)一次即可,故也可以單獨定義一個InitBoard函數(shù): class CctrlCard public: static int InitBoard(); /定義一個靜態(tài)函數(shù),以表警示 int CctrlCard:InitBoard() return d1000_board_init(); 還有一種方法,情況稍加復(fù)雜,但表達(dá)的功能也要強(qiáng)一些,以下展現(xiàn)可以稍微安慰一下代碼狂。 Class CctrlCard public: CctrlCard(); /請注意這個構(gòu)造函數(shù)的定義 CctrlCard:CctrlCard() /呵呵,也很明了 static int n(0); /注意,是個靜態(tài)變量 n+; /每次調(diào)用CctrlCard生成實例時,都會計數(shù)一次 assert( n = 1 ); /在DEBUG版本下,只有n=1的情況下可以通過 /否則,會出現(xiàn)致命錯誤,還好,它會告訴你錯在哪個文件, /哪一行,呵呵,是個好東東啊。 通過強(qiáng)行報警處理,當(dāng)你有g(shù)_DmcCard這個實例時,其它的所有控制卡的定義都只能是以引用或指針的方式進(jìn)行了,不會再產(chǎn)生新有效的實例了,對于由小組編程的項目軟件,而你又恰好負(fù)責(zé)編程控制卡這一塊的話,以上的顯性報警,會讓其它人心領(lǐng)神會。當(dāng)然,你也可以將上面的方法加入到InitBoard當(dāng)中去,可以避你的無意識的多次調(diào)用了。 附:無意識的多次調(diào)用經(jīng)常發(fā)生,特別是那些對MFC機(jī)制不明確的程序員,在多文檔框架下,不知道這個CctrlCard:InitBoard函數(shù)到底是應(yīng)該放在CmainFrame的OnCreate里面,還是應(yīng)該放在CchildFrame的OnCreate,或者是Cview的OnInitUpdate里面進(jìn)行調(diào)用。 在一言難盡MFC的情況下,我建議兩個小方法: No.1 將CctrlCard的函數(shù)置于Cmainframe的OnCreate或者Capp:Initstance內(nèi)調(diào)用 No.2 將InitBoard函數(shù)稍加改造成這樣: Int CctrlCard:InitBoard() static int n(-1000);/注意,-1000是控制卡函數(shù)不可能返回的值 if( n = -1000 ) n = d1000_board_init(); return n;/這樣,即使多次調(diào)用也不樣怕了,呵呵,雕蟲小技也可以除蟲啊 必須額外聲明一下,我們不是不重視資源的釋放,而是作為一個C+程序員寫下這些代碼是基本的義務(wù)(這也是我為什么要交待讀者必須要有一定的C+基礎(chǔ)): class CctrlCard public: CctrlCard() /定義析構(gòu)函數(shù),在此釋放資源,對此,我不想再轉(zhuǎn)到讀者的眼球了 d1000_board_close(); 二、 數(shù)據(jù)結(jié)構(gòu)及數(shù)據(jù)類型的定義,部分相關(guān)聲明 調(diào)用控制卡驅(qū)動函數(shù)時,經(jīng)常會有如下形式: 單軸相對運動 d1000_start_t_move( axis, pulse, start, speed, accel ); 單軸絕對運動 d1000_start_ta_move( axis, pulse, start, speed, accel ); 兩軸相對插補(bǔ) d1000_start_t_line( axisArray, distArray, start, speed, accel ); 兩軸絕對插補(bǔ) d1000_start_ta_line( axisArray, distArray, start, speed, accel ); 圓弧相對插補(bǔ) d3000_start_t_arc( axisArray, C1, C2, E1,E2, dir, start, speed, accel ); 圓弧絕對插補(bǔ) d3000_start_ta_arc( axisArray, C1, C2, E1,E2, dir, start, speed, accel ); 以上的調(diào)用,很多重復(fù)枯燥,又不直觀,難于理解,并且在面向客戶時,常常是指每分多少米,或者每秒多少毫米,很少有人問每秒多少脈沖,移動多少脈沖作距離,故需要單位之間的換算。顯然,對于這些問題,我想,程序員應(yīng)該找到用武之地了,所以我們一步一步來,慢慢統(tǒng)一各個問題。實質(zhì)上,在以下的幾個技巧,也需要在此澄清一些概念。 我們先來幾個宏定義提高一下情緒: # define MAX_AXIS 4 /最多軸數(shù) # define XCH 0 /定義軸的值 # define YCH 1 # define ZCH 2 # define UCH 3 .(其它以次類推) # define M_ABS 0x01 /定義一個絕對標(biāo)志位 # define M_INP 0x02 /定義一個插補(bǔ)位 接下來深入一點點,再來幾個結(jié)構(gòu)定義: typedef struct tag_ARC tag_ARC( double ox=0.0, double oy=0.0, double ex=0.0, double ey=0.0, int dir=0 ): ox(ox), oy(oy), ex(ex), ey(ey), dir(dir)/定義這樣一個構(gòu)造函數(shù)需要勇氣,看似不合理,但是好用麻 double ox,oy; double ex,ey; int dir; ARC; typedef struct tag_SPEED tag_SPEED( double start=0.0, double speed=0.0, double accel=0.0, double decel=0.0, double scc=0.0 ) : start(start), speed(speed), accel(accel), decel(decel), scc(scc) double start; double speed; double accel; double decel; double scc; SPEED; 以上兩個ARC和SPEED的結(jié)構(gòu)定義,把幾個參數(shù)變成一個參數(shù)。比如要實現(xiàn)的單軸驅(qū)動函數(shù),就變得非常明了: void Move( int nAxis, double fMM, const SPEED &speed, int nFlag = M_ABS );/往后我們再具體完善其實現(xiàn)。 以上的結(jié)構(gòu)具有類的特性,但是由于其每個成員都可以給外部直接使用,故就不需要什么類的public及其析構(gòu)函數(shù)的定義了。之所以全都采用double的數(shù)據(jù)類型,是面向客戶習(xí)慣及單位計算方便的。 接下來是對控制卡常用的單位計算及部分常用變量的聲明: class Cctrlcard public: (其它略去) public: /屬性 mutable int ORGIN; /指定原點狀態(tài)位 mutable int LIMIT_A, LIMIT_B; /指定左右限位狀態(tài)位 private: /以下的屬性不給外部訪問的 struct tag_AXIS/單軸屬性 double fUnitPM; /脈沖當(dāng)量 long nRP; /每轉(zhuǎn)脈沖數(shù) double fJourey; /行程 ; tag_AXIS m_axisMAX_AXIS; ; 定義ORGIN,LIMIT_A, LIMIT_B為變量,是有兩個意義: No.1 當(dāng)你訪問它們的狀態(tài)時,不需要每次調(diào)用d1000_get_axis_status函數(shù),你可以這樣: Int nStatus = d1000_get_axis( XCH ); If( nStatus & g_DmcCard.ORGIN = g_dmcCard.ORGIN ) If( nStatus & g_DmcCard.LIMIT_A = g_DmcCard.LIMIT_A ) If( nStatus & g_DmcCard.LIMIT_B = g_DmcCard.LIMIT_B ); No.2 你可以擴(kuò)展不同的卡,當(dāng)外部調(diào)用的程序邏輯已被確定時,當(dāng)你需要從DMC1000控制卡升級到DMC3000控制卡時,只需要給ORGIN等狀態(tài)位指定不同的值即可。指定狀態(tài)位的值也有一個小小的技巧,以O(shè)RGIN為例,在DMC1000控制卡,其位值在2位,則可以這樣: ORGIN = 12; 在DMC3000控制卡,其值在第9位,則這樣: ORGIN = 19; 方法都很簡單,關(guān)鍵是要想得到。 對于tag_AXIS定義,引出幾個函數(shù)的聲明,專門為其服務(wù): void SetUP( nit nAxis, double fMM, double nPulse, double fMax );/設(shè)定當(dāng)量 double P2M ( int nAxis, long nPulse ); /脈沖轉(zhuǎn)成毫米 pulse to metric long M2P( int nAxis, double fMM ); /毫米轉(zhuǎn)成脈沖 mitric to pulse 現(xiàn)在,我們再回過頭來完成Move函數(shù)的實現(xiàn),以便獲得一點點成就感,同時也展示一下以上的大堆表述是有其意義的。 void Move( int nAxis, double fMM, const SPEED &speed, int nFlag = M_ABS ) ( nFlag & M_ABS = M_ABS ) ? d1000_start_ta_move( nAxis, /絕對 M2P( nAxis, fMM), M2P( nAxis, speed.start ), M2P( nAxis, speed.speed), Speed.accel ): /注意是冒號,?:是一個表達(dá)式 d1000_start_t_move( nAxis, /相對 M2P( nAxis, fMM), M2P( nAxis, speed.start ), M2P( nAxis, speed.speed), Speed.accel ); 是不是很簡單呢,當(dāng)外部調(diào)用時,客戶的觀念就直接面對Metric即可,如: Move( XCH, 10.0, SPEED(5,10,0.1), M_ABS );/達(dá)到絕對位置10.0毫米處。 以上羅嗦了一大堆,對于剛開始C+編程的程序員來說應(yīng)該是收益不小,對于高手,則希望能夠體會一下我的良苦用心。在以下的技巧介紹當(dāng)中,我將變得很簡易。一般來講,程序員的基礎(chǔ)不是太差的話,至少能夠在1分鐘內(nèi)明白是什么道理??刂瓶☉?yīng)用編程技巧幾招(2)發(fā)布日期:2009-3-9 0:42:58 瀏覽次數(shù):2416 三、 插補(bǔ)和聯(lián)動函數(shù) 當(dāng)程序員決定需要幾軸進(jìn)行插補(bǔ)時,盡量選擇最大插補(bǔ)軸數(shù),如在雕銑系統(tǒng)時,有時會用到兩軸插補(bǔ),有時會進(jìn)行三軸插補(bǔ),在這個基礎(chǔ)上,為簡化編程,我的理論只使用三軸插補(bǔ),當(dāng)需要進(jìn)行兩軸插補(bǔ)或聯(lián)動時,根據(jù)相對或絕對的坐標(biāo)關(guān)系,將不運動軸填入0偏移或絕對位置即可。 以下為XYZ三軸聯(lián)動和插補(bǔ)的函數(shù),由nFlag的M_INP位決定是否進(jìn)行插補(bǔ): void MoveXYZ( double fX, double fY, double fZ, const tag_SPEED &speed, int nFlag = M_ABS ) short axisArray= XCH, YCH, ZCH ; if( nFlag & M_INP = M_INP ) /插補(bǔ) long distArray= M2P(XCH, fX), M2P(YCH,fY), M2P(ZCH,fZ) ; long nStart, nSpeed;/計算新的矢量速度,參見DMC1000矢量速度的計算 (矢量速度計算在此略去) ( nFlag & M_ABS = M_ABS ) ? d1000_start_ta_line( 3, axisArray, nStart, nSpeed, speed,accel ):/絕對 d1000_start_t_line(3, axisArray, nStart, nSpeed, accel );/相對 else /聯(lián)動 double fpos= fX, fY, fZ; for( int I(0); ISelectObject( &newPen );時,或者除了復(fù)位之外,你真正需要調(diào)用這個SetPosition函數(shù)時,你會發(fā)現(xiàn)這個設(shè)計,真是人情味實足。 五、 復(fù)位,相對與絕對, 在如今PC機(jī)開發(fā)控制卡軟件時代,設(shè)備上電不復(fù)位的幾乎沒有,在此談到復(fù)位這個問題確實有必要,實現(xiàn)上,復(fù)位動作因不同設(shè)備的工藝要求而定,故一般而言,控制卡提供的那個復(fù)位函數(shù)太過簡單,有點力不從心,所以,本人自己寫了個復(fù)位函數(shù),但是代碼寫起來將會占用很大的面版,故有此需要者,可以來電或E_mail索取。 其基本思路是采用兩次找原點,第一次高速找,停止后退出,再次以較低的速度找原點。并且在執(zhí)行第二次復(fù)位時,會在離原點5毫米處減速(第一次執(zhí)行做不到)。 提供相對和絕對位置的概念是很有必要的,眾所周知,現(xiàn)在控制卡能作到最小單位為1個脈沖,當(dāng)然,作為數(shù)字脈沖,到此已不能再小了,故為了提高精度,通常情況下要提高計算當(dāng)量,即增加每轉(zhuǎn)脈沖數(shù),或減少每轉(zhuǎn)毫米數(shù)。 不論怎么,我們將問題放大并明朗化,可以看看以下片段: for( int I(0); I10000; I+)/ 走10000次 move( 0.5 );/走相對0.5個脈沖的距離 結(jié)果是:1個脈沖也發(fā)不出,造成很大的累積誤差。 若換成絕對方式: for( int I(0); I10000; I+) goto( I*0.5 ); 最后的誤差,最大也就是1個脈沖以內(nèi)。雖然還是有誤差,但總算達(dá)到可容忍的程序,再加上適當(dāng)?shù)膹?fù)位操作,讓客戶至少不必再擔(dān)心這個巨大的累積誤差了。 實質(zhì)上,在整個軟件設(shè)計時最好采用絕對坐標(biāo)系,即使要處理加工原點或工面起點等這些參數(shù),也要把它換算成絕對位置,唯手動移動設(shè)備可以例外。另外,在CNC系統(tǒng)中,除了有循環(huán)用到相對坐標(biāo)系,其余都是用絕對坐標(biāo)系為上策,實際上,在實現(xiàn)編程算法上,為統(tǒng)一起見,最好將相對的坐標(biāo)關(guān)系全部轉(zhuǎn)成絕對的坐標(biāo)關(guān)系,這樣也便于外部進(jìn)行暫?;蚶^續(xù)的處理。 相信,到此為止,若你的設(shè)備在加工時有一定的誤差漂移,你會意識到自己應(yīng)該是不是要檢查一下采用了什么坐標(biāo)系了吧。 六、 輸出輸入及軟限位 對于通用的I/O操作,沒有什么特別要說明的,只有兩點需要注意的,先給出兩個小函數(shù),以作參考: int ReadBit( int nIO ); /讀指定通用輸入口的電平狀態(tài),返回1 或 0 int WriteBit( int nIO, int nStatus ); / 輸出電平到指定輸出端口 兩點注意: No.1 對于ReadBit若需要加入抗干擾處理,則寫一個函數(shù): Int RealInput( int nIO, int nStatus, int di=50 ) if( ReadBit( nIO ) != nStatus ) return 0; while( di - );/耗上幾個CPU的周期時間,再讀一次 return ReadBit( nIO ) = nStatus; No.2 增加一個變量及函數(shù)擴(kuò)展一下輸出功能: Long m_nOutStatus= 0x00000000; 再次改造一下WirteBit void WriteBit( int nIO, int nStatus ) if( nStatus ) m_nOutStatus |= (1 else m_nOutStatus &= (1 d1000_out_bit( nIO, nStatus ); 添加的訪問輸出狀態(tài)函數(shù): int ReadOutbit( int nIO ) static int a; a = 1(nIO-1); a &= m_nOutStatus; return a!=0; 軟限位的思想原本是用于為客戶節(jié)省正負(fù)限位的光電開關(guān)成本而產(chǎn)生的,致使使用軟件限位正常的話,設(shè)備每個驅(qū)動軸只需要一個原點開關(guān)即可。當(dāng)然,軟限位能正確運作是非常重要的,否則很容易撞壞設(shè)備。而其正確運行,就必須依賴正確的復(fù)位動作,以找到可靠的機(jī)械原點位置。 軟件限位的基本算法非常簡單,特別是在一個絕對坐標(biāo)系當(dāng)中。其原理如下: if( pos maxPos ) pos = maxPos; 實在沒有必要再詳說下去了。 編程技巧介紹至此算是一個了斷,若在未來的日子里,有更好的想法,我會拿出來給大家參考,請大家一起來支持這件事情,拿出自己的寶貴經(jīng)驗,算是給數(shù)控行業(yè)添加強(qiáng)有力的潤滑劑吧。 謝謝。過程控制編程之簡要探討發(fā)布日期:2009-3-9 0:42:32 瀏覽次數(shù):2160 抽像一點講,過程控制滲透在生活的各個角落。特別是在數(shù)控行業(yè),尤為明顯。早期在PLC時代,幾乎是一統(tǒng)天下。當(dāng)大小不一的控制卡公司如雨后春筍般成長起來時,控制卡在過程控制逐步體現(xiàn)出強(qiáng)勁優(yōu)勢。 其編程手段往往邦定非常成熟的編程工具,如:CB,VC,Dephi,CB。故其推廣非常迅速. 很快擁有大量客戶群。 但是,作為編程者,碰到同一程序需要控制多個同樣設(shè)備時(動作不一定同步),往往在Window多任務(wù)系統(tǒng)的影響下,很快想到多線程技術(shù),其實多線程編程對系統(tǒng)依賴性較強(qiáng),不同級別的處理,將導(dǎo)致程序的維護(hù)成本增加,并且還需要考慮線程之間的通訊,使編程起來較為麻煩。事實上,依靠過程編程的思想,會使程序獲得更簡單的做法。 純粹從編程角度來看,過程控制編程應(yīng)包含幾個要素,下面以C+偽碼方式來表示一個類,較易說明問題: /* 一個動作封裝類,包含一個 設(shè)備的所有執(zhí)行動作 */ class CAction public: CAction():m_nWorkStep(-1000) CAction() public: enum None, Inital, Start, Stop, Pause, Continue ;/部分控制標(biāo)記 public: int Control( int nStatus, void *pParam ); /要素2: 一定可以接受外部控制 int Run( void *pParam ); /要素3: 絕對有一個不斷推動的執(zhí)行過程(這是整個過程編程的心臟所在) public: int m_nWorkStep; /要素1: 必須有一個工作執(zhí)行步 private: void * m_pMemberData; /要素4: 可選,邦定被操作的數(shù)據(jù) / .其它輔助變量 ; 要素5:可選,為了能與外界用戶進(jìn)行溝通,Control函數(shù)與Run函數(shù),須選擇一個參數(shù),滿足用戶的輸入輸出。但由于用戶可選項太多,故古人告訴我們,萬事皆空即是成功,對于C+而言,沒有比void *類型更有前途了(若想體會,需搭配類型轉(zhuǎn)換更有潛力)。早在一年前,本人寫過一個過程控制器編程,并有成功實例,但今次版本,更有精裝之特點。 住下再參見一下Control函數(shù),及Run函數(shù)的一個小樣例,這將是程序員發(fā)揮強(qiáng)勁功能的場地所在。如下: int CAction:Control( int nStatus, void *pParam ) /此處的設(shè)計需要一點技巧,當(dāng)然完全取決程序員的經(jīng)驗,和對控制的理解 switch( nStatus ) case Inital: m_pMemberData = pParam;/初始化邦定的用戶數(shù)據(jù) break; case Start: m_nWorkStep = 0; /一般令第0步作為開始較易理解 break; case Stop: m_nWorkStep = -1000;/停止 break; case /其它略去 default: break; return m_nWorkStep;/返回值可自定 int CAction:Run( void *pParam ) /以下為一個動作不斷返回,直至接受到停止指令 switch( m_nWorkStep ) case 0: if( IsMove() ) break; /正在忙,不執(zhí)行 Move(1600); /正向移動1600單位 m_nWorkStep+; /跳至下一步 break; case 1: if( IsMove() ) break; /正在忙,不執(zhí)行 Move(-1600); /反向移動1600單位 m_nWorkStep=0; /再回至第0步 break; case 1000: break;/停止 default: break;/此句最好有,以便于理解 return m_nWorkStep; /返回值可自定 對于Run函數(shù)須謹(jǐn)記一點:不要有長時間的循環(huán)操作,更不要有死循環(huán),否則另外設(shè)備無法正確動作,因為另外的設(shè)備Run函數(shù)無法被激活執(zhí)行,心臟無法跳動,只好等死吧! 當(dāng)然,還須擔(dān)心一點:多個設(shè)備同時執(zhí)行時,其實時性會下降一點,若沒有特別高的要求,在現(xiàn)今CPU狂奔的時代,以上程序框架足已滿足90%的需求,還是有學(xué)習(xí)和理解的必要吧! 以上的框架出來了,那么如何操作使設(shè)備驅(qū)動起來呢,不管在DOS亦或在Window系統(tǒng)環(huán)境里,以下的思路都一樣,參見偽代碼如下: const int nSize=10; /定義10臺設(shè)備對象 CAction exeArraynSize; BOOL bRunning=FALSE;/控制整個驅(qū)動的標(biāo)志 Void OnRunAction()/啟動函數(shù) /初始化一下 for( int i(0); inSize; i+) exeArrayi.Control( CAction:Inital, ( void *)userData );/userData由用戶選擇 bRunning = true;/外部控制變量 for( i=0; bRunning; i=(i+1)%nSize)/給予運行時間,即是驅(qū)動了 exeArrayi.Run( void *)userData); /不斷驅(qū)動Action設(shè)備(即激活心臟) DoEvents();/做其它事情,如系統(tǒng)消息檢測,以防止死機(jī) DoEvents函數(shù)功能的詳解可參見本人的DMC1000控制卡不能響應(yīng)系統(tǒng)消息,上面有不同編程工具下的實現(xiàn)源代碼。 void OnControlAction() for( int i(0); i nSize; i+) exeArrayi.Control( Caction:(/*用戶想要的動作*/), ( void *)userData); void OnOver() bRunning = FALSE;/結(jié)束驅(qū)動 注意:有很多程序員在不同編譯器下,需要不同的OnRunAction函數(shù)版本,以上實現(xiàn)最為簡單,但有一些較特殊。比如:在程序啟動時,就驅(qū)動所有設(shè)備,這點本人在VC6.0環(huán)境有過經(jīng)驗,可以分享一下,其它環(huán)境下,還需同胞們一起去努力發(fā)現(xiàn)。 還有一點聲明,多線程技術(shù)也不是一無是處,在花費時間較頻繁的通訊編程方面,它的優(yōu)勢,還是有相當(dāng)?shù)恼T惑力。雷泰運動控制卡應(yīng)用程序開發(fā)注意事項概述: 對于一些初次使用雷泰運動控制產(chǎn)品的客戶,由于對本公司產(chǎn)品的特點以及程序開發(fā)流程不夠熟悉,在應(yīng)用程序的開發(fā)過程中,難免會疏漏一些細(xì)節(jié),從而產(chǎn)生各種問題,浪費很多寶貴的時間。 如果在應(yīng)用程序開發(fā)前,就可以考慮到那些既重要又容易疏漏的細(xì)節(jié),這樣可以避免很多不必要的問題產(chǎn)生,從而大大縮短程序的開發(fā)周期。本文總結(jié)以往的經(jīng)驗,以雷泰運動控制卡DMC2410B為例,為客戶在開發(fā)應(yīng)用程序時的初始化過程給出了一些參考與建議(其他產(chǎn)品與此類似),其中包括運動控制卡的初始化、特殊參數(shù)的設(shè)置及各種信號的設(shè)置,如圖1虛線框內(nèi)所示,這些處理過程必須加載至應(yīng)用程序的初始化過程中,不同編程環(huán)境下,應(yīng)用程序的初始化過程略有不同,例如在VB6.0編程環(huán)境下,須在Form_Load()函數(shù)中做程序的初始化處理,而在VC6.0編程環(huán)境下,須在OnInitDialog()函數(shù)中做程序的初始化處理。圖1DMC2410B控制卡應(yīng)用程序開發(fā)流程圖1所示的控制卡初始化過程中,實線框內(nèi)所示的參數(shù)設(shè)置或特殊信號的設(shè)置必須在初始化過程中加以處理,而虛線框內(nèi)的信號在未選擇使用時,可以不用設(shè)置,而當(dāng)選擇使用這些信號時,必須進(jìn)行正確設(shè)置。下面對這些初始化過程的方法及必要性做出簡要的說明。一、初始化運動控制卡相關(guān)函數(shù):WORD d2410_board_init (void)函數(shù)功能:為控制卡分配系統(tǒng)資源并初始化控制卡;若在應(yīng)用程序中未初始化控制卡,則系統(tǒng)無法為控制卡分配資源,導(dǎo)致控制卡無法正常使用,程序在運行時提示錯誤,彈出如圖2所示對話框:圖2未初始化控制卡時的錯誤提示 注意:程序在結(jié)束運行時,必須關(guān)閉運動控制卡,以釋放系統(tǒng)資源,否則控制卡將一直占用系統(tǒng)資源,導(dǎo)致再次運行該應(yīng)用程序時產(chǎn)生錯誤。關(guān)閉控制卡的方法及說明如下:相關(guān)函數(shù):Void d2410_board_close (void) 函數(shù)功能:釋放控制卡占用的系統(tǒng)資源。當(dāng)程序結(jié)束時必須調(diào)用此函數(shù),它與d2410_board_init()函數(shù)是一個相反的過程。二、脈沖參數(shù)設(shè)置脈沖參數(shù)包括指令脈沖類型、脈沖輸出有效電平以及方向控制邏輯電平,這些參數(shù)需根據(jù)電機(jī)驅(qū)動器的類型及參數(shù)來設(shè)置,若設(shè)置錯誤時,則會造成控制卡正常發(fā)出脈沖,而電機(jī)無法正常運轉(zhuǎn)、運轉(zhuǎn)方向錯誤或只能朝同一個方向運轉(zhuǎn)等現(xiàn)象。以下為脈沖參數(shù)設(shè)置的相關(guān)函數(shù)及說明:相關(guān)函數(shù):Void d2410_set_pulse_outmode (WORD axis, WORD outmode )函數(shù)說明:設(shè)置指定軸的脈沖輸出方式。 參數(shù)說明:axis指定軸號Outmode脈沖輸出方式選擇,其值如圖3所示:圖3脈沖類型的選擇三、特殊信號的設(shè)置 特殊信號包括限位信號、原點信號、急停信號等,對這些特殊信號未進(jìn)行設(shè)置或設(shè)置錯誤時,會導(dǎo)致控制卡無法正常輸出脈沖、電機(jī)無法正常運轉(zhuǎn)、原點回歸錯誤等現(xiàn)象,下面分別對這些信號的設(shè)置及用途加以說明:1.限位信號的設(shè)置 相關(guān)函數(shù):Void d2410_config_EL_MODE (WORD axis, WORD el_mode)函數(shù)功能:設(shè)置限位信號的有效電平及制動方式。參數(shù)說明:axis指定軸號;el_mode限位信號的有效電平和制動方式:0立即停、低電平有效;1減速停、低電平有效;2立即停、高電平有效;3減速停、高電平有效; 限位信號的有效電平需根據(jù)所使用的限位開關(guān)的類型進(jìn)行設(shè)置,DMC2410B控制卡默認(rèn)為低電平有效,若有效電平設(shè)置錯誤,則控制卡會認(rèn)為相應(yīng)軸遇到限位信號而停止輸出脈沖。2.原點信號的設(shè)置相關(guān)函數(shù):Void d2410_set_HOME_pin_logic (WORD axis, WORD org_logic, WORD filter)函數(shù)功能:設(shè)置原點信號的有效電平以及允許/禁止濾波功能。參數(shù)說明:axis指定軸號;org_logic原點信號的有效電平:0低電平有效;1高電平有效;filter允許/禁止濾波功能:0禁止;1允許; 原點信號的有效電平需根據(jù)所使用的原點開關(guān)的類型進(jìn)行設(shè)置,DMC2410B控制卡默認(rèn)為低電平有效,若有效電平設(shè)置錯誤,則會導(dǎo)致回原點運動無法啟動、回原點方向相反、未遇到原點信號時回原點動作立即結(jié)束等現(xiàn)象。3.急停信號的設(shè)置 相關(guān)函數(shù):Void d2410_config_EMG_PIN (WORD cardno, WORD enable, WORD emg_logic)函數(shù)功能:急停信號設(shè)置。急停信號有效時會立即停止所有軸脈沖的輸出。參數(shù)說明:cardno卡號enable電平設(shè)置使能:0-電平設(shè)置無效;1-電平設(shè)置有效;emg_logic急停信號的有效電平:0-低電平有效;1-高電平有效; 急停信號的有效電平需根據(jù)所使用的急停開關(guān)的類型進(jìn)行設(shè)置,DMC2410B控制卡默認(rèn)為低電平有效,若有效電平設(shè)置錯誤,則控制卡會認(rèn)為收到急停信號而停止所有軸的脈沖輸出。四、伺服專用信號的設(shè)置 伺服專用信號是針對伺服電機(jī)和驅(qū)動器而設(shè)置的,包括伺服使能信號、報警信號、誤差清除信號、零相信號、編碼器反饋輸入模式等,當(dāng)無特殊要求時,可以選擇不用控制卡去控制這些信號,但若選擇使用這些信號時,必須在程序的初始化過程中進(jìn)行正確的設(shè)置,否則會導(dǎo)致控制卡無法正常輸出脈沖、伺服電機(jī)無法正常運轉(zhuǎn)、編碼器反饋計數(shù)無法讀取或計數(shù)錯誤等現(xiàn)象,下面分別對這些信號的設(shè)置加以說明:1.伺服使能(Sevon)信號的設(shè)置 伺服使能信號的有效電平是通過控制卡的撥碼開關(guān)進(jìn)行設(shè)置,如圖4所示,DMC2410B控制卡默認(rèn)為高電平有效,若此電平設(shè)置錯誤,則會出現(xiàn)控制卡正常輸出脈沖,而伺服電機(jī)的軸未鎖緊而無法運轉(zhuǎn)的情況,此信號端子可用軟件控制,其相關(guān)函數(shù)及說明如下:相關(guān)函數(shù):Void d2410_write_SEVON_PIN (WORD axis, WORD on_off);函數(shù)功能:輸出對指定軸的伺服使能端子的控制參數(shù)說明:axis指定軸號on_off設(shè)定伺服使能電平狀態(tài):0低電平;1高電平。注意:其中SEVON輸出口初始狀態(tài)可
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《機(jī)械設(shè)計基礎(chǔ)》課件-第19章 機(jī)械的平衡與調(diào)速
- 肝腎聯(lián)合移植的手術(shù)與抗排斥治療
- 項目質(zhì)量安全課件
- 交通安全教育培訓(xùn)課件
- 音樂說課課件購買
- 油田開發(fā)項目環(huán)境影響報告書(模板)
- 電網(wǎng)側(cè)獨立儲能示范項目運營管理方案(范文模板)
- 大數(shù)據(jù)安全態(tài)勢感知解決方案
- 無人機(jī)森林防火應(yīng)用探索
- 西醫(yī)內(nèi)科題庫(含答案)
- 裝飾裝修維修改造工程施工方案
- 金屬材料凝固原理與技術(shù)PPT完整版全套教學(xué)課件
- 《論語》中的人生智慧與自我管理學(xué)習(xí)通課后章節(jié)答案期末考試題庫2023年
- 品管圈QCC質(zhì)量持續(xù)改進(jìn)案例皮膚科-降低窄頻中波紫外線照射不良反應(yīng)發(fā)生率PDCA
- 煤化工產(chǎn)業(yè)鏈詳解課件
- RB/T 303-2016養(yǎng)老服務(wù)認(rèn)證技術(shù)導(dǎo)則
- GB/T 6896-2007鈮條
- GB/T 6075.1-2012機(jī)械振動在非旋轉(zhuǎn)部件上測量評價機(jī)器的振動第1部分:總則
- 大學(xué)2023年自主招生報名登記表
- 小學(xué)體育暑假特色作業(yè)
- 2020四川考研數(shù)學(xué)二真題【含答案】
評論
0/150
提交評論