运动控制卡应用编程技巧(1)

2018-11-06   阅读:96

  //如许,即便多次挪用也不样怕了,呵呵,虫篆之技也能够除虫啊 } 必需额外声明一下,不是不注沉资本的释放,而是做为一个C++法式员写下这些代码是根基的权利(这也是我为什么要交待读者必必要有必然的C++根本): class CctrlCard { public: ~CctrlCard() {//定义析构函数,正在此释放资本,对此,我不想再转到读者的眼球了 d1000_board_close()同时,为了提高针对性,大部门节制卡挪用的函数会明白指出是邦定哪些卡的,现实使用时,法式员可自行选择,以表现一下本人的智商是能够写写软件的。正在一言难尽MFC的环境下,我建议两个小方式: No.1 将CctrlCard的函数置于Cmainframe的OnCreate或者Capp::Initstance内挪用 No.2 将InitBoard函数稍加改形成如许: Int CctrlCard::InitBoard() { static int n(-1000)int dir以上方式实正在太简单了,良多人城市高兴起来。既然节制卡资本是独一的,那么最好Cctrlcard发生的实例也是独一的,如许,我们能够便利的需要定义一个全局变量即可: CctrlCard g_Dmcard} } 二、 数据布局及数据类型的定义,部门相关声明 挪用节制卡驱动函数时,经常会有如下形式: 单轴相对活动 d1000_start_t_move( axis, pulse, start, speed, accel )方式都很简单,环节是要想获得。//脉冲当量 long nRP

  //行程 }以上的挪用,良多反复单调,又不曲不雅,难于理解,而且正在面向客户时,常常是指每分几多米,或者每秒几多毫米,很少有人问每秒几多脉冲,挪动几多脉冲做距离,故需要单元之间的换算。正在DMC3000节制卡,其值正在第9位,则如许: ORGIN=1<<9//每转脉冲数 double fJourey//留意,-1000是节制卡函数不成能前往的值 if( n==-1000 ) n=d1000_board_init()。

  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 )本色上,正在以下的几个技巧,也需要正在此澄清一些概念。单轴绝对活动 d1000_start_ta_move( axis, pulse, start, speed, accel )两轴相对插补 d1000_start_t_line( axisArray, distArray, start, speed, accel )定义ORGIN,LIMIT_A, LIMIT_B为变量,是有两个意义: No.1 当你拜候它们的形态时,不需要每次挪用d1000_get_axis_status函数,你能够如许: Int nStatus=d1000_get_axis( XCH )tag_AXIS m_axis[MAX_AXIS]//毫米转成脉冲 mitric to pulse 现正在,再回过甚来完成Move函数的实现,以便获得一点点成绩感,同时也展现一下以上的大堆表述是有其意义的。double decel两轴绝对插补 d1000_start_ta_line( axisArray, distArray, start, speed, accel )//正在DEBUG版本下,只要n==1的环境下能够通过 //不然,会呈现致命错误,还好,它会告诉你错正在哪个文件, //哪一行,呵呵,是个好东东啊。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以上的布局具有类的特征,可是因为其每个成员都能够给外部间接利用,故就不需要什么类的public及其析构函数的定义了。明显,对于这些问题,我想,C++法式员该当找到用武之地了,所以我们一步一步来,慢慢同一各个问题。

  //指定pString邦定的数据不克不及被点窜 char * const pString一、 节制卡类的单一实例实现 把节制卡类做一个类来处置,几乎所有C++法式员都为举双手暗示附和,故第一个什么都没有的伪代码就此发生,如下表示:class CCtrlCard { public: …Function public: …attrib } 于是,用这个CctrlCard能够发生n多个节制卡实例,只需内存脚够。当然,你也能够将上面的方式插手到InitBoard傍边去,能够避你的无认识的多次挪用了。} 还有一种方式,环境稍加复杂,但表达的功能也要强一些,以下展示能够稍微抚慰一下代码狂。//定义一个静态函数,以表警示 } int CctrlCard::InitBoard() { return d1000_board_init()好比要实现的单轴驱动函数,就变得很是了然: void Move( int nAxis, double fMM, const SPEED speed, int nFlag=M_ABS )} 是不是很简单呢,当外部挪用时,客户的不雅念就间接面临Metric即可,如: Move( XCH, 10.0, SPEED(5,10,0.1), M_ABS )先来几个宏定义提高一下情感: # define MAX_AXIS 4 //最多轴数 # define XCH 0 //定义X轴的值 # define YCH 1 # define ZCH 2 # define UCH 3 …..(其它以次类推) # define M_ABS 0x01 //定义一个绝对标记位 # define M_INP 0x02 //定义一个插补位 接下来深切一点点,再来几个布局定义: 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)//定义如许一个构制函数需要怯气,看似不合理,可是好用麻 { } double ox,oy}之所以全都采用double的数据类型,是面向客户习惯及单元计较便利的。然而,针对现实世界,环境并不那么夸姣。No.2 你能够扩展分歧的卡,当外部挪用的法式逻辑已被确按时,当你需要从DMC1000节制卡升级到DMC3000节制卡时,只需要给ORGIN等形态位指定分歧的值即可。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 ): //留意是冒号,?:是一个表达式 d1000_start_t_move( nAxis, //相对 M2P( nAxis, fMM), M2P( nAxis, speed.start ), M2P( nAxis, speed.speed), Speed.accel );double scc;圆弧相对插补 d3000_start_t_arc( axisArray, C1, C2, E1,E2, dir, start, speed, accel );double ex,ey;正在其它需要挪用的处所,进行外部呼叫: extern CctrlCard g_DmcCard;//往后我们再具体完美其实现。圆弧绝对插补 d3000_start_ta_arc( axisArray, C1, C2, E1,E2, dir, start, speed, accel );//指定原点形态位 mutable int LIMIT_A, LIMIT_B。

  //含上面两种指定功能 当然,随便提示一下,这些源代码若需要插手你的软件工程傍边,还需要做一些调整和点窜,因而,这些源代码本色上称为伪代码也能够,之所以展示它们,是让法式员们有个可视化的快感,出格是那些认为源代码就是一切的法式员。//请留意这个构制函数的定义 } CctrlCard::CctrlCard() {//呵呵,也很了然 static int n(0);附:无认识的多次挪用经常发生,出格是那些对MFC机制不明白的法式员,正在多文档框架下,不晓得这个CctrlCard::InitBoard函数到底是该当放正在CmainFrame的OnCreate里面,仍是该当放正在CchildFrame的OnCreate,或者是Cview的OnInitUpdate里面进行挪用。对于tag_AXIS定义,引出几个函数的声明,特地为其办事: void SetUP( nit nAxis, double fMM, double nPulse, double fMax );以上两个ARC和SPEED的布局定义,把几个参数变成一个参数。指定形态位的值也有一 个小小的技巧,以ORGIN为例,正在DMC1000节制卡,其位值正在2位,则能够如许: ORGIN=1<<2;//指定pString的地址不克不及被点窜 const char * const pString;关于源代码的阅读,需要读者有必然的C++编程根本,至多对以下暗示形式不会发生曲解: const char *pString。

  //达到绝对位置10.0毫米处。//指定摆布限位形态位 private: //以下的属性不给外部拜候的 struct tag_AXIS{//单轴属性 double fUnitPM;double speed;本色上,方式还有良多,即然能够发生n多对实例,我们的焦点是只需包管挪用board_init函数一次即可,故也能够零丁定义一个 InitBoard函数: class CctrlCard { public: static int InitBoard();//每次挪用CctrlCard生成实例时,城市计数一次 assert( n==1 );//留意,是个静态变量 n++;接下来是对节制卡常用的单元计较及部门常用变量的声明: class Cctrlcard { public: …(其它略去) public: //属性 mutable int ORGIN;Class CctrlCard { public: CctrlCard();//设定当量 double P2M ( int nAxis, long nPulse );//脉冲转成毫米 pulse to metric long M2P( int nAxis, double fMM );初始化函数就是C++的new或malloc的操做,取得系统的资本,可是节制卡的资本取内存纷歧样,取得资本后必需要释放才能够再次获取,即节制卡资本是独一的。double accel;}SPEED;} 通过强行报警处置,当你有g_DmcCard这个实例时,其它的所有节制卡的定义都只能是以援用或指针的体例进行了,不会再发生新无效的实例了,对于由小组编程的项目软件,而你又刚好担任编程节制卡这一块的话,以上的显性报警,会让其它人心领神会。凡是环境下,PC机内只插同品种型的节制卡1到2张,正在通过挪用d1000_board_init或d3000_board_init函数时,它们会担任前往无效卡数nCards,然后从0-nCards*4 - 1自行按排好轴数。return n;}ARC!

新媒体

在线编程技术在CAN现场设备中
最小的嵌入式正在线编程、仿实正在验器SL-K51L[N];2004全国测控、计量取仪器仪表学术年会论文集(下册)[C];2003年04期 4 毋富