; Управление шаговым двигателем через LPT порт
DOSSEG
.MODEL SMALL ;модель памяти
.STACK 100h ; сегмент стека размером 100h
.DATA ;сегмент данных
TEXT1 DB 'Число шагов на один оборот - ', 0DH, 0AH, '$'
RESULT DB ' ', 0DH, 0AH, '$' ; число шагов на 1 оборот в ASCII
TEXT2 DB 'Задайте число шагов по часовой стрелке - ', 0DH, 0AH, '$'
TEXT3 DB 'Задайте число шагов против часовой стрелки - ', 0DH, 0AH, '$'
TEXT4 DB 'Задайте время одного шага в мкс (от 2000 до 65000) - ', 0DH, 0AH, '$'
err_msg db 'Bad number entered'
crlf db 0Dh,0Ah,'$'
buffer db 6 ; максимальный размер буфера ввода
blength db ? ; размер буфера после считывания
bcontents DB 10 DUP (0) ; содержимое буфера
ST_MCS DW 0 ; старший байт микросекунд
ML_MCS DW 10000 ; младший байт микросекунд
COUNT_T DW 1 ; счетчик шагов в полном обороте
COUNT_L DW 0 ; счетчик шагов влево
COUNT_R DW 0 ; счетчик шагов вправо
ERROR DB 0 ; флаг ошибки
.CODE ; сегмент кода
main proc ;начало процедуры main
mov ax, @DATA
mov ds, ax ; установить регистр DS
mov es, ax
MOV AH, 09H
MOV DX, OFFSET TEXT1
INT 21H ;вывод сообщения
MOV AL, 00010001B
H1: ROL AL, 1 ; установить вал в начальное положение
MOV DX, 378H ; адрес регистра данных LPT
OUT DX, AL
PUSH AX
CALL TIME ; задержка шага
MOV DX, 379H ; адрес регистра состояния LPT
IN AL, DX
TEST AL, 08H ; анализ состояния фототранзистора
POP AX
JNZ H1 ; повторить, если не начало
H2: ROR AL,1 ; шагаем вправо, чтобы убрать шторку
INC COUNT_T ; накапливаем счетчик шагов
MOV DX, 378H
OUT DX, AL
PUSH AX
CALL TIME
MOV DX, 379H
IN AL, DX
TEST AL, 08H
POP AX
JNZ H2
MOV AX, COUNT_T ; перекодируем в ASCII и выводим шаги
CALL HEX2DEC ;на монитор
MOV AH, 09H
MOV DX, OFFSET TEXT2
INT 21H ;вывод сообщения
CALL DEC2HEX ; вводим число шагов влево и
;перекодируем из ASCII в двоичное
TEST ERROR, 1
JNZ FIN ; конец, если неправильный ввод числа
MOV COUNT_L, AX ; сохраняем число шагов влево
MOV AH, 09H
MOV DX, OFFSET TEXT3
INT 21H ;вывод сообщения
CALL DEC2HEX ; вводим число шагов вправо и ;перекодируем из ASCII в двоичное
TEST ERROR, 1
JNZ FIN ; конец, если неправильный ввод числа
MOV COUNT_R, AX ; сохраняем число шагов вправо
MOV AH, 09H
MOV DX, OFFSET TEXT4
INT 21H ;вывод сообщения
CALL DEC2HEX ; вводим время шага и
;перекодируем из ASCII в двоичное
TEST ERROR, 1
JNZ FIN ; конец, если неправильный ввод числа
MOV ML_MCS, AX ; сохраняем время шага
MOV AL, 00010001B
H3: ROL AL, 1 ; вращаем двигатель влево
MOV DX, 378H
OUT DX, AL
PUSH AX
CALL TIME
DEC COUNT_L
POP AX
JNZ H3
H4: ROR AL, 1 ; вращаем двигатель вправо
MOV DX, 378H
OUT DX, AL
PUSH AX
CALL TIME
DEC COUNT_R
POP AX
JNZ H4
FIN: mov ah, 4ch ; функция DOS завершения программы
int 21h ; завершить программу
main endp ; конец процедуры main
HEX2DEC PROC NEAR ; Зубков, с. 220
MOV DI,OFFSET RESULT ;адрес результата
MOV BX, 10 ;делитель
XOR CX, CX ;счетчик цифр в 0
DIVLP: XOR DX, DX
DIV BX ;разделить число на 10
ADD DL, '0' ;добавить к остатку ASCII ?код нуля
PUSH DX ;записать цифру в стек
INC CX ;увеличить счетчик цифр
TEST AX, AX ;и, если еще есть, что делить,
JNZ DIVLP ;продолжить деление
STORE:
POP AX ;считать цифру из стека
STOSB ;дописать ее в конец строки в ES:DI
LOOP STORE ;продолжить для всех CX цифр
;MOV BYTE PTR ES:[DI], '$' ;дописать '$' в конец строки
MOV DX, OFFSET RESULT ;в DX адрес строки
MOV AH, 9
INT 21H ;вывод строки
RET
HEX2DEC ENDP
TIME PROC NEAR ; задержка в микросекундах
MOV AH, 86H
MOV CX, ST_MCS
MOV DX, ML_MCS
INT 15H
RET
TIME ENDP
DEC2HEX PROC NEAR ; Зубков, с. 152
mov dx, offset buffer
mov ah, 0Ah
int 21h ; считать строку символов в буфер
mov dx, offset crlf
mov ah,9
int 21h ; перевод строки
; перевод числа в ASCII-формате из буфера в бинарное число в AX
xor di,di ; DI = 0 - номер байта в буфере
xor ax,ax ; AX = 0 - текущее значение результата
mov cl,blength
xor ch,ch
xor bx,bx
mov si,cx ; SI - длина буфера
mov cl,10 ; CL = 10, множитель для MUL
asc2hex:
mov bl,byte ptr bcontents[di]
sub bl,'0' ; цифра = код цифры - код символа "0"
jb asc_error ; если код символа был меньше, чем код "0",
cmp bl,9 ; или больше, чем "9",
ja asc_error ; выйти из программы с сообщением об ошибке
mul cx ; иначе: умножить текущий результат на 10,
add ax,bx ; добавить к нему новую цифру,
inc di ; увеличить счетчик
cmp di,si ; если счетчик+1 меньше числа символов -
jb asc2hex ; продолжить(счетчик считается от 0)
ret ; завершение подпрограммы (результат в AX)
asc_error: MOV ERROR, 1 ; флаг ошибки
mov dx,offset err_msg
mov ah,9
int 21h ; вывести сообщение об ошибке
ret ; и завершить подпрограмму
DEC2HEX ENDP
end main ; конец программы с точкой входа main
Управление шаговым двигателем (Asm)
Необходимо написать программу на языке ассемблер вот что у меня имеется по заданию:
Имеется униполярный шаговый двигатель, который через драйвер усилителя мощности подключен к LPT порту компьютера. Требуется разработать программу увеличивающую скорость вращения при нажатии на «1» и уменьшающую при нажатии на «2»
1. Скорость вращения шагового двигателя ограничена величиной 1000 шагов в минуту.
2. Сначала удобно определить число шагов на один оборот, выполнив один начальный оборот (ориентировочно – 200 шагов на оборот).
3. Для ограничения скорости вращения удобно использовать прерывание, формирующее задержку в микросекундах.
MOV AH,86H ;номер функции
MOV CX,ST_MKS ;старшее слово задержки
MOV DX,ML_MKS ;младшее слово задержки
INT 15H ;вызов прерывания
Вот наработки того кода который нужно изменить согласно заданию:
Код:
Так никто и не смог помочь...