Глава 7. Ввод/вывод.
Раздел 1. Доступ к последовательному порту.
7.1.6 Передача данных.
Передача данных проще чем прием, поскольку программа имеет полный контроль над составом данных и скоростью, с которой они должны посылаться. Тем не менее процедуры передачи могут быть достаточно сложными, если они обрабатывают данные по мере того, как они посылаются. Могут быть также проблемы с синхронизацией при использовании протокола XON/XOFF. Этот протокол использует коды ASCII 17(XON) и 19(XOFF), для того чтобы сигнализировать принимающей станции, что передатчик хочет продолжить передачу временно прерванного потока данных. Чтобы принять эти сигналы, программа должна непрерывно анализировать принимаемые символы при передаче (в полнодуплексном режиме, в котором обычно работают модемы, сигналы одновременно идут в обе стороны по телефонному каналу). Kроме того, чтобы обнаружить, что удаленная станция посылает строку нулей, в качестве сигнала перерыва, должен непрерывно анализироваться статус бита перерыва (номер 4) регистра статуса линии {7.1.4}. Hа рис. 7-2 (в {7.1.7}) показано как процедура передачи данных взаимодействует с кодом, принимающим данные.
Вследствие этих причин, представленные в этом пункте процедуры отдельно передающие данные являются искуственными. Hо их можно скомбинировать с процедурами приема данных, описанными в {7.1.7} для создания общего представления о том, что нужно. Ясно, что для создания работоспособной процедуры необходимо затратить большие усилия, особенно в части обнаружения и исправления ошибок при передаче данных.
Средний уровень.
Функция 1 прерывания 14H BIOS посылает символ, содержащийся в AL в коммуникационный канал. При входе DX содержит номер порта (0 или 1). При возврате AH содержит байт статуса, в котором бит 7 = 1, если операция неуспешна. В этом случае имеют значение следующие биты:
бит 4 обнаружен перерыв (сигнал "стоп" от принимающей станции) 5 регистр сдвига передатчика пуст 6 регистр хранения передатчика пуст
MS DOS имеет функцию для передачи по коммуникационному каналу символа, помещаемого в DL. Это функция номер 4 прерывания 21H, но она не имеет никаких преимуществ перед функцией BIOS; она не возвращает статусной информации и не позволяет назначать какой из коммуникационных портов надо использовать (всегда используется COM1).
Чтобы вывести строку данныз используйте функцию 40H прерывания 21H. Это обычная функция вывода для всех файлов и устройств при использовании метода доступа дескриптора файлов. COM1 имеет прелопределенный номер #3. Поместите номер файла в BX, а число передаваемых байтов в CX. Пусть DS:DX указывают на буфер выводимых данных и вызывайте функцию.
MOV AH,40H | ;номер функции |
MOV BX,3 | ;предопределенный номер файла для COM1 |
MOV CX,50 | ;выводим 50 байтов |
LEA DX,DATA_BUFFER | ;DS:DX указывают на буфер данных |
INT 21H | ;посылаем данные |
JC COM_ERROR | ;уход на обработку ошибки |
Hизкий уровень.
Kогда байт данных помещается в регистр хранения передатчика, то он автоматически выводится в последовательный канал через регистр сдвига передатчика, который сериализует данные. Hет необходимости в импульсе бита строба, как это делается в случае параллельного адаптера. Бит 5 регистра статуса линии показывает свободен ли регистр хранения передатчика для приема данных. Регистр постоянно проверяется до тех пор, пока бит 5 не станет равным 1. После этого в регистр хранения передатчика посылается очередной байт из того места, откуда они берутся. В процессе передачи бит 5 равен 0 и только когда он опять станет равным 1, то в регистр хранения передатчика может быть послан следующий символ. Этот процесс повторяется до тех пор, пока это нужно.
В следующем примере даны основные понятия об этой процедуре. Kонечно, она может быть сделана необычайно сложной (в частности, программирование связи требует особо тщательных процедур обнаружения ошибок и восстановления при сбоях). В примере предполагается, что коммуникационный порт и модем уже инициализированы, как показано в {7.1.2} и {7.1.5}. Первая часть это цикл проверки ошибок и приема символов. В {7.1.7} приведен код для процедуры приема данных.
;---ждем пока все будет готово для посылки символа | |
KEEP_TRYING: MOV DX,BASE_ADDRESS | ;базовый адрес |
ADD DX,5 | ;указываем на регистр статуса линии |
IN AL,DX | ;получаем байт статуса |
TEST AL,00011110B | ;проверяем на ошибку |
JNZ ERROR_ROUTINE | ;если есть, то на процедуру обработки |
TEST AL,00000001B | ;проверяем получены ли данные |
JNZ RECEIVE | ;если да, то на процедуру приема |
TEST AL,00100000B | ;проверяем готовность к передаче |
JZ KEEP_TRYING | ;если нет, то возвращаемся назад |
;---передаем символ принимаемый с клавиатуры | |
MOV AH,1 | ;функция проверки нажатия клавиши |
INT 16H | ;прерывание клавиатуры BIOS |
JZ KEEP_TRYING | ;возврат, если не было нажатия |
MOV AH,0 | ;функция получения кода с клавиатуры |
INT 16H | ;теперь нужный символ в AL |
SUB DX,5 | ;адрес регистра хранения передатчика |
OUT DX,AL | ;посылаем символ |
JMP SHORT KEEP_TRYING | ;возвращаемся к началу цикла |
<~-7.1.5 Инициализация и управление модемом.
Содержание
7.1.7 Получение данных.-~>