IDEAL
MODEL SMALL,PASCAL
P286
wo equ word
by equ byte
macro LD r1,r2
push r2
pop r1
endm
;Ansteuerung von bis zu 6 Kreuztischen mit je 3 2-Strang-Schrittmotoren
;im Ministep-Betrieb (mit Sinustabelle)
;und - wie gehabt - mit grauenhafter Schrittweitenanpassung.
; Die Leutchen haben sich offenbar allesamt keinen Kopf gemacht,
; dabei ist es doch gar nicht soo schwer (s. vielzitierte Diplomarbeit)
public Stepper_Freq, Stepper_Startup, Stepper_Isub, Stepper_StepWidth
public Stepper_Power, Stepper_Boost, Stepper_Set, Stepper_Move
public Stepper_Step, Stepper_Arrived, Stepper_Steps
struc T3D
X dd ?
Y dd ?
Z dd ?
ends T3D
extrn Stepper_Distance:T3D:6, Stepper_Position:T3D:6
extrn Stepper_EndsMask:Byte:6, Stepper_EndsPol:Byte:6
extrn Stepper_CheckBreak:Byte
extrn Stepper_Port:Word:6, Stepper_Phase:T3D:6
extrn Stepper_SinTab:Word:256
extrn Stepper_Disabled:Byte:6
DATASEG
Stepper_Delay dd ?
Stepper_WaitVal dd ?
CODESEG
db ' (c)1992 LLT GmbH, Mnchen/BRD '
;
; SUBROUTINE
;
proc Div32
push cx si di bp
xor bp,bp
xor si,si
xor di,di
mov cx,33
@@l1:
rcl bp,1
rcl si,1
sub bp,bx
sbb si,di
jnc @@1
add bp,bx
adc si,di
@@1:
cmc
rcl ax,1
rcl dx,1
loop @@l1
pop bp di si cx
ret
endp Div32
;
; SUBROUTINE
;
proc Stepper_Startup far
cld
LD es,ds
xor ax,ax ;Variablen ausnullen
lea di,[Stepper_Port]
mov cx,6
rep stosw
lea di,[Stepper_Distance.X]
mov cx,6*6
rep stosw
lea di,[Stepper_Position.X]
mov cx,6*6
rep stosw
lea di,[by Stepper_Phase.X]
mov cx,6*6
rep stosw
lea di,[Stepper_EndsPol]
mov cx,3
rep stosw
lea di,[Stepper_Disabled]
mov cx,3
rep stosw
mov ax,3F3Fh
lea di,[Stepper_EndsMask]
mov cx,3
rep stosw
push ds
LD ds,cs ;igitt!!
lea si,[CS_SinTab]
lea di,[Stepper_SinTab]
mov cx,256
rep movsw ;Sinustabelle ins Datensegment kopieren
pop ds
mov [Stepper_CheckBreak],0
xor dx,dx
xor cx,cx
xor ax,ax
mov es,ax
mov di,46Ch ;Timer-Zelle ansteuern
mov al,[es:di]
@@l1: cmp al,[es:di] ;Warten auf Wechsel
je @@l1
mov al,[es:di] ;Neuer Zhlerstand
@@l2: cmp al,[es:di] ;Warten auf Wechsel und mitzhlen
loopz @@l2
jnz @@1 ;Raus!
inc dx ;Obere 16 bit
jns @@l2 ;solange positiv, sonst berlauf
@@1:
mov ax,cx
neg ax
mov bx,55
call Div32
mov bx,dx
mov cx,1000
mul cx
mov [wo LOW Stepper_WaitVal],ax
mov [wo HIGH Stepper_WaitVal],dx
mov ax,bx
mul cx
add [wo HIGH Stepper_WaitVal],ax
ret
endp Stepper_Startup
;
; SUBROUTINE
;
proc SetPhaseFree
lodsw ;Portadresse holen
or ax,ax ;Gltig?
jz @@e ;Raus!
mov dx,ax
add dx,4
xor ax,ax
out dx,ax
sub dx,2
out dx,ax
sub dx,2
out dx,ax
@@e: ret
endp SetPhaseFree
;
; SUBROUTINE
;
proc Stepper_Isub far
lea si,[Stepper_Port]
call SetPhaseFree
call SetPhaseFree
call SetPhaseFree
call SetPhaseFree
call SetPhaseFree
call SetPhaseFree
ret
endp Stepper_Isub
;
; SUBROUTINE
;
proc Stepper_Freq far
;arg @@Hz:Word
mov bx,sp
mov bx,[ss:bx+4]
or bx,bx
jz @@e ;Null=Fehler
mov ax,[wo LOW Stepper_WaitVal]
mov dx,[wo HIGH Stepper_WaitVal]
call Div32
mov [wo LOW Stepper_Delay],1
mov [wo HIGH Stepper_Delay],1
mov cx,ax
or cx,dx
jz @@e
or ax,ax
jnz @@1
inc ax
@@1: mov [wo LOW Stepper_Delay],ax
inc dx
mov [wo HIGH Stepper_Delay],dx
@@e: ret 2
endp Stepper_Freq
label CS_SinTab word
dw 07F00h,07F03h,07F06h,07E09h,07E0Ch,07E10h,07E13h,07E16h
dw 07D19h,07C1Ch,07C1Fh,07B22h,07A25h,07928h,0782Bh,0772Eh
dw 07430h,07333h,07236h,07139h,0703Ch,06F3Fh,06B40h,06A43h
dw 06A47h,06849h,0654Bh,0644Eh,06351h,05F52h,05F56h,05C58h
dw 05A5Ah,0585Ch,0565Fh,0525Fh,05163h,04E64h,04B65h,04968h
dw 0476Ah,0436Ah,0406Bh,03F6Fh,03C70h,03971h,03672h,03373h
dw 03074h,02E77h,02B78h,02879h,0257Ah,0227Bh,01F7Ch,01C7Ch
dw 0197Dh,0167Eh,0137Eh,0107Eh,00C7Eh,0097Eh,0067Fh,0037Fh
dw 0007Fh,0837Fh,0867Fh,0897Eh,08C7Eh,0907Eh,0937Eh,0967Eh
dw 0997Dh,09C7Ch,09F7Ch,0A27Bh,0A57Ah,0A879h,0AB78h,0AE77h
dw 0B074h,0B373h,0B672h,0B971h,0BC70h,0BF6Fh,0C06Bh,0C36Ah
dw 0C76Ah,0C968h,0CB65h,0CE64h,0D163h,0D25Fh,0D65Fh,0D85Ch
dw 0DA5Ah,0DC58h,0DF56h,0DF52h,0E351h,0E44Eh,0E54Bh,0E849h
dw 0EA47h,0EA43h,0EB40h,0EF3Fh,0F03Ch,0F139h,0F236h,0F333h
dw 0F430h,0F72Eh,0F82Bh,0F928h,0FA25h,0FB22h,0FC1Fh,0FC1Ch
dw 0FD19h,0FE16h,0FE13h,0FE10h,0FE0Ch,0FE09h,0FF06h,0FF03h
dw 0FF00h,0FF83h,0FF86h,0FE89h,0FE8Ch,0FE90h,0FE93h,0FE96h
dw 0FD99h,0FC9Ch,0FC9Fh,0FBA2h,0FAA5h,0F9A8h,0F8ABh,0F7AEh
dw 0F4B0h,0F3B3h,0F2B6h,0F1B9h,0F0BCh,0EFBFh,0EBC0h,0EAC3h
dw 0EAC7h,0E8C9h,0E5CBh,0E4CEh,0E3D1h,0DFD2h,0DFD6h,0DCD8h
dw 0DADAh,0D8DCh,0D6DFh,0D2DFh,0D1E3h,0CEE4h,0CBE5h,0C9E8h
dw 0C7EAh,0C3EAh,0C0EBh,0BFEFh,0BCF0h,0B9F1h,0B6F2h,0B3F3h
dw 0B0F4h,0AEF7h,0ABF8h,0A8F9h,0A5FAh,0A2FBh,09FFCh,09CFCh
dw 099FDh,096FEh,093FEh,090FEh,08CFEh,089FEh,086FFh,083FFh
dw 000FFh,003FFh,006FFh,009FEh,00CFEh,010FEh,013FEh,016FEh
dw 019FDh,01CFCh,01FFCh,022FBh,025FAh,028F9h,02BF8h,02EF7h
dw 030F4h,033F3h,036F2h,039F1h,03CF0h,03FEFh,040EBh,043EAh
dw 047EAh,049E8h,04BE5h,04EE4h,051E3h,052DFh,056DFh,058DCh
dw 05ADAh,05CD8h,05FD6h,05FD2h,063D1h,064CEh,065CBh,068C9h
dw 06AC7h,06AC3h,06BC0h,06FBFh,070BCh,071B9h,072B6h,073B3h
dw 074B0h,077AEh,078ABh,079A8h,07AA5h,07BA2h,07C9Fh,07C9Ch
dw 07D99h,07E96h,07E93h,07E90h,07E8Ch,07E89h,07F86h,07F83h
label CS_SinTab2 word
dw 0FF7Fh,0FFFFh,07FFFh,07F7Fh
;
; SUBROUTINE
;
proc Stepper_StepWidth far
arg @@stw:Byte
mov bl,[@@stw]
and bl,7Fh
jnz @@1
lea si,[CS_SinTab2]
lea di,[Stepper_SinTab]
mov cx,100h
xor bx,bx
LD es,ds
@@l1: mov ax,[cs:bx+si]
stosw
add bx,2
and bx,6
loop @@l1
ret
@@1:
mov dl,80h
@@l2: shr dl,1
shr bl,1
jnz @@l2
sub dh,dh
add dx,dx
lea si,[CS_SinTab]
sub bx,bx
mov cx,100h
lea di,[Stepper_SinTab]
LD es,ds
@@l3: mov ax,[cs:bx+si]
stosw
add bx,dx
and bx,1FEh
loop @@l3
ret
endp Stepper_StepWidth
;
; SUBROUTINE
;
proc Stepper_Arrived far
xor si,si
xor di,di
@@l1:
mov bx,di
mov dx,[Stepper_Port+bx+di]
or dx,dx ;Portadresse vorhanden?
jnz @@do ;ja, untersuchen
@@cont:
add si,6*2 ;Nchster Kreuztisch
inc di
cmp di,6
jc @@l1
mov ax,1
ret
@@do:
mov ch,[Stepper_Disabled+di]
test ch,3
jnz @@noX
mov ax,[(wo LOW Stepper_Distance.X)+si]
or ax,[(wo HIGH Stepper_Distance.X)+si]
jz @@noX
xor ax,ax
ret
@@noX:
test ch,0Ch
jnz @@noY
mov ax,[(wo LOW Stepper_Distance.Y)+si]
or ax,[(wo HIGH Stepper_Distance.Y)+si]
jz @@noY
xor ax,ax
ret
@@noY:
test ch,30h
jnz @@noZ
mov ax,[(wo LOW Stepper_Distance.Z)+si]
or ax,[(wo HIGH Stepper_Distance.Z)+si]
jz @@noZ
xor ax,ax
ret
@@noZ:
jmp @@cont
endp Stepper_Arrived
;
; SUBROUTINE
;
proc Stepper_Steps far
endp
proc Stepper_Step far
push bp
xor bp,bp
xor si,si ;SI "zeigert" in Zwlferschritten
xor di,di ;DI "zeigert" in Einerschritten
@@l1:
mov bx,di ;BX+DI "zeigert" in Zweierschritten
mov dx,[Stepper_Port+bx+di]
or dx,dx ;Portadresse des Kreuztisches okay?
jnz @@1 ;dann Motor ansteuern!
@@l2:
add si,6*2 ;Nchster Kreuztisch
inc di
cmp di,6 ;Letzter Kreuztisch?
jc @@l1
or bp,bp
jz @@e ;Nicht warten
xor di,di
mov es,di
mov al,[es:di] ;Was will der Typ wohl mit /0-IntVec?
mov cx,[wo LOW Stepper_Delay]
mov dx,[wo HIGH Stepper_Delay]
@@l3: cmp al,[es:di]
loopz @@l3 ;etwas warten!
dec dx
jnz @@l3 ;Und noch etwas warten!
@@e: mov ax,bp ;AX<>0 liefern, wenn Bewegung erfolgte
pop bp
ret
@@1:
in al,dx
;Endschalter in Bits 0..5
xor al,[Stepper_EndsPol+di] ;Polaritt
and al,[Stepper_EndsMask+di] ;Maske
mov cl,al
or cl,[Stepper_Disabled+di]
mov ax,[(wo LOW Stepper_Distance.X)+si]
mov bx,[(wo HIGH Stepper_Distance.X)+si]
or ax,bx ;Entfernung Null?
jz @@X_cont ;Nichts (mehr) tun
or bh,bh
jns @@X_neg ;Negativ schreiten
test cl,2 ;Endschalter "+" bettigt?
jnz @@X_0 ;ja, anhalten
add [(wo LOW Stepper_Distance.X)+si],1
adc [(wo HIGH Stepper_Distance.X)+si],0
sub [(wo LOW Stepper_Position.X)+si],1
sbb [(wo HIGH Stepper_Position.X)+si],0
inc [(by Stepper_Phase.X)+si]
jmp @@X_pos
@@X_0:
mov [(wo LOW Stepper_Distance.X)+si],0
mov [(wo HIGH Stepper_Distance.X)+si],0
jmp @@X_cont
@@X_neg:
test cl,1 ;Endschalter "-" bettigt?
jnz @@X_0 ;ja, anhalten
sub [(wo LOW Stepper_Distance.X)+si],1
sbb [(wo HIGH Stepper_Distance.X)+si],0
add [(wo LOW Stepper_Position.X)+si],1
adc [(wo HIGH Stepper_Position.X)+si],0
dec [(by Stepper_Phase.X)+si]
@@X_pos:
inc bp ;Oben: Nicht warten
mov bl,[(by Stepper_Phase.X)+si]
sub bh,bh
add bx,bx
mov ax,[Stepper_SinTab+bx]
out dx,ax
@@X_cont:
add dx,2
mov ax,[(wo LOW Stepper_Distance.Y)+si]
mov bx,[(wo HIGH Stepper_Distance.Y)+si]
or ax,bx
jz @@Y_cont
or bh,bh
jns @@Y_neg
test cl,8
jnz @@Y_0
add [(wo LOW Stepper_Distance.Y)+si],1
adc [(wo HIGH Stepper_Distance.Y)+si],0
sub [(wo LOW Stepper_Position.Y)+si],1
sbb [(wo HIGH Stepper_Position.Y)+si],0
inc [(by Stepper_Phase.Y)+si]
jmp @@Y_pos
@@Y_0:
mov [(wo LOW Stepper_Distance.Y)+si],0
mov [(wo HIGH Stepper_Distance.Y)+si],0
jmp @@Y_cont
@@Y_neg:
test cl,4
jnz @@Y_0
sub [(wo LOW Stepper_Distance.Y)+si],1
sbb [(wo HIGH Stepper_Distance.Y)+si],0
add [(wo LOW Stepper_Position.Y)+si],1
adc [(wo HIGH Stepper_Position.Y)+si],0
dec [(by Stepper_Phase.Y)+si]
@@Y_pos:
inc bp
mov bl,[(by Stepper_Phase.Y)+si]
sub bh,bh
add bx,bx
mov ax,[Stepper_SinTab+bx]
out dx,ax
@@Y_cont:
add dx,2
mov ax,[(wo LOW Stepper_Distance.Z)+si]
mov bx,[(wo HIGH Stepper_Distance.Z)+si]
or ax,bx
jz @@Z_cont
or bh,bh
jns @@Z_neg
test cl,20h
jnz @@Z_0
add [(wo LOW Stepper_Distance.Z)+si],1
adc [(wo HIGH Stepper_Distance.Z)+si],0
sub [(wo LOW Stepper_Position.Z)+si],1
sbb [(wo HIGH Stepper_Position.Z)+si],0
inc [(by Stepper_Phase.Z)+si]
jmp @@Z_pos
@@Z_0:
mov [(wo LOW Stepper_Distance.Z)+si],0
mov [(wo HIGH Stepper_Distance.Z)+si],0
jmp @@Z_cont
@@Z_neg:
test cl,10h
jnz @@Z_0
sub [(wo LOW Stepper_Distance.Z)+si],1
sbb [(wo HIGH Stepper_Distance.Z)+si],0
add [(wo LOW Stepper_Position.Z)+si],1
adc [(wo HIGH Stepper_Position.Z)+si],0
dec [(by Stepper_Phase.Z)+si]
@@Z_pos:
inc bp
mov bl,[(by Stepper_Phase.Z)+si]
xor bh,bh
add bx,bx
mov ax,[Stepper_SinTab+bx]
out dx,ax
@@Z_cont:
jmp @@l2
endp Stepper_Step
;
; SUBROUTINE
;
proc Stepper_Move far
cmp [Stepper_CheckBreak],0
jne @@2
@@l1:
call Stepper_Step
or ax,ax ;War Bewegung erfolgt?
jnz @@l1 ;Ja, noch 'ne Runde!
ret ;fertig
@@2:
xor ax,ax
mov es,ax
mov [by es:471h],0 ;CTRL-Break-Flag lschen
@@l2:
call Stepper_Step
or ax,ax ;War Bewegung erfolgt?
jz @@e ;nein, fertig
cmp [by es:471h],0 ;CTRL-Break gedrckt?
je @@l2 ;nein, weitermachen
LD es,ds
xor ax,ax
lea di,[Stepper_Distance.X]
mov cx,6*6
rep stosw ;Alle Entfernungen lschen - HALT
@@e: ret
endp Stepper_Move
;
; SUBROUTINE
;
proc SetPhaseCurrent
mov ax,0
jnz @@free ;Stromlos, wenn Z=1
mov bl,[(by Stepper_Phase.X)+si]
sub bh,bh
add bx,bx
mov ax,[Stepper_SinTab+bx]
@@free:
out dx,ax
add dx,2 ;nchstes Port
add si,4 ;nchste Phase
ret
endp SetPhaseCurrent
label CS_Mul12 word
dw 0000h,000Ch,0018h,0024h,0030h,003Ch
;
; SUBROUTINE
;
proc Stepper_Set far
arg @@Card:Word, @@Flags:Byte
iset: dec [@@Card] ;Card ist 1-basiert
mov si,[@@Card]
mov bx,si
add bx,bx ;*2
mov dx,[Stepper_Port+bx]
or dx,dx ;Keine Portadresse?
jz @@e ;raus!
mov cl,[@@Flags]
mov [Stepper_Disabled+si],cl
mov si,[cs:CS_Mul12+bx]
test cl,3
call SetPhaseCurrent
test cl,0Ch
call SetPhaseCurrent
test cl,30h
call SetPhaseCurrent
@@e: ret
endp Stepper_Set
label Magic2 byte
db 3Fh,3Ch,33h,30h,0Fh,0Ch,03h,00h
proc Stepper_Power far
arg @@Card:Word, @@Flags:Byte
mov bl,[@@Flags]
and bx,7
mov al,[cs:Magic2+bx]
mov [@@Flags],al
jmp iset
endp Stepper_Power
;
; SUBROUTINE
;
proc SetPhaseCurr2
jz @@NoOut
mov bl,[(by Stepper_Phase.X)+si]
sub bh,bh
add bx,bx
mov ax,[Stepper_SinTab+bx]
out dx,ax
@@NoOut:
add dx,2
add si,4
ret
endp SetPhaseCurr2
label CS_Magic3 byte
db 00h,03h,0Ch,0Fh,30h,33h,3Ch,3Fh
;
; SUBROUTINE
;
proc Stepper_Boost far
arg @@Card:Word, @@Flags:Byte
dec [@@Card]
mov si,[@@Card]
mov bx,si
add bx,bx
mov dx,[Stepper_Port+bx]
or dx,dx
jz @@e
mov cl,[Stepper_Disabled+si]
not cl
mov si,[cs:CS_Mul12+bx]
mov bl,[@@Flags]
and bx,7
and cl,[cs:CS_Magic3+bx]
test cl,3
call SetPhaseCurr2
test cl,0Ch
call SetPhaseCurr2
test cl,30h
call SetPhaseCurr2
@@e: ret
endp Stepper_Boost
end
Vorgefundene Kodierung: UTF-8 | 0
|