|
|
以愚人之见,运动控制的编程使用多任务确实令人不可理解,因本人的理论是在数控行业编程,越是简单就越好操作。但既有客户的需求,那也得进行编程测试一下,毕竟实践出真知嘛。 从理论上讲,Window比较大牌的编译都是支持多任务编程(即多线程)。以下,为了使事情更简化,本人从VC6.0环境下写成一段小小代码,配上一些注释,望能了以解明。 本例程序基本思路是这样的,开辟一个新的线程,在线程中不断显示位置。以下列出相关步聚:
1、在可视类(如Cdialog)声明两个变量 CWinThread *pThread; //线程变量 BOOL bActive; //状态,用于终止线程
2、给变量初始化,至于构造函数中 pThread = NULL; bActive = FALSE; 3、在初始化控制成功后,分配并激活线程工作 以下部分是在OnInitDialog()中完成的 if( d3000_board_init() <= 0 ) MessageBox(Fail initial ); Else { pThread = AfxBeginThread( //创建一个线程 (AFX_THREADPROC)TaskFunc, //这是线程的工作内容,一个函数指针 (LPVOID)&m_hWnd, //传入当前可视类的句柄 THREAD_PRIORITY_NORMAL,//优先级正常 0, //无堆栈 CREATE_SUSPENDED//线程被创建时即刻挂起 ); if( pThread != NULL ) { bActive = TRUE;//允许线程工作 pThread->ResumeThread();//开始工作 } } 若需要更多了解AfxBeginThread函数,可参见MSDN说明
4、为线程分配一个工作 这个工作就是读取板卡的位置,注意此函数为静态函数 UINT CTaskDlg::TaskFunc(LPVOID lParam) { CTaskDlg * pDlg = (CTaskDlg *)FromHandle(*((HWND *)lParam));//将句柄恢复成可视类 if( pDlg == NULL ) return 0;
static CString string; long nStart = ::GetTickCount(),nEnd(nStart); while( pDlg->bActive )//当bActive为FALSE工作结束 { nEnd = ::GetTickCount(); if( labs(nEnd - nStart) >= 100 )//100毫米刷新一次,因为线程执行速度比定时要快很多,频繁高速的刷新反而让人看不清,要不去掉else continue即可。 { nStart = nEnd; } else continue;
string.Format("Position:%ld, %ld, %ld, %ld", long(d3000_get_command(0)), long(d3000_get_command(1)), long(d3000_get_command(2)), long(d3000_get_command(3))); //取得四轴的脉冲位置,并刷新到一个ID名为IDC_STATIC_COUNT控件上 pDlg->GetDlgItem( IDC_STATIC_POSITION )->SetWindowText( string ); } return 1; }
5、结束线程 此段代码放置于OnDestroy()函数中 bActive=FALSE; //停止线程工作 delete pThread; //删除线程(可以不需要此语句,创建线程时若不特别指定,线程会自动被删除)。 d3000_board_close();//关闭控制卡须放大线程结束后,否则线程读到的位置会不正确
6、后记补充 据我所知,要是用线程来作实时性强的过程控制将是个不错的选择,因为定时器的响应速度太慢,不及线程执行速度快。若想更多了解过程控制编程的特点,可参见另一篇《过程控制编程探计》。
|
|
状 态:
离线
公司简介
产品目录
|
|
公司名称:
|
深圳市雷赛智能控制股份有限公司
|
联 系 人: |
梁邦敏
|
电 话: |
755-26401178
|
传 真: |
|
地 址: |
深圳市南山区登良路天安南油工业区2栋3楼 |
邮 编: |
518000 |
主 页: |
|
|
|
|
|