📄 step.asm
字号:
; 步进电机控制综合实验
; ⑴8279 的0~9号键作数字键
; ⑵控制键有: A--正反转切换键,控制电机的正反转
; B--提高转速,12级转速
; C--降低转速
; D--输入需要转动的步数后,按这个键,如果步数为零,一直转下去,按任意键停下;
; 如果步数不为零,转动指定步数后停下。
; LED7显示正反转:0代表正转,1代表反转
; LED5显示第几级转速
; LED3..0转动步数
.MODEL TINY
EXTRN Display8:NEAR, SCAN_KEY:NEAR
EXTRN CMD_8279:WORD, DATA_8279:WORD
PCIBAR1 EQU 14H ;PCI9052 I/O基地址(用于访问局部配置寄存器)
PCIBAR3 EQU 1CH ;8位I/O空间基地址(它就是实验仪的基地址,也为DMA & 32 BIT RAM板卡上的8237提供基地址)
PCIIPR EQU 3CH ;IRQ号
INTCSR EQU 4CH ;PCI9052 INTCSR地址
mask_int_9052 EQU 24H
Vendor_ID EQU 10EBH ;厂商ID号
Device_ID EQU 8376 ;设备ID号
.STACK 100
.DATA
IO8259_0 DW 00F0H
IO8259_1 DW 00F1H
RD_IO8259 DW 0000H
Con_8253 DW 00E3H
T0_8253 DW 00E0H
IO8255_Con DW 00D3H ;CS3
IO8255_PC DW 00D2H
IO_Bit8_BaseAddress DW ?
PCI_IO_BaseAddress0 DW ?
PCI_IRQ_NUMBER DB ?
INT_MASK DB ?
INT_Vector DB ?
INT_CS DW ? ;保护原中断入口地址
INT_IP DW ?
msg0 DB 'BIOS不支持访问PCI $'
msg1 DB '找不到Star PCI9052板卡 $'
msg2 DB '读PCI9052 I/O基地址时出错$'
msg3 DB '读8位I/O空间基地址时出错$'
msg4 DB '读IRQ号出错$'
StepControl DB 0 ;下一次送给步进电机的值
buffer DB 8 DUP(0) ;显示缓冲区,8个字节
buffer1 DB 8 DUP(0) ;显示缓冲区,8个字节
SpeedNo DB 0 ;选择哪一级速度
StepDelay DB 0 ;转动一步后,延时常数
StartStepDelay DB 0 ;如果选择的速度快于启动速度,延时由长到短,最终使用对应的延时常数
StartStepDelay1 DB 0 ;StartStepDelay
bFirst DB 0 ;有没有转动过步进电机
bClockwise DB 0 ; =1 顺时针方向 =0 逆时针方向转动
bNeedDisplay DB 0 ;已转动一步,需要显示新步数
StepCount DW 0 ;需要转动的步数
StepDelayTab: DB 250,125,83,62,50,42,36,32,28,25,22,21
.CODE
START: MOV AX,@DATA
MOV DS,AX
MOV ES,AX
NOP
CALL InitPCI
CALL ModifyAddress ;根据PCI提供的基地址,将偏移地址转化为实地址
CALL ModifyVector ;修改中断向量、允许中断
MOV bFirst,1 ;有没有转动过步进电机
MOV bClockwise,1 ;顺时针方向
MOV StepControl,33H ;下一次送给步进电机的值
MOV SpeedNo,5 ;第五级速度
CALL Init8255
CALL Init8253
CALL Init8259
; CALL WriIntver
MOV buffer,0 ;显示缓冲器初始化
MOV buffer+1,0
MOV buffer+2,0
MOV buffer+3,0
MOV buffer+4,10H
MOV AL,SpeedNo
MOV buffer+5,AL
MOV buffer+6,10H
MOV buffer+7,0
STAR2: LEA SI,buffer
LEA DI,buffer1
MOV CX,8
REP MOVSB
LEA SI,buffer1
CALL Display8
STAR3: CALL IfExit
CALL Scan_Key
JB STAR5
CMP bNeedDisplay,0
JZ STAR3
MOV bNeedDisplay,0
CALL Step_SUB_1
JMP STAR2
STAR5: CLI ;终止步进电机转动
CMP AL,10
JNB STAR1
MOV AH,buffer+2
MOV buffer+3,AH
MOV AH,buffer+1
MOV buffer+2,AH
MOV AH,buffer
MOV buffer+1,AH
MOV buffer,AL
JMP STAR2
STAR1: CMP AL,14
JNB STAR3
LEA SI,DriverTab
SUB AL,10
SHL AL,1
XOR AH,AH
MOV BX,AX
JMP CS:[SI+BX]
DriverTab: DW Direction ;转动方向
DW Speed_up ;提高转速
DW Speed_Down ;降低转速
DW Exec ;步进电机根据方向、转速、步数开始转动
Direction: CMP bClockwise,0
JZ Clockwise
MOV bClockwise,0
MOV buffer+7,1
AntiClockwise: CMP bFirst,0
JZ AntiClockwise1
MOV StepControl,91H
JMP Direction1
AntiClockwise1: MOV AL,StepControl
ROR AL,2
MOV StepControl,AL
JMP Direction1
Clockwise: MOV bClockwise,1
MOV buffer+7,0
CMP bFirst,0
JZ Clockwise1
MOV StepControl,33H
JMP Direction1
Clockwise1: MOV AL,StepControl
ROL AL,2
MOV StepControl,AL
Direction1: JMP STAR2
Speed_up: MOV AL,SpeedNo
CMP AL,11
JZ Speed_up2
Speed_up1: INC AL
MOV SpeedNo,AL
MOV buffer+5,AL
Speed_up2: JMP STAR2
Speed_Down: MOV AL,SpeedNo
CMP AL,0
JZ Speed_Down1
DEC AL
MOV SpeedNo,AL
MOV buffer+5,AL
Speed_Down1: JMP STAR2
Exec: MOV bFirst,0
CALL TakeStepCount
LEA BX,StepDelayTab
MOV AL,SpeedNo
XLAT
MOV StepDelay,AL
CMP AL,50
JNB Exec1
MOV AL,50
Exec1: MOV StartStepDelay,AL
MOV StartStepDelay1,AL
STI
JMP STAR2
TIMER0: PUSH AX
PUSH DX
CALL ClearInt
; MOV DX,RD_IO8259
; IN AL,DX
; IN AL,DX ;判断由哪个中断源引起的中断
; IN AL,DX
DEC StartStepDelay
JNZ TIMER0_1
MOV AL,StartStepDelay1
CMP AL,StepDelay
JZ TIMER0_2
DEC AL
MOV StartStepDelay1,AL
TIMER0_2: MOV StartStepDelay,AL
MOV AL,StepControl
MOV DX,IO8255_PC
OUT DX,AL
CMP bClockwise,0
JNZ TIMER0_3
ROR AL,1
JMP TIMER0_4
TIMER0_3: ROL AL,1
TIMER0_4: MOV StepControl,AL
CMP StepCount,0
JZ TIMER0_1
MOV bNeedDisplay,1
DEC StepCount
JNZ TIMER0_1
add sp,8 ;小写部分允许使用单步、单步进入命令
popf
cli
pushf
sub sp,8
nop
TIMER0_1: ; MOV DX,IO8259_0
; MOV AL,20H
; OUT DX,AL
POP DX
POP AX
IRET
Step_SUB_1 PROC NEAR
MOV CX,4
LEA BX,buffer
Step_SUB_1_1: DEC BYTE PTR [BX]
CMP BYTE PTR [BX],0FFH
JNZ Step_SUB_1_2
MOV BYTE PTR [BX],9
INC BX
LOOP Step_SUB_1_1
Step_SUB_1_2: RET
Step_SUB_1 ENDP
TakeStepCount PROC NEAR
MOV AL,buffer+3 ;转动步数送入StepCount
MOV BX,10
MUL BL
ADD AL,buffer+2
MUL BL
ADD AL,buffer+1
ADC AH,0
MUL BX
ADD AL,buffer
ADC AH,0
MOV StepCount,AX
RET
TakeStepCount ENDP
Init8255 PROC NEAR
MOV DX,IO8255_Con
MOV AL,80H
OUT DX,AL ;8255 PC输出
DEC DX
MOV AL,0FFH
OUT DX,AL ;0FFH->8255 PC
RET
Init8255 ENDP
Init8253 PROC NEAR
MOV DX,Con_8253
MOV AL,35H
OUT DX,AL ;计数器T0设置在模式2状态,BCD码计数
MOV DX,T0_8253
MOV AL,00H
OUT DX,AL
MOV AL,03H
OUT DX,AL ;CLK0/400
RET
Init8253 ENDP
Init8259 PROC NEAR
MOV DX,IO8259_0
MOV AL,13H
OUT DX,AL
MOV DX,IO8259_1
MOV AL,08H
OUT DX,AL
MOV AL,09H
OUT DX,AL
MOV AL,0FEH
OUT DX,AL
RET
Init8259 ENDP
IfExit PROC NEAR
PUSH AX
PUSH DX
MOV AH,06H
MOV DL,0FFH
INT 21H
POP DX
POP AX
JZ IfExit1
JMP Exit
IfExit1: RET
IfExit ENDP
InitPCI PROC NEAR
MOV AH,00H
MOV AL,03H
INT 10H ;清屏
MOV AH,0B1H
MOV AL,01H
INT 1AH
CMP AH,0
JZ InitPCI2
LEA DX,msg0
InitPCI1: MOV AH,09H
INT 21H
JMP Exit
InitPCI2: MOV AH,0B1H
MOV AL,02H
MOV CX,Device_ID
MOV DX,Vendor_ID
MOV SI,0
INT 1AH
JNC InitPCI3 ;是否存在Star PCI9052板卡
LEA DX,msg1
JMP InitPCI1
InitPCI3: MOV DI,PCIBAR1
MOV AH,0B1H
MOV AL,09H
INT 1AH ;读取该卡PCI9052基地址
JNC InitPCI4
LEA DX,msg2
JMP InitPCI1
InitPCI4: AND CX,0FFFCH
MOV PCI_IO_BaseAddress0,CX
MOV DI,PCIBAR3
MOV AH,0B1H
MOV AL,09H
INT 1AH ;读取该卡扩展的8位IO基地址
JNC InitPCI5
LEA DX,msg3
JMP InitPCI1
InitPCI5: AND CX,0FFFCH
MOV IO_Bit8_BaseAddress,CX
MOV DI,PCIIPR
MOV AH,0B1H
MOV AL,09H
INT 1AH ;读取IRQ号
JNC InitPCI6
LEA DX,msg4
JMP InitPCI1
InitPCI6: MOV PCI_IRQ_NUMBER,CL
RET
InitPCI ENDP
ModifyAddress PROC NEAR
MOV AX,IO_Bit8_BaseAddress
ADD IO8259_0,AX
ADD IO8259_1,AX
ADD RD_IO8259,AX
ADD Con_8253,AX
ADD T0_8253,AX
ADD IO8255_Con,AX
ADD IO8255_PC,AX
ADD CMD_8279,AX
ADD DATA_8279,AX
RET
ModifyAddress ENDP
ModifyVector PROC NEAR
PUSH ES
MOV AL,PCI_IRQ_NUMBER
CMP AL,08H
JAE ModifyVector1
ADD AL,08H ;IRQ0..7 -> 中断向量8..F
JMP ModifyVector2
ModifyVector1: ADD AL,70H-08H ;IRQ8..F -> 中断向量70H..77H
ModifyVector2: MOV INT_Vector,AL
MOV AH,35H
INT 21H
MOV INT_IP,BX ;保护原中断处理例程地址
MOV AX,ES
MOV INT_CS,AX
MOV AL,INT_Vector
LEA DX,TIMER0
PUSH DS
PUSH CS
POP DS
MOV AH,25H
INT 21H ;设置新中断向量
POP DS
MOV BL,PCI_IRQ_NUMBER
MOV DX,21H
CMP AL,08H
JB ModifyVector3
MOV DX,0A1H
ModifyVector3: IN AL,DX
MOV INT_MASK,AL
AND BL,07H
MOV CL,BL
MOV BL,1
SHL BL,CL
NOT BL
AND AL,BL
OUT DX,AL ;允许中断
POP ES
RET
ModifyVector ENDP
ClearInt PROC NEAR ;清楚PCI9052、系统中断控制器的中断标志
MOV DX,PCI_IO_BaseAddress0
ADD DX,INTCSR
; IN AL,DX
; AND AL,mask_int_9052
; JZ ClearInt3 ;不是8259引取的中断
INC DX
IN AL,DX
OR AL,0CH
OUT DX,AL ;清除PCI9052的中断标志位
MOV AL,PCI_IRQ_NUMBER
CMP AL,08H
JAE ClearInt1
AND AL,7
OR AL,60H
MOV DX,20H
OUT DX,AL
JMP ClearInt2
ClearInt1: AND AL,7
OR AL,60H
MOV DX,0A0H
OUT DX,AL
MOV DX,20H
MOV AL,62H
OUT DX,AL
ClearInt2: CLC
RET
;ClearInt3: STC
; RET
ClearInt ENDP
Exit: CLI
MOV BL,PCI_IRQ_NUMBER
MOV DX,21H
CMP AL,08H
JB Exit1
MOV DX,0A1H
Exit1: MOV AL,INT_MASK
OUT DX,AL ;屏蔽中断
PUSH DS
MOV AL,INT_Vector
MOV DX,INT_IP ;保护原中断处理例程地址
MOV AX,INT_CS
MOV AH,25H
INT 21H ;设置新中断向量
POP DS
STI
MOV AH,4CH
INT 21H
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -