2003年度  第2期


标题:用单片机最小系统实现三坐标测量系统的联动控制
作者:黄 劼,周肇飞
作者单位:四川大学制造学院
关键字:主从式控制,实时性,单片机最小系统
摘要:

本文根据某专用三坐标测量系统数据存储量大、计算复杂且控制实时性强的要求,提出了一种主从式控制模式,即用基于Windows操作系统的台式机作上位机,完成的数据存储和复杂计算;用单片机最小系统实现三坐标实时联动控制。文章给出了具体的软硬件实现方案。

 

  杂志上略去的程序清单如下:

单片机程序

LP1:       MOV       A,INPT

     MOV       COMMAND,A

     LCALL       NEWCOM                ;判断是否为新指令

LP1X:       JNB         NEW,LP1         ;不是新命令,返回

LP0:       ANL        A,#01100000B   

     SWAP       A

     RR             A

     MOV       NUMB,A                   ;识别电机号

     MOV       A,COMMAND

     ANL        A,#00001110B

     RR             A

     MOV       SPEED,A             ;速度档

     MOV       A,NUMB

     MOV R0,A

LP2:           DJNZ         R0,LP3

     LJMP       NO1                        ;1号电机

NO1:         MOV         R0,SPEED          ;判断速度档位

SP1:           DJNZ         R0,SP2                          ;1档速度用于定位,每个距离值发出12个脉冲

     SETB       FULL                       ;无升降频,立即全速移动

     MOV SPH, #0F0H            ;置速度值(高位)

     MOV SPL, #00                 ;置速度值(低位)

     MOV       XHCS,#12          ;每个距离值12个脉冲

     LJMP       RUN

SP2:           DJNZ         R0,SP3                          ;2~7档速度,每个距离值发出150个脉冲

     CLR         FULL                       ;无升降频标志

     MOV       SPH,#0F2H

     MOV       SPL,#00

     MOV       XHCS,#150               ;每个距离值150个脉冲

     LJMP       RUN

RUN:         MOV         TH0,SPH            ;给定时器置初值:电机初始速

     MOV       TL0,SPL

SETB  SELECT          ;设置为从INPT读入距离值

     MOV A,INPT                ;读取距离值

     MOV DIST,A                ;保存距离值

     CLR         SELECT             ;设置为从INPT读入指令

     MOV        C,COM_DIR

     MOV DIR1,C                ;方向

     SETB       TR0                  ;开启定时器中断

  MOV       A,COMMAND

     CPL         ACC.7                ;启动应答信号的bit7与指令的bit7相反

     MOV       OUTP,A             ;给系统机发出电机启动应答信号

     LJMP       LP1                   ;回到主循环

 

上位机程序:

#define COMMANDADR 0x300

static bool m_bStatus = FALSE;

//   功能:  向步进电机ISA卡的命令端口发出命令

//   参数:  byData

//          (入口)byData:向命令端口发出的指令

//          向命令端口发普通指令前,须使用MakeCommonCmd()创建指令,

//          然后使用此函数发出指令.

//          将对所发出的普通指令进行状态位的转换*/

void OutCmdPort(BYTE byData)

{

//对普通指令的状态位进行切换

     if ((byData >> 5) != 0x00)

     { if (m_bStatus)//bit7 <= 1

{   m_bStatus = FALSE;

                   byData = byData | 0x80;       }

            else          //bit7 <= 0

            {       m_bStatus = TRUE;

                   byData = byData & 0x7f;}

     }      

_outp(COMMANDADR, byData);

}

//   功能:  创建普通命令字

//   参数:       byMotorNo, bDirection, bySpeedLevel, bToLimit

//          (入口)byMotorNo:         电机号: 0x00-不选电机, 0x01~0x11: 1号到3号电机

//          (入口)bDirection:  移动方向, TRUE-前进(左移), FALSE-后退(右移)

//          (入口)bySpeedLevel:速度档位: 0x00-停止, 0x01-每个步长单位为0.01mm,

//                                                          0x010~0x111-每个步长单位为1/8毫米

//          (入口)bToLimit:    是否移到最左(右端), TRUE-, FALSE-

//bit7:       状态位 bit6-bit5:        电机号: 00-不选, 01-1, 10-2, 11-3

//bit4:       方向位: 1-向左, 0-向右 bit3-bit2-bit1:    速度档位

//bit0:                                是否到最左(右端): 1-, 0-

//   返回:  所创建的命令字, 且状态位bit7均为0

BYTE MakeCommonCmd(BYTE byMotorNo, BOOL bDirection,

                                                             BYTE bySpeedLevel, BOOL bToLimit)

{       BYTE byDirect;

     if (bDirection)

            byDirect = 0x10;

     else

            byDirect = 0x00;

     BYTE byLimit;

     if (bToLimit)

            byLimit = 0x01;

     else

            byLimit = 0x00;

     BYTE byCmdByte = 0x00;

     //状态位bit7暂为0,写端口时再切换状态位

     byCmdByte = (byMotorNo << 5)//电机号

                            + byDirect//方向

                            + (bySpeedLevel << 1)//速度档

                            + bToLimit;//极限

         return byCmdByte;}