控制卡應(yīng)用編程技巧.docx_第1頁
控制卡應(yīng)用編程技巧.docx_第2頁
控制卡應(yīng)用編程技巧.docx_第3頁
控制卡應(yīng)用編程技巧.docx_第4頁
控制卡應(yīng)用編程技巧.docx_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

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

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論