Схема ввода и вывода информации: Устройства ввода и вывода данных
Содержание
7. Организация устройств ввода/вывода информации в микропроцессорных системах.
Одной из важнейших
задач проектирования МПС является
организация взаимодействия с устройствами
ввода/вывода (УВВ) — источниками и
приемниками данных. К устройствам ввода
относятся переключатели, клавиатура,
аналого-цифровые преобразователи (АЦП),
датчики двоичной информации, а к
устройствам вывода — индикаторы,
светодиоды, дисплеи, печатающие
устройства, цифроаналоговые преобразователи
(ЦАП), транзисторные ключи, реле,
коммутаторы. Примерами устройств
одновременно и ввода и вывода являются
накопители на гибких и жестких магнитных
дисках. УВВ различаются: разрядностью
данных, быстродействием, управляющими
сигналами, типом протокола обмена, т.е.
определенным порядком обмена. Данные
в УВВ изменяются в произвольный или
определенный момент времени. Соединение
УВВ с системной шиной МПС осуществляется
с помощью интерфейса ввода/вывода,
который согласовывает сигналы УВВ с
системной шиной МПС. Как правило,
интерфейс состоит из одного или нескольких
портов ввода/вывода и схем управления
ими.
При проектировании
интерфейса ввода/вывода необходимо
обеспечить: хранение информации,
поступающей от УВВ; доступ к информации
со стороны МП; управление обменом;
преобразование форматов данных.
Хранение
информации и доступ к ней со стороны
МП. Ввод и вывод информации
выполняется с помощью портов ввода/вывода,
которые представляют собой 8- или
16-разрядные регистры со схемами выборки
и управления чтением/записью. В качестве
портов могут быть использованы буферные
регистры, например, i8282,
i8285, КР580ИР82, КР589ИР12,
КР580ВВ55. Использование регистра КР580ИР82
для соединения с устройством ввода и
устройством вывода показано на рис.
5.1, а и б соответственно.
Рис. 5.1. | Если регистр |
Ввод или вывод
данных можно осуществлять двумя
способами: использованием отдельного
адресного пространства УВВ; с использованием
общего с памятью адресного пространства,
т.е. с отображением на память.
В первом случае
ввод и вывод данных выполняются по
командам in
и out.
Во втором случае адреса портов
располагаются в общем с памятью адресном
пространстве, и обращение к портам не
отличается от обращения к ячейке памяти.
Сигналы выборки
БИС (рис. 5.1) конкретных портов формируются
с помощью дешифраторов. Адрес 16-разрядного
порта Р16 должен быть четным, чтобы
обращение к нему происходило за один
цикл шины. Адреса 8-разрядных портов
ввода/вывода P8 могут
быть любыми (четными, нечетными), но при
четном адресе 8-разрядные порты нужно
соединить с младшей половиной шины
данных D7-D0,
а при нечетном — со старшей половиной
D15-D8.
Функциональная
схема дешифратора показана на рис. 5.2.
Рис. 5.2. Функциональная | Схема содержит |
В противном случае
сигнал на том выходе DC,
двоичный код номера которого определяются
кодом на информационных входах DC
Х2, XI, Х0, является активным,
т.е. имеет L-уровень. Сигналы
на других выходах имеют Н-уровень. Этот
принцип работы DC позволяет
в любой момент работы МП обратиться
лишь к одному из портов.
Управление
обменом. Существуют три способа
управления обменом: программный обмен;
обмен по прерыванию; обмен в режиме
прямого доступа к памяти.
Программный
обмен инициируется МП и осуществляется
под его управлением. Различают простой
и стробированный программный обмен.
При простом программном обмене считается,
что УВВ в любой момент готово к обмену
по командам in
или out.
При стробированном обмене УВВ
извещает о своей готовности к обмену
стробом. Например, выдача 8-разрядных
данных сопровождается девятым битом —
стробом. При таком обмене схема интерфейса
содержит триггер или порт управления
для сохранения информации о готовности
внешнего устройства к обмену. Процессор
опрашивает соответствующий разряд
порта управления для определения
состояния внешнего устройства — его
готовности к обмену.
Функциональная
схема стробированного обмена приведена
на рис. 5.3.
Схема содержит:
устройство ввода, соединенное с портом
ввода; устройство вывода, соединенное
с портом вывода; порт управления для
хранения сигналов готовности устройств
ввода и вывода. Устройство ввода имеет
восемь информационных выходных линий
и одну выходную линию строба сопровождения
данных. Появление этого строба
сигнализирует о том, что данные на
информационных линиях являются
действительными (корректными). Устройство
вывода имеет восемь информационных
входных линий и одну выходную линию
строба подтверждения приема данных.
Появление этого строба сигнализирует
о том, что данные приняты устройством
и МП может передавать новую порцию
данных. Порт управления хранит информацию
о стробах от двух устройств.
Рис. 5.3. Схема
стробированного ввода/вывода
Если УВВ имеет
встроенное аппаратное средство для
определения готовности к обмену, о
состоянии устройства свидетельствует
флаг готовности READY или
флаг готовности/занятости READY/BUSY.
Информация о готовности устройств
принадлежит к статусной информации
и входит в состав слова состояния
устройства. Иногда состояние
готовности и занятости идентифицируется
отдельными флагами: READY
и BUSY. Флаг READY
заменяет бит порта управления (см. рис.
5.3).
На чтение статусной
информации и ее анализ, МП тратит
несколько циклов работы, что приводит
к непроизводительным потерям его
времени. Недостатками программного
стробированного обмена является то,
что данный способ обмена информацией
не разрешает внешним устройствам
инициировать обмен. Преимущество
программного обмена состоит в простоте
реализации, а также в том, что нет
необходимости в дополнительных аппаратных
средствах. Программный обмен используется
для обмена с УВВ, производительность
которых меньше производительности МП.
Обмен по прерыванию
инициируется УВВ и осуществляется
под управлением МП. В этом случае сигнал
готовности УВВ к обмену используется
как запрос прерывания и поступает в
программируемый контроллер прерываний
(ПКП) (рис. 5.5). Ввод или вывод осуществляется
в подпрограмме обработки запроса
прерывания.
Рис. 5.5. Схема | Программируемый |
Реагируя на сигнал
INT
МП прерывает выполнение основной
программы, идентифицирует устройство,
вызвавшее прерывание, и переходит к
выполнению подпрограммы обслуживания
прерывания от этого устройства, а после
его завершения восстанавливает выполнение
прерванной программы. По команде INT
содержимое программного счетчика и
флагов автоматически запоминается в
стеке. Содержимое аккумулятора и рон
необходимо занести в стек с помощью
команд push
в подпрограмме обработки прерывания.
В каждом МП
реализована особая структура системы
прерываний. Однако общая последовательность
обмена по прерыванию включает следующие
действия:
1. УВВ генерирует
сигнал готовности, вызывающий появление
сигнала прерывания INT МП.
2. МП завершает
выполнение текущей команды и, если
прерывание разрешено (не замаскировано),
формирует сигнал INTA
подтверждения прерывания.
3. МП запоминает
содержимое аккумулятора, программного
счетчика и РОН в стеке.
4. МП идентифицирует
устройство, вызвавшее прерывания, и
выполняет соответствующую подпрограмму
обслуживания прерывания.
5. С помощью команды
pop
восстанавливаются значения
содержимого аккумулятора и РОН из стека.
6. По команде ret
возврата из прерывания, которая
является последней командой подпрограммы
обслуживания прерывания, восстанавливаются
значения программного счетчика и флагов,
и продолжается выполнение прерванной
программы.
Обмен по прерыванию
более производительный, чем программный
обмен, поскольку не требует времени для
опроса готовности УВВ к обмену.
Обмен в режиме
ПДП инициируется УВВ и осуществляется
под управлением контроллера прямого
доступа к памяти (КПДП) без участия МП.
При обмене данными между УВВ и памятью
нет необходимости в пересылке данных
через МП. Данные с помощью КПДП пересылаются
непосредственно из УВВ в память или
наоборот. Прямой доступ к памяти при
выполнении операций ввода/вывода
позволяет значительно увеличить скорость
передачи данных и повысить эффективность
использования средств МП. Схема обмена
в режиме ПДП показана на рис. 5.6. Контроллер
прямого доступа принимает запрос от
УВВ, формирует сигнал запроса захвата
шин МП HOLD и, получив от МП
разрешение HLDA, формирует
адреса памяти и управляющие сигналы
MEMR, IOW — в
случае чтения памяти, или MEMW
, IOR —в случае записи в
память.
Информацию об
области памяти, используемой при обмене
в виде начального адреса и длины массива,
загружают в КПДП при его программировании.
Производительность обмена в режиме ПДП
наиболее высокая из рассмотренных
способов обмена.
Рис. 5.6. Схема
обмена в режиме ПДП
Преобразование
форматов данных. Если разрядность
данных, с которыми оперирует МП, меньше
разрядности данных, с которыми оперирует
УВВ, то для согласования разрядности
увеличивают число портов ввода/вывода.
Если разрядность данных, с которыми
оперирует МП, больше разрядности данных,
с которыми оперирует УВВ, то для
согласования разрядности выполняют
упаковку данных, полученных из нескольких
источников, в одно слово нужной разрядности
или используют дополнение нулями. Для
преобразования последовательного кода
в параллельный и наоборот используют
контроллер последовательного обмена.
Разработка принципиальной схемы устройства ввода-вывода информации на основе микропроцессора. Блок-схема проектируемого агрегата
ВВЕДЕНИЕ
Целью данной курсовой
работы является разработка принципиальной схемы устройства ввода-вывода
информации на основе микропроцессора. Данное устройство должно выполнять
следующие функции:
— ввод аналогового
сигнала:
— преобразование
сигнала в цифровую форму;
— обработку
информации по программе пользователя;
— обратное
преобразование цифрового сигнала в аналоговый;
— вывод полученного
аналогового сигнала.
Блок-схема проектируемого агрегата
приведена на рисунке 1, где:
Рис.1-блок-схема микропроцессорного агрегата.
Г — генератор
тактовых импульсов микропроцессора;
БМП — непосредственно
блок микропроцессора;
ОЗУ — оперативное
запоминающее устройство, хранящее программу обработки сигнала совместно с ПЗУ;
ПЗУ — постоянное
запоминающее устройство;
Порт ввода -
аналоговый порт ввода, производящий непосредственно ввод и оцифровку сигнала;
Порт вывода -
цифроаналоговый преобразователь, осуществляющий преобразование в аналоговую
форму и вывод обработанной информации.
Программные
возможности проектируемого агрегата ограничены объемом памяти и функциональными
устройствами. В качестве примера использования подобного устройства можно
привести применение его для регистрации и оценки электрических параметров на
входе, хранении их значений в памяти и выдачи отчетного сигнала на выходе.
Техническая
характеристика микропроцессора
Интегральная
микросхема КР580ИК80А представляет собой однокристальное 8’разрядное
параллельное центральное процессорное устройство (микропроцессор) с
фиксированной системой команд. По уровням входных и выходных сигналов
микросхема совместима с ТТЛ-схемами.
Микросхема
применяется в качестве центрального элемента обработки информации в микроЭВМ.
Микросхема (СР11)
состоит из 16’разрядного трехстабильного канала данных, 4 входных и 6 выходных
шин управления.
Канал адреса
обеспечивает адресацию внешней памяти объемом 64 КЬ, а также адресацию 256
устройств ввода и 256 устройств вывода.
К особенностям
микропроцессора следует отнести:
1 наличие в структуре
регистров общего назначения, которые могут использоваться как три 16’разрядных
или шесть 8’иразрядных регистров;
2 наличие
16’разрядного регистра указателя стека, который позволяет размещать память
магазинного типа в любой зоне ОЗУ (КАМ) и обеспечивать вложение неограниченного
числа подпрограмм,
3 наличие
одновременной 8’уровневой схемы прерывания с возможностью размаскирования,
которая позволяет программного
маскирования и использовать микропроцессор в системах, работающих в реальном
времени;
4 возможность работы
в режиме прямого доступа к памяти;
5 возможность работы
с памятью и устройствами ввода-вывода любого быстродействия.
Схема выполнена по
n’канальной технологии. В сочетании со схематическими и структурными
особенностями это позволило довести время выполнения команд типа RR до 16 мкс,
команд типа RS — до 28 мкс (при тактовой частоте 2.5 МГц).
1.2 Функциональная
схема и описание работы рис.-2 Условное
графическое изоброжение ИМС КР580ИК80К
Принцип выполнения
команды в микропроцессоре состоит из двух частей: подготовительной и
исполнительной. В подготовительной части осуществляется прием команды (одного,
двух или трех байтов) из ЗУ и размещение на регистрах СРU В исполнительной
части осуществляется дешифрация кода команды и выполняются действия,
определенные кодом команды.
Условное графическое
обозначение и назначение входных и выходных цепей микропроцессора
Условное графическое
обозначение ИМС КР580ИК80А приведено на рис. 2. На этом же рисунке приведены
параметры входных и выходных сигналов; выводы для подключения источников
питания. порядок включения и выключения напряжений питания и входных cигналов.
Назначения всех
выводов микропроцессора приведено в таблице
1.1. Таблица 1.1 -
Обозначение и назначение выводов ИМС КР580ИК80А
Ввод и вывод
Ввод и вывод
Четыре двухрукавные спирали, искривленные в гиперболическом пространстве.
Все операции ввода и вывода выполняются через портов .
Порт — это указатель на (возможно, бесконечный) поток символов.
(обычно файл), отверстие, через которое программы могут рисовать символы
или объекты из потока или поместите символы или объекты в поток.
Порты — это объекты первого класса, как и любой другой объект в Scheme.
Подобно процедурам, порты не имеют печатного представления, как строки.
и номера, поэтому они показаны здесь с обозначением #
Изначально в системе есть два порта: текущий входной порт и
текущий выходной порт.
На интерактивном сеансе
эти порты обычно указывают на входные и выходные потоки терминала.
Предусмотрено несколько способов открытия новых портов.
Входной порт часто указывает на конечный поток, например, входной
файл, хранящийся на диске.
Если одна из операций ввода (чтение, чтение-символ,
или peek-char) запрашивается
чтение из порта, достигшего конца конечного потока, возвращает
специальный eof (конец файла) объект .
Предикат eof-объекта? может быть
используется, чтобы определить, вернулся ли объект из чтения,
read-char или peek-char — это объект eof.
Раздел 7.1. Операции ввода
процедура : (вход-порт? obj )
возвращает: #t, если obj является входным портом, #f иначе
(входной порт? ‘(a b c))) #f
(входной-порт? (текущий-входной-порт)) #t
(входной-порт? (открытый-входной-файл «infile.ss»)) #t
В последнем примере предполагается, что файл с именем «infile.ss» может быть
открыт для ввода.
процедура : (ток-вход-порт)
возвращает: текущий входной порт
Большинство процедур, использующих входные порты, могут быть вызваны с или без
явный аргумент порта.
При вызове без явного аргумента порта текущий входной порт
использовал.
Например, (read-char) и (read-char (current-input-port))
оба возвращают следующий символ из текущего порта ввода.
процедура : (открытый входной файл имя файла )
возвращает: новый входной порт
имя файла должно быть строкой.
open-input-file создает новый входной порт для файла с именем
имя файла .
Сообщение об ошибке, если файл не существует или не может быть открыт для
вход.
См. пример для close-input-port.
процедура : (закрыть порт ввода порт ввода )
возвращает: не указано
close-input-port закрывает входной порт.
После того, как входной порт был закрыт, никакие другие операции ввода не могут быть выполнены.
выполняется на этом порту.
Поскольку операционная система может устанавливать ограничения на количество открытых портов
одновременно или ограничить доступ к открытому порту, рекомендуется
закройте любой порт, который больше не будет использоваться для ввода или вывода.
Некоторые реализации Scheme автоматически закрывают порты после того, как они становятся
недоступен для программы или при выходе из программы Scheme, но это
лучше всего закрывать порты явно, когда это возможно.
Закрытие уже закрытого порта не является ошибкой; делает
так что не влияет.
Ниже показано использование open-input-file и
close-input-port в выражении, которое собирает список
объекты из файла с именем «myfile.ss».
Функционально он эквивалентен примеру, приведенному для
call-with-input-file ниже.
(let ((p (open-input-file «myfile.ss»)))
(let f ((x (read p)))
(if (eof-object? x)
(begin
(close-input -порт р)
‘())
(cons x (f (читать p))))))
процедура : (вызов с входным файлом имя файла процедура )
возвращает: результат вызова proc
имя файла должно быть строкой. proc должна быть процедурой
один аргумент.
call-with-input-file создает новый входной порт для файла с именем
by filename и передает этот порт proc .
Сообщение об ошибке, если файл не существует или не может быть открыт для
вход.
Если proc возвращает, call-with-input-file закрывает входной порт
и возвращает значение, возвращенное proc .
call-with-input-file не закрывает вход автоматически
порт, если вызывается продолжение, созданное вне proc , поскольку оно
возможно, что другое продолжение, созданное внутри proc , будет
вызывается позже, возвращая управление proc .
Если proc не возвращается, реализация может закрыть процесс.
входной порт, только если он может доказать, что входной порт больше недоступен.
Как показано в Разделе 5.5, динамический ветер можно использовать для
убедитесь, что порт закрыт, если продолжение создано за пределами
вызывается процедура .
В следующем примере показано использование call-with-input-file
в выражении, которое собирает
список объектов из файла с именем «myfile. ss».
Функционально он эквивалентен примеру, приведенному для
закрыть входной порт выше.
(вызов с входным файлом «myfile.ss»
(лямбда (p)
(let f ((x (read p)))
(if (eof-object? x)
‘() 9000 2 (cons x (f (читать p)))))))
call-with-input-file может быть определен следующим образом.
(define call-with-input-file
(лямбда (filename proc)
(let ((p (open-input-file filename)))
(let ((v (proc p)))
(close-input-port р)
в))))
процедура : (с вводом из файла имя файла преобразователь )
возвращает: значение, возвращенное преобразователем
имя файла должно быть строкой.
with-input-from-file временно изменяет текущий входной порт на
результат открытия файла с именем имя файла для ввода во время
применение преобразователь .
Если преобразователь возвращается, порт закрывается и текущий входной порт
восстанавливается до прежнего значения.
Поведение with-input-from-file не указано
если продолжение создано снаружи
из преобразователь вызывается до возврата преобразователя .
Реализация может закрыть порт и восстановить текущий ввод
портировать к своему старому значению — но это не так.
with-input-from-file появляется в Revised 5 Отчет но
не стандарт ANSI/IEEE.
процедура : (чтение)
процедура : (чтение вход-порт )
возвращает: следующий объект из порт ввода
Если input-port не указан, по умолчанию используется текущий входной порт.
Если входной порт находится в конце файла, возвращается объект eof.
См. примеры для close-input-port и
вызов-с-входным-файлом.
процедура : (чтение символов)
процедура : (чтение символов ввод-порт )
возвращает: следующий символ из порт ввода
Если input-port не указан, по умолчанию используется текущий входной порт.
Если входной порт находится в конце файла, возвращается объект eof.
См. примеры для peek-char и write-char.
процедура : (просмотр-символ)
процедура : (просмотр-символ вход-порт )
возвращает: следующий символ из порт ввода
Если input-port не указан, по умолчанию используется текущий входной порт.
Если входной порт находится в конце файла, возвращается объект eof.
В отличие от read-char, peek-char не потребляет
символ, который он читает с input-port ; последующий вызов
peek-char или read-char возвращают один и тот же символ.
peek-char предоставляется для приложений, требующих одного символа
смотреть вперед.
Слово чтения процедуры, определенное ниже
возвращает следующее слово из входного порта в виде строки, где
слово определяется как последовательность букв алфавита.
Так как read-word не знает, пока не увидит один символ
помимо слова, что он прочитал все слово, он использует
peek-char для определения следующего символа и
read-char для использования символа.
(define read-word
(лямбда (p)
(list->string
(let f ()
(let ((c (peek-char p)))
(cond
((eof-object? c) ‘())
((char-alphabetic? c)
(read-char p)
(cons c (f))) 90 002 (иначе ‘())))))))
процедура : (eof-object? obj )
возвращает: #t, если obj является объектом eof, #f в противном случае
Объект конца файла возвращается read, read-char,
или peek-char, когда входной порт достиг конца ввода.
Хотя объекты конца файла не обязательно должны отличаться от других объектов
типы, они уникальны в том смысле, что их нельзя спутать с
объекты, которые могут быть возвращены read, read-char или
peek-char, когда входной порт не достиг конца ввода.
Например, если (eof-object? x) равно #t,
(eq? x #\a) должно быть ложным, но (char? x) может быть истинным
или ложный.
процедура : (char-ready?)
процедура : (char-ready? input-port )
возвращает: #t, если символ доступен на порту ввода , #f в противном случае
Если input-port не указан, по умолчанию используется текущий входной порт.
готов? позволяет программе искать введенные символы на
интерактивный порт без зависаний.
Если чар готовы? возвращает #t, следующий символ просмотра или
чтение-символ
работа на входном порту не будет задержан.
Если входной порт находится в конце файла, char-ready? возвращает #т.
готов? фигурирует в пересмотренном отчете 5 , но
не в стандарте ANSI/IEEE.
Раздел 7.2. Операции вывода
процедура : (выходной порт? obj )
возвращает: #t, если obj является выходным портом, #f в противном случае
Порты не должны отличаться от других типов объектов.
(выходной порт? ‘(a b c))) #f
(выходной-порт? (текущий-выходной-порт)) #t
(выходной-порт? (открытый-выходной-файл «outfile.ss»)) #t
В последнем примере предполагается, что файл с именем «outfile.ss» может быть открыт для вывода.
процедура : (ток-выход-порт)
возвращает: текущий выходной порт
Большинство процедур, включающих выходные порты, могут быть вызваны с или без
явный аргумент порта.
При вызове без явного аргумента порта текущий выходной порт
использовал.
Например, (напишите объект ) и
(напишите obj (текущий-выходной-порт))
оба пишут в текущий выходной порт.
процедура : (открытый-выходной-файл имя файла )
возвращает: новый выходной порт
имя файла должно быть строкой.
open-output-file создает новый выходной порт для файла с именем
имя файла .
Ошибка сообщается, если файл не может быть открыт для вывода.
См. пример, приведенный для close-output-port.
процедура : (закрыть выходной порт выходной порт )
возвращает: не указано
close-output-port закрывает выходной порт.
После того, как выходной порт был закрыт, дальнейшие операции вывода не могут быть выполнены.
выполняется на этом порту.
Поскольку операционная система может устанавливать ограничения на количество открытых портов
одновременно или ограничить доступ к открытому порту, рекомендуется
закройте любой порт, который больше не будет использоваться для ввода или вывода.
Кроме того, поскольку система может буферизовать выходные данные для повышения эффективности, некоторые из
вывод может не появиться в файле, пока файл не будет закрыт.
Некоторые реализации Scheme автоматически закрывают порты после того, как они становятся
недоступен для программы или при выходе из программы Scheme, но это
лучше всего закрывать порты явно, когда это возможно.
Закрытие уже закрытого порта не является ошибкой; делает
так что не влияет.
Ниже показано использование open-output-file и
close-output-port для записи списка объектов (значение
список для печати), разделенных символами новой строки, в файл
названный «myfile.ss».
Функционально он эквивалентен примеру, приведенному для
call-with-output-file ниже.
(let ((p (open-output-file «myfile.ss»)))
(let f ((ls list-to-be-print))
(if (not (null? ls))
(begin
(write (car ls) p)
(newline p)
(f (cdr ls)))))
(close-output-port p))
процедура : (вызов с выходным файлом имя файла процедура )
возвращает: результат вызова proc
имя файла должно быть строкой. proc должна быть процедурой
один аргумент.
call-with-output-file создает новый выходной порт для файла с именем
к имя файла и передает этот порт proc .
Ошибка сообщается, если файл не может быть открыт для вывода.
Если proc возвращается, call-with-output-file закрывает выходной порт
и возвращает значение, возвращенное proc .
call-with-output-file не закрывает вывод автоматически
порт, если вызывается продолжение, созданное вне proc , поскольку оно
возможно, что другое продолжение, созданное внутри proc , будет
вызывается позже, возвращая управление процедура .
Если proc не возвращается, реализация может закрыть процесс.
выходной порт, только если он может доказать, что выходной порт больше недоступен.
Как показано в Разделе 5.5, динамический ветер можно использовать для
убедитесь, что порт закрыт, если продолжение создано за пределами
вызывается процедура .
Ниже показано использование call-with-output-file для
написать список объектов (значение list-to-be-print),
разделенные символами новой строки, в файл с именем «myfile. ss».
Функционально он эквивалентен примеру, приведенному для
закрыть выходной порт выше.
(вызов-с-выходным-файлом «myfile.ss»
(лямбда (p)
(let f ((ls list-to-be-print))
(if (not (null? ls))
(begin
(запись (car ls) p)
(новая строка p)
(f (cdr ls)))))))
call-with-output-file может быть определен следующим образом.
(define call-with-output-file
(лямбда (filename proc)
(let ((p (open-output-file filename)))
(let ((v (proc p)))
(close-output-port р)
в))))
процедура : (без вывода в файл имя файла преобразователь )
возвращает: значение, возвращенное преобразователем
имя файла должно быть строкой.
with-output-to-file временно перепривязывает текущий выходной порт к
результат открытия файла с именем имя_файла для вывода во время
применение преобразователь .
Если преобразователь возвращается, порт закрывается и текущий выходной порт
восстанавливается до прежнего значения.
Поведение with-output-to-file не определено, если
продолжение, созданное за пределами , преобразователь вызывается перед
преобразователь возвращает.
Реализация может закрыть порт и восстановить текущий вывод
портировать к своему старому значению — но это не так.
with-output-to-file появляется в пересмотренном отчете 5 , но
не стандарт ANSI/IEEE.
процедура : (напишите obj )
процедура : (напишите obj порт вывода )
возвращает: не указано
Если порт вывода не указан, по умолчанию используется текущий порт вывода.
запись печатает obj на порт вывода в такой
таким образом, чтобы он мог быть позже прочитан процедурой read, если только он не
содержит непечатаемые объекты, такие как процедуры, порты или символы
содержащие нестандартные символы.
Строки печатаются в кавычках, где необходимо используется косая черта.
и символы печатаются с обозначением #\.
См. раздел 9..5 для реализации записи и
отображать.
процедура : (отобразить объект )
процедура : (отображение obj порт вывода )
возвращает: не указано
Если порт вывода не указан, по умолчанию используется текущий порт вывода.
display похож на write, но печатает строки
и символы, найденные в пределах obj напрямую.
Строки печатаются без кавычек и косых черт, а символы
печатаются без обозначения #\.
Например, оба (отобразить «(a b c)»)
и (display ‘(«a b» c)) напечатает
(а б в).
Из-за этого display не следует использовать для печати объектов, которые
предназначены для чтения с помощью read.
дисплей полезен в первую очередь для печати сообщений, с объект
чаще всего это строка.
См. раздел 9.5 для реализации записи и
отображать.
процедура : (запись-символ символ )
процедура : (write-char char output-port )
возвращает: не указано
Если порт вывода не указан, по умолчанию используется текущий порт вывода.
write-char записывает один символ char в
output-port , без обозначения #\.
В следующем примере содержимое одного файла копируется в другой.
по одному персонажу за раз.
(вызов с входным файлом «infile»
(лямбда (ip)
(вызов с выходным файлом «outfile»
(лямбда (op)
(do ((c (read-char ip) (read -char ip)))
((eof-object? c))
(write-char c op))))))
процедура : (новая строка)
процедура : (новая строка выходной порт )
возвращает: не указано
Если порт вывода не указан, по умолчанию используется текущий порт вывода.
новая строка отправляет символ новой строки на выходной порт .
Его можно определить следующим образом.
(определить новую строку
(лямбда args
(применить write-char #\newline args)))
Раздел 7.3. Загрузка программ
процедура : (загрузить имя файла )
возвращает: не указано
имя файла должно быть строкой.
load читает и оценивает последовательно каждое выражение в файле
указано имя файла .
нагрузка появляется в Пересмотренном 5 Отчет, но не в стандарте ANSI/IEEE.
Раздел 7.4. Файлы расшифровки
Файл стенограммы представляет собой запись интерактивного сеанса.
Это также полезно как «быстрая и грязная» альтернатива открытию
выходной файл и использование явных операций вывода.
расшифровка и расшифровка приведены в Пересмотренном 5
Отчет, но не в стандарте ANSI/IEEE.
процедура : (расшифровка имя файла )
возвращает: не указано
имя файла должно быть строкой.
Transcription-on открывает файл с именем имя файла для вывода,
и он копирует в этот файл весь ввод с текущего порта ввода и
весь вывод на текущий выходной порт.
Ошибка сообщается, если файл не может быть открыт для вывода.
процедура : (отключение расшифровки)
возвращает: не указано
Transcription-off Завершает транскрипцию и закрывает файл стенограммы.
R. Kent Dybvig / The Scheme Programming Language, Third Edition
Copyright © 2003 The MIT Press. Воспроизведено в электронном виде с разрешения.
Иллюстрации © 2003 Jean-Pierre Hébert
ISBN 0-262-54148-3 / LOC QA76.73.S34D93
заказать эту книгу / об этой книге
http://www.scheme.com
9. ИО
9. ИО
ДОМ | 8. Функции высшего порядка | Еще одно руководство по схеме | 10. Задание | Опубликовать сообщения |
1. Введение
Вы должны быть в состоянии писать и выполнять программы, используя интерактивный интерфейс Scheme, используя знания
предоставленные предыдущими главами.
В этой главе я расскажу о вводе и выводе.
Используя эту функцию, вы можете читать и записывать данные из/в файлы.
2. Ввод из файлов
2.1. открыть входной файл, прочитать символ,
и eof-объект?
Функция (open-input-file filename ) доступен для
открыть файл. Эта функция возвращает порт для ввода.
Функция (read-char порт ) предназначена для чтения символа из порта .
Поскольку эта функция возвращает объект eof, когда он достигает конца файла (EOF), вы можете проверить это,
используя eof-объект?. Функция (закрыть входной порт порт )
это закрыть входной порт. [код 1] показывает функцию, которая возвращает содержимое файла в виде строки.
[код 1]
(определить (имя-файла-чтения-файла) (пусть ((p (открыть-входной-файл имя-файла))) (let loop((ls1 '()) (c (read-char p))) (если (eof-объект? c) (начинать (закрыть входной порт p) (список->строка (обратный ls1))) (цикл (cons c ls1) (read-char p)))))
Например, результат, показанный в [примере 1], получается путем применения [кода 1] к файлу [hello.txt].
Поскольку символ новой строки представлен символом ‘\n’, его нелегко читать.
Однако функция отображения доступна для форматирования ([пример 2]).
[привет.txt]
Привет, мир! Scheme — это элегантный язык программирования.
[пример 1]
(кд "C:\\doc") (чтение файла "hello.txt") ;Значение 14: "Привет, мир!\nScheme — элегантный язык программирования.\n"
[пример 2]
(отображение (чтение файла "hello.txt")) Привет, мир! Scheme — это элегантный язык программирования. ;Не указано возвращаемое значение
2.2. Синтаксисы call-with-input-file и with-input-from-file
Вы можете открыть файл для ввода, используя синтаксис call-with-input-file или
с вводом из файла.
Эти синтаксисы удобны, потому что они обрабатывают ошибки.
- (вызов с входным файлом имя файла процедура )
- Он открывает файл с именем имя_файла для ввода.
Процедура — это функция, которая принимает входной порт в качестве аргумента.
Файл должен быть закрыт явно, потому что он не закрывается, когда управление возвращается из процедуры
если входной порт потенциально используется снова.
[Код 1] можно переписать как [код 2], используя вызов с входным файлом.[код 2]
(определить (имя-файла-чтения-файла) (вызов-с-входным-файлом-имя-файла (лямбда (р) (let loop((ls1 '()) (c (read-char p))) (если (eof-объект? c) (начинать (закрыть входной порт p) (список->строка (обратный ls1))) (loop (cons c ls1) (read-char p)))))))
- (с вводом из файла имя файла процедура )
- Он открывает файл с именем имя_файла в качестве стандартного ввода.
Процедура — это функция без аргументов.
Файл закрывается, когда управление возвращается из процедуры .
[код 3] показывает переписанную функцию [кода 1] с использованием ввода из файла.[код 3]
(определить (имя-файла-чтения-файла) (с-вводом-из-файла-имя-файла (лямбда () (let loop((ls1 '()) (c (read-char))) (если (eof-объект? c) (список->строка (обратный ls1)) (loop(cons c ls1)(read-char)))))))
2.3. читать
Функция (чтение порт ) считывает S-выражение
с порта .
Содержимое удобно читать со скобками типа [paren.txt].
[paren.txt]
'(Привет, мир! Scheme — элегантный язык программирования.) '(Lisp — это язык программирования, готовый к развитию.)
[код 4]
(определить (s-read имя-файла) (с-вводом-из-файла-имя-файла (лямбда () (let loop ((ls1 '()) (s (прочитать))) (если (eof-объект? s) (обратный ls1) (цикл (минус лс1) (читать)))))))
Ниже показан результат чтения файла paren.txt с помощью s-read.
(s-читать "paren.txt") ⇒ ((quote (привет, мир! схема — элегантный язык программирования.)) (quote (lisp — язык программирования, готовый развиваться.)))
Упражнение 1
Напишите строки чтения функции
который возвращает список строк, соответствующих каждой строке содержимого файла.
Символ новой строки представлен #\Linefeed в схеме.
Ниже приведен результат применения этой функции к файлу hello.txt.
(чтение строк «hello.txt») ⇒ («Привет, мир!» «Scheme — элегантный язык программирования». )
3. Вывод в файлы
3.1. Создание порта для вывода
Аналогичные функции для ввода доступны для создания выходных портов.
- (открытый выходной файл имя файла )
- Открывает файл для вывода и возвращает порт вывода.
- (закрыть выходной порт порт )
- Закрывает порт для вывода. 907:20
- (вызов с выходным файлом имя файла процедура )
- Он открывает файл с именем имя_файла для вывода и вызывает процедуру .
Функция процедура принимает порт в качестве аргумента. - (без вывода в файл имя файла процедура )
- Он открывает файл с именем имя файла в качестве стандартного вывода и вызывает процедуру .
Процедура — это функция без аргументов.
Файл закрывается, когда управление возвращается из процедуры .
3.1. Функции для выхода
Доступны следующие функции вывода.
Эти функции выводят на стандартный вывод, если порт опущен.
- (запись obj порт )
- Выводит obj на порт . Строки заключаются в двойные кавычки и
символы сочетаются с #\. 907:20 - (дисплей объект порт )
- Выводит obj на порт .
Строки , а не , заключенные в двойные кавычки и
символы , а не в сочетании с #\. - (новая строка порт )
- Начинается новая строка.
- (запись символов символов порт )
- Выводит символов на порт . 907:20
Упражнение 2
Напишите функцию для копирования файлов (my-copy-file).
Упражнение 3
Напишите функцию (линии печати)
который принимает произвольное количество строк в качестве аргументов и выводит их на стандартный вывод.
Выходные строки должны быть разделены новой строкой.
4.Сводка
Эта глава короткая, потому что Scheme имеет минимальные средства ввода-вывода.
Я объясню о назначении на схеме в следующей главе.
Ответы на упражнения
Ответ 1
Сначала напишите функцию group-list, которая разделяет список разделителем.
Затем разделите список символов, считанных из входного файла, на #\Linefeed и
преобразовать их в строки. (видеть ; *)
(определить (групповой список ls sep) (letrec ((iter (лямбда (ls0 ls1) (состояние ((нуль? ls0) (список ls1)) ((eqv? (car ls0) sep) (cons ls1 (iter (cdr ls0) '()))) (else (iter (cdr ls0) (cons (car ls0) ls1))))))) (обратная карта (iter ls '())))) (определить (чтение-строки имя-файла) (с-вводом-из-файла-имя-файла (лямбда () (let loop((ls1 '()) (c (read-char))) (если (eof-объект? c) (map list->string (group-list (reverse ls1) #\Linefeed)) ; * (loop(cons c ls1)(read-char)))))))
пример:
(групповой список '(1 4 0 3 7 2 0 9 5 0 0 1 2 3) 0)
;Значение 13: ((1 4) (3 7 2) (9 5) () (1 2 3))
(читаем строки "hello.