📄 main.asm
字号:
BASE_ADR_ADC0809 EQU 1400H
BASE_ADR_8255 EQU 1440H
BASE_ADR_8254 EQU 1460H
STACK SEGMENT STACK
DB 100 DUP(?)
STACK ENDS
DATA SEGMENT PUBLIC
frequency DB ? ;the speed of stepping motor and singing
;sequnce DB 05H,0CH,0AH,03H ;the driver of stepping motor
;index DB 0H ;the index of array
direction DB 0H ;rotate direction,0 is ShunShiZhen and 1 is NiShiZhen
;counter DB 0H
motor DB 33H
DATA ENDS
CODE SEGMENT PUBLIC
ASSUME CS:CODE,DS:DATA,SS:STACK
;驱动步进电机旋转
rotate PROC NEAR
PUSH SI
PUSH DX
PUSH AX
CMP frequency,10h
JL exitRotate
;输出数据进行转动
MOV AL,motor
MOV DX,BASE_ADR_8255
ADD DX,02H
OUT DX,AL
CALL delay
CMP direction,0h ;调节转动驱动数据
JE clockwise
JMP anticlockwise
clockwise: ;顺时针旋转
ROL motor,1
JMP exitRotate
anticlockwise: ;逆时针旋转
ROR motor,1
exitRotate:
POP AX
POP DX
POP SI
RET
rotate ENDP
;初始化8255
init8255 PROC NEAR
PUSH DX
PUSH AX
MOV DX,BASE_ADR_8255 ;A,B口输入,C口输出,都是方式0
ADD DX,03H
MOV AL,92H
OUT DX,AL
NOP
POP AX
POP DX
RET
init8255 ENDP
;获得旋转方向
getDirection PROC NEAR
PUSH DX
PUSH AX
MOV DX,BASE_ADR_8255 ;按键key0接8255A口,0为顺时针,1为逆时针
IN AL,DX
AND AL,01H
MOV direction,AL
POP AX
POP DX
RET
getDirection ENDP
;延时
delay PROC NEAR
PUSH CX
MOV CX,0FFFFH
delayCount:
NOP
LOOP delayCount
POP CX
RET
delay ENDP
;获得电机旋转速度和蜂鸣器蜂鸣频率
getFrequency PROC NEAR
PUSH DX
PUSH AX
MOV DX,BASE_ADR_ADC0809 ;启动AD转换
OUT DX,AL
CALL delay
IN AL,DX ;取得AD转换结果,作为电机和蜂鸣器的频率
CALL delay
CMP frequency,AL
JE exitGetFrequency
MOV frequency,AL
CALL setSigning
CALL setDCMotor
exitGetFrequency:
POP AX
POP DX
RET
getFrequency ENDP
;停止蜂鸣器,将8254 gate0置为低电平
stopSigning PROC NEAR
PUSH DX
PUSH AX
MOV DX,BASE_ADR_8255 ;pc4连接gate0控制8254,设置gate0为低电平禁止计数
ADD DX,03H
MOV AL,08H
OUT DX,AL
POP AX
POP DX
RET
stopSigning ENDP
;启动蜂鸣器,将8254 gate0置为高电平
openSigning PROC NEAR
PUSH DX
PUSH AX
MOV DX,BASE_ADR_8255 ;pc4连接gate0控制8254,设置gate0为高电平启动计数
ADD DX,03H
MOV AL,09H
OUT DX,AL
POP AX
POP DX
RET
openSigning ENDP
;设置蜂鸣频率
setSigning PROC NEAR
PUSH DX
PUSH AX
CALL open8254
CMP frequency,10H ;当从AD得到的数据小于16时停止蜂鸣
JL stopSigning
stopSigning:
CALL stop8254
JMP exitSetSigning
MOV DX,BASE_ADR_8254 ;设置计数器0工作在方式3,BCD编码
ADD DX,03H
MOV AL,17H
OUT DX,AL
MOV AL,255 ;计数器值为255减去从AD得到的数据
SUB AL,frequency
MOV DX,BASE_ADR_8254
OUT DX,AL
exitSetSigning:
POP AX
POP AX
RET
setSigning ENDP
;停止直流电机,将8254 gate1置为低电平
stopDCMotor PROC NEAR
PUSH DX
PUSH AX
MOV DX,BASE_ADR_8255 ;pc5连接gate1控制8254,设置gate1为低电平禁止计数
ADD DX,03H
MOV AL,0AH
OUT DX,AL
POP AX
POP DX
RET
stopDCMotor ENDP
;启动直流电机,将8254 gate1置为高电平
openDCMotor PROC NEAR
PUSH DX
PUSH AX
MOV DX,BASE_ADR_8255 ;pc5连接gate1控制8254,设置gate1为高电平启动计数
ADD DX,03H
MOV AL,0BH
OUT DX,AL
POP AX
POP DX
RET
openDCMotor ENDP
;设置直流电机占空比
setDCMotor PROC NEAR
PUSH DX
PUSH AX
CALL openDCMotor
CMP frequency,10H ;当从AD得到的数据小于16时停止蜂鸣
JL stop
stop:
CALL stopDCMotor
JMP exitSetDCMotor
MOV DX,BASE_ADR_8254 ;设置计数器1工作在方式2,BCD编码
ADD DX,03H
MOV AL,55H
OUT DX,AL
MOV AL,frequency ;计数器值为frequency,直流电机以占空比来控制快慢
MOV DX,BASE_ADR_8254
OUT DX,AL
exitSetDCMotor:
POP AX
POP AX
RET
setDCMotor ENDP
;主过程
main PROC FAR
start:
MOV AX,DATA
MOV DS,AX
CALL init8255
next:
CALL getDirection
CALL getFrequency
MOV CX,WORD PTR frequency
speedCtrl:
CALL delay
LOOP speedCtrl
CALL rotate
MOV AH,0BH ;检测是否有键按下,若有则退出
INT 21H
CMP AL,0
JNE exitMain
LOOP next
exitMain:
NOP
main ENDP
CODE ENDS
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -