一、問題現象及分析
問題經常通過以下編程表現出來:

//X發出脈沖后,等待脈沖發完后再做其它事情
d1000_start_t_move( 0, 6400, 3200, 6400, 0.1 );
while( d1000_check_done(0) == 0 );">

      技術頻道

      DMC1000控制卡不能響應系統消息

      一、問題現象及分析
      問題經常通過以下編程表現出來:

      //X發出脈沖后,等待脈沖發完后再做其它事情
      d1000_start_t_move( 0, 6400, 3200, 6400, 0.1 );
      while( d1000_check_done(0) == 0 );

      老版本的庫函數如下:

      d1000_start_tr_move( 0, 6400, 3200, 6400, 0.1 );
      while( d1000_check_done(0) == 0 );

      或者:
      d1000_wait_done( 0 );
      此函數內部實際上包含類似于while( d1000_check_done(0) == 0 );的語句

      以上可以看出,在檢測脈沖是否發完時,此段代碼的執行完全獨占了CPU分配給當前進程的所有時間,
      因而也排擠了其它消息的響應,當然也就不能響應定時器讀取位置,或其它停止操作等.

      二、解決方法
      解決此問題關鍵是讓while循環時能檢測系統消息,以下分別介紹在VB,VC,CB下的解決措施:

      注:以下編程全以DMC1000最新的驅動庫函為參考

      1.VB編程
      d1000_start_t_move 0, 6400, 3200, 6400, 0.1
      DO
      DoEvents
      LOOP WHILE (d1000_check_done(0) = 0)

      2.VC編程
      在VC下編程關鍵是要解決類似于VB的DoEvnets函數

      void DoEvents()
      {
      static MSG msg;
      if( ::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE) ){
      ::TranslateMessage( &msg );
      ::DispatchMessage( &msg );
      }
      }

      然后編程如下:

      d1000_start_t_move( 0, 6400, 3200, 6400, 0.1 );
      while( d1000_check_done(0) == 0 )
      ::DoEvents();

      3.CB編程
      同樣也需要完成一個DoEvents函數的定義:
      void DoEvents()
      {
      Application->ProcessMessages();//VCL給程序帶來極大簡化
      }
      編程如下:
      d1000_start_t_move( 0, 6400, 3200, 6400, 0.1 );
      while( d1000_check_done(0) == 0 )
      ::DoEvents();

      三、技巧提升
      有了自產的DoEvents函數,是否就可以一切OK了呢。試想一個問題,實際加工時,
      通常會有大量的小線段(即短脈沖距離)出現,若頻繁的調用DoEvents勢必帶來新的麻煩,因為加工
      需要連續的進行,設備的運動之間停頓時間過長,會形成設備的多次啟停,進而易產生振動,造成
      設備的加速磨損,并且速度也快不起來。因此添加一小小技巧(實用又省錢),判斷脈沖距離是否過小
      若過小則不執行DoEvents函數,過小量可以根據自己的需求也定義一個參考量。當然程序的執行順序也
      可以優化一下,以上面程序為例:
      if( d1000_check_done(0) != 0 ) return;
      d1000_start_t_move( 0, 6400, 3200, 6400, 0.1);
      咋一看沒有什么特別的,但是請看下加工程序的部分簡化代碼,也許會有新的啟示:

      for( int i(0); i
      {

      if( d1000_check_done(0) == 0 )
      {
      if( Len > 2.0 )DoEvents();
      //小于2單位(可以指為毫米,或其它單位)則不執行DoEvents函數
      continue;
      }
      Len = dist[i].Len;
      d1000_start_t_move( 0, dist[i], speed );
      i ++;
      }
      當然,世界上做事情的方法多的是,有高手則愿意動用復雜的多任務編程方法來完成操作,
      最后經過努力,事情也可以解決,若有興趣,可參見另一篇《控制卡的多任務編程》,然后自行做
      編程測試。不過本人的理論是,解決事情的方法越簡單越好,據本人了解,大師之所以為大師,通常
      不是把問題搞得高深莫測,而是通俗易懂。

      四、其它應用
      此方法對所有DMC系列的控制卡的編程都可以運用,還可用在自定義的Arc(圓弧運動)函數
      上,參見下面偽代碼(Arc的直線擬合算法參見DMC2000的ARC算法):

      for( int i(0); i
      {
      while( IsRunning(X) || IsRunning(Y) )
      {
      if( i%16 == 0 ) DoEvents();//每16再運行一次
      }
      start_line2( newx, newy );
      }

      文章版權歸西部工控xbgk所有,未經許可不得轉載。

      主站蜘蛛池模板: 精品无人区一区二区三区在线| 日本精品一区二区在线播放| 日韩福利视频一区| 中文字幕人妻无码一区二区三区| 精品人体无码一区二区三区| 亚洲第一区二区快射影院| 国产高清在线精品一区小说| 无码中文人妻在线一区| 99精品国产一区二区三区不卡| 一区二区三区日本电影| 国产在线不卡一区| 国产成人精品亚洲一区| 尤物精品视频一区二区三区 | 精品乱码一区二区三区在线| 99无码人妻一区二区三区免费| 亚洲国产精品无码久久一区二区| 中文字幕一区二区三区在线播放 | 国产高清不卡一区二区| 一区二区三区内射美女毛片 | 男人的天堂av亚洲一区2区 | 国产精品一级香蕉一区| 人妻aⅴ无码一区二区三区| 国产精品美女一区二区视频| 久久青草国产精品一区| 久久精品道一区二区三区| 久久se精品一区二区国产| 性色AV一区二区三区| 99久久精品国产一区二区成人 | 亚洲制服丝袜一区二区三区| 久久精品国产一区二区三| 日韩综合无码一区二区| 久久久久久免费一区二区三区| 亚洲国产综合无码一区| 亚洲国产一区国产亚洲| 日韩精品一区二区三区老鸭窝| 国产精品制服丝袜一区| 久久久久人妻精品一区三寸| 日本一区二区三区精品视频| av在线亚洲欧洲日产一区二区| 国产成人无码一区二区三区在线 | 国产剧情一区二区|