- •Министерство образования и науки Российской Федерации Федеральное государственное бюджетное образовательное учреждение
- •«Комсомольский-на-Амуре государственный технический университет»
- •1 Основные сведения
- •1.1 Описание параллельного интерфейса
- •1.2 Тестирование lpt-поpтa
- •1.3 Использование lpt-поpтa для ввода-вывода сигналов
- •2 Задание к лабораторной работе
- •3 Содержание отчета
- •4 Контрольные вопросы
1.2 Тестирование lpt-поpтa
Тестирование LPT-поpтa можно выполнить с помощью простой заглушки, которую можно изготовить, воспользовавшись табл. 7.
Таблица 7 - Таблица цепей заглушки для тестирования LPT-поpтa
|
Сигнал |
Направление |
Вывод |
Вывод Ш |
Направление |
Сигнал |
|
Data 0 |
Выход |
2 |
15 |
Вход |
-Error |
|
Data l |
Выход |
3 |
13 |
Вход |
Select |
|
Data 2 |
Выход |
4 |
11 |
Вход |
Busy |
|
Data 3 |
Выход |
5 |
10 |
Вход |
-Ack |
|
Data 4 |
Выход |
6 |
12 |
Вход |
Paper End |
Заглушка изготавливается из разъема-вилки DB-25M путем распайки на нем перемычек между контактами, указанными в таблице.
В лабораторной работе используется программа test-lpt, предложенная в [1]. Первоначально программа предназначалась для тестирования LPT-порта. Но на поверке оказалось, что с ее помощью очень удобно отлаживать новые устройства, подключаемые к LPT-порту, а также отыскивать неисправности при ремонте различных цифровых устройств. Кроме того, эта программа является прекрасным учебным пособием для начинающих программистов и схемотехников. Она написана на языке программирования C++. При запуске программы на экране монитора появляется окно работы программы, приведенное на рис. 3.

Рисунок 3 - Окно работы программы test-lpt
В центре этого окна изображен разъем LPT-порта с назначением контактов и отображением логического уровня сигнала на каждом из них. Описание сигналов разъема DB-25F параллельного порта LPT приведено в табл. 1.
В регистрах, доступных по записи, можно произвольно менять информацию, при этом состояние порта автоматически будет подчиняться действиям пользователя программы, и логические уровни на разъеме будут также изменяться. Выбор регистра по записи производится клавишей TAB. Таким образом, можно управлять LPT-портом в статическом режиме и отлаживать внешние устройства, подключенные к нему. Поскольку некоторые разряды регистров инвертируются в самом компьютере, в программу введена маска инверсии данных разрядов при чтении и записи для устранения путаницы. Поэтому данные регистры обозначены со знаком апострофа, например SR'.
В нижней части окна программы находятся строки помощи. При нажатии клавиши F10 можно вызвать до пяти экранов справочной информации для LPT- порта. В них содержится информация о назначении сигналов порта, соответствии их контактам разъема, описаны функции прерывания порта, алгоритм вывода символа на печать, адреса и назначение всех регистров порта и другая полезная информация.
Клавиши Fl - F3 позволяют выбрать номер используемого LPT- порта от 1 до 3 при их наличии в компьютере. В противном случае будет выдано сообщение о недоступности соответствующего LPT-порта, и выбор не будет произведен.
1.3 Использование lpt-поpтa для ввода-вывода сигналов
В качестве примера использования LPT-порта для управления внешним устройством рассмотрим подключение к компьютеру униполярного шагового двигателя.
Шаговый двигатель (ШД) – это электромеханическое устройство, которое преобразует электрические импульсы в дискретные механические перемещения. Шаговые двигатели обладают некоторыми уникальными свойствами, что делает их исключительно удобными для применения или даже незаменимыми в некоторых областях.
Шаговые двигатели относятся к классу бесколлекторных двигателей постоянного тока. Как и любые бесколлекторные двигатели, они имеют высокую надежность и большой срок службы, что позволяет использовать их в критичных к надежности применениях. По сравнению с обычными двигателями постоянного тока, шаговые двигатели требуют значительно более сложных схем управления, которые должны выполнять все коммутации обмоток при работе двигателя.
Одним из главных преимуществ шаговых двигателей является возможность осуществлять точное позиционирование и регулировку скорости без датчика обратной связи. Это очень важно, так как такие датчики могут стоить намного больше самого двигателя. Однако это подходит только для систем, которые работают при малом ускорении и с относительно постоянной нагрузкой. В то же время системы с обратной связью способны работать с большими ускорениями и даже при переменном характере нагрузки. Если нагрузка шагового двигателя превысит его момент, то информация о положении ротора теряется и система требует калибровки с помощью, например, концевого выключателя или другого датчика. Системы с обратной связью не имеют подобного недостатка.
При проектировании конкретных систем приходится делать выбор между обычным и шаговым двигателем. Когда требуется прецизионное позиционирование и точное управление скоростью, а требуемый момент и скорость не выходят за допустимые пределы, то шаговый двигатель является наиболее экономичным решением. Как и для обычных двигателей, для повышения момента может быть использован понижающий редуктор. Однако для шаговых двигателей редуктор не всегда подходит. В отличие от коллекторных двигателей, у которых момент растет с увеличением скорости, шаговый двигатель имеет больший момент на низких скоростях. К тому же, шаговые двигатели имеют гораздо меньшую максимальную скорость по сравнению с коллекторными двигателями, что ограничивает максимальное передаточное число и, соответственно, увеличение момента с помощью редуктора. Готовые шаговые двигатели с редукторами выпускаются промышленностью в малых объемах. Еще одним фактом, ограничивающим применение редуктора, является присущий ему люфт.
ШД обладают следующими особенностями:
1. Угол поворота ротора определяется числом импульсов, которые поданы на двигатель.
2. Двигатель обеспечивает полный момент в режиме остановки (если обмотки запитаны).
3. Прецизионное позиционирование и повторяемость. Хорошие шаговые двигатели имеют точность 3-5% от величины шага. Эта ошибка не накапливается от шага к шагу.
4. Возможность быстрого старта/остановки/реверсирования.
5. Высокая надежность, связанная с отсутствием щеток, срок службы шагового двигателя фактически определяется сроком службы подшипников.
6. Однозначная зависимость положения от входных импульсов обеспечивает позиционирование без обратной связи.
7. Возможность получения очень низких скоростей вращения для нагрузки, присоединенной непосредственно к валу двигателя без промежуточного редуктора.
8. Может быть перекрыт довольно большой диапазон скоростей, скорость пропорциональна частоте входных импульсов.
Шаговые двигатели также имеют недостатки:
1. Им присуще явление резонанса.
2. Возможна потеря контроля положения ввиду работы без обратной связи.
3. Потребление энергии не уменьшается даже без нагрузки.
4. Затруднена работа на высоких скоростях.
5. Невысокая удельная мощность.
6. Относительно сложная схема управления.
Существуют униполярные и биполярные шаговые двигатели. Первые имеют четыре обмотки с одним общим выводом и четырьмя управляющими выводами, на которые последовательно подают напряжения одной полярности. Вторые имеют всего две обмотки с четырьмя выводами, полярность напряжения на которых необходимо изменять.
Если замкнуть все выводы исправного двигателя между собой и попробовать повернуть его вал, то вал должен проворачиваться с трудом, по сравнению с тем, как он проворачивается при разомкнутых выводах.
Для согласования маломощных ТТЛ выходов LPT-порта с низким сопротивлением обмоток шагового двигателя удобно использовать микросхему драйвера ULN2003, которая содержит семь мощных транзисторных ключей n-p-n-типа, собранных по схеме Дарлингтона. Каждый ключ способен управлять нагрузкой с током потребления до 500 мА. Микросхема имеет резисторы в цепи базы, что позволяет напрямую подключить ее входы к обычным цифровым микросхемам. Все эмиттеры соединены вместе и выведены на общий вывод E. Коллекторы транзисторных ключей через выпрямительные диоды подсоединены к выводу CLMP, что позволяет управлять с помощью этой микросхемы индуктивными нагрузками при минимуме внешних компонентов. В нашем стенде использовано только четыре транзисторных ключа.
Электрическая схема подключения шагового двигателя показана на рис. 4.

Рисунок 4 – Схема включения шагового двигателя
Выводы шагового двигателя подсоединены к разрядам D0 – D3 регистра данных параллельного порта через микросхему ULN2003. Параллельно входам драйвера к разрядам D0 – D3 подключены красные светодиоды с ограничивающими ток резисторами. Это позволяет в режиме отладки и на малых скоростях вращения наблюдать порядок подачи импульсов на обмотки двигателя.
Обычно перед началом работы с устройством, использующим привод с шаговым двигателем, необходимо установить подвижный узел в начальное положение. Для получения обратной связи по положению в простейшем случае используют концевой выключатель, например, оптопару с щелью, в которую входит флажок, закрепленный на подвижном узле. В стенде флажок закреплен непосредственно на валу ротора двигателя. Такое решение позволяет легко определить не только начальное положение вала, но и число шагов на полный поворот ротора.
Роль датчика обратной связи выполняет фототранзистор оптопары. На нем построен простейший ключ с общим эмиттером, выходной ток которого дополнительно усиливается двумя ключевыми каскадами на транзисторах КТ315. Усиленный сигнал фототранзистора зажигает для наглядности зеленый светодиод и поступает на разряд S3 (вывод 15 разъема) регистра состояния порта.
Алгоритм для управления шаговым двигателем достаточно прост. Необходимо формировать на выводах порта специальную последовательность импульсов. Эта последовательность показана в табл. 8.
Таблица 8 – Комбинация импульсов для вращения вала двигателя
|
Номер шага |
D0 |
D1 |
D2 |
D3 |
|
1 |
1 |
0 |
0 |
0 |
|
2 |
1 |
1 |
0 |
0 |
|
3 |
0 |
1 |
0 |
0 |
|
4 |
0 |
1 |
1 |
0 |
|
5 |
0 |
0 |
1 |
0 |
|
6 |
0 |
0 |
1 |
1 |
|
7 |
0 |
0 |
0 |
1 |
|
8 |
1 |
0 |
0 |
1 |
Указанная в таблице последовательность реализует половинный угол поворота вала на один шаг. Если использовать комбинации только для шагов 1, 3, 5 и 7, то получим полный угол поворота вала на один шаг.
Различие между алгоритмами (полным и половинным углом поворота вала на один шаг) состоит в том, что во втором случае скорость вращения оказывается в два раза ниже, при этом в два раза уменьшается угол поворота вала двигателя на каждом шаге, т. е. увеличивается разрешающая способность системы. Также во втором случае примерно в два раза увеличивается потребляемая мощность, и кроме того, двигатель способен развивать в два раза больший крутящий момент.
Для изменения направления вращения вала двигателя необходимо формировать указанные последовательности в обратном порядке.
Ниже приведен короткий пример программы для Turbo С, работающей в операционной системе MS-DOS. Эта программа заставляет шаговый двигатель вращаться в прямом направлении, в режиме полного угла на один шаг.

Рассмотрим еще один пример программы управления шаговым двигателем на языке ассемблера. Эта программа опрашивает датчик обратной связи и автоматически устанавливает вал двигателя в исходное начальное положение. Кроме того, при запуске она выполняет полный оборот ротора с целью нахождения числа шагов на один оборот. Полученный параметр позволяет однозначно определить требуемое число шагов для поворота на нужный угол. Для вывода числовых значений на экран в удобной для оператора форме использованы подпрограммы преобразования кодов из источника [3].
; Управление шаговым двигателем через 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 преобразует целое двоичное число в AX в строку
; десятичных ASCII-цифр в ES:DI, заканчивающуюся символом «$»
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 переводит десятичное число в шестнадцатиричное
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
; Пауза
pause proc near
pushad ; поместить в стек все общие регистры
mov ecx, [freq] ; загружаем нужное число тиков RDTSC
; Вычислить опасную границу счетчика
mov ebx,0ffffffffh ; 232-1
sub ebx, ecx ; отнимаем частоту процессора
warn_bord:
;RDTSC ; чтение счетчика тактов процессора
DB 0FH, 31H ; код команды RDTSC
cmp eax, ebx ; сравнить текущее RDTSC с опасной границей
dec ecx ; вычесть уже отмерянное циклом из нужного ; числа тиков
jae warn_bord ; если больше - зациклить во избежание
; перехода через 0
mov ebx, eax ; загрузить начальное значение счетчика тактов
; Ожидать в течение ecx тиков (ecx = freq минус уже пройденные тики)
add ebx, ecx ; получить конечное значение счетчика
tp:
;RDTSC ; получить текущее значение счетчика
DB 0FH, 31H ; код команды RDTSC
cmp eax, ebx ; сравнить текущее и конечное значение
jb tp ; пока текущее меньше - зациклить
popad ; извлечь из стека все общие регистры
ret
PAUSE ENDP
