标题:用单片机最小系统实现三坐标测量系统的联动控制 作者:黄 劼,周肇飞 作者单位:四川大学制造学院 关键字:主从式控制,实时性,单片机最小系统 摘要: 本文根据某专用三坐标测量系统数据存储量大、计算复杂且控制实时性强的要求,提出了一种主从式控制模式,即用基于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;} |