Курсовая работа: Создание измерительного аппаратно-программного комплекса термометра на основе микроконтроллеров семьи ATMEGA

Очень часто программисту приходится управлять с помощью компьютера каким-либо внешним устройством, или просто анализировать состояние этого устройства. Порты ввода/вывода — самый распространенный способ сопряжения компьютера и внешнего устройства. Давным-давно уже написано множество классов, библиотек и компонент для работы с портами, поэтому можно, конечно, воспользоваться уже готовым и к тому же бесплатным решением. Именно так я и поступил лет семь назад, при этом потеряв самое главное — своевременное понимание того, как все-таки работать с портами из-под Win32. Незнание внутренних механизмов — это, во-первых, пробел в стройном ряду знаний, а во-вторых, актуальная возможность ошибок в работе программы.

С портами из-под Win32 работают так же, как и с обычными файлами, используя при этом всего несколько специфичных функций WinAPI. Однако коммуникационный порт — это не совсем обычный файл. Для него, например, нельзя выполнить позиционирование файлового указателя, или же создать порт, если таковой отсутствует. Любая работа с портом начинается с его открытия. Для этого используется файловая функция WinAPI (описания WinAPI-функций взяты из MSDN (Microsoft Developer Network), следовательно, приводятся в синтаксисе C):

HANDLE CreateFile(

LPCTSTR lpFileName,

DWORD dwDesiredAccess,

DWORD dwShareMode,

LPSECURITY_ATTRIBUTES lpSecurityAttributes,

DWORD dwCreationDistribution,

DWORD dwFlagsAndAttributes,

HANDLE hTemplateFile

);

lpFileName — указатель на строку с нулевым завершающим символом. Обычно это имя открываемого файла, но в нашем случае это должно быть название порта (COM1, COM2, …).

dwDesiredAccess — тип доступа. В нашем случае должен быть равен GENERIC_READ|GENERIC_WRITE.

dwShareMode — параметр совместного доступа. Для коммуникационных портов всегда равен 0.

lpSecurityAttributes — атрибут защиты. Для коммуникационных портов всегда равен NULL.

dwCreationDistribution — режим автосоздания. Для коммуникационных портов всегда равен OPEN_EXESTING.

dwFlagsAndAttributes — атрибут режима обработки. Для коммуникационных портов должен быть равен 0 или FILE_FLAG_OVERLAPPED.

hTemplateFile — описатель файла-шаблона. Для коммуникационных портов должен быть равен NULL.

При успешном открытии порта функция возвращает его описатель, а в случае ошибки возвращает INVALID_HANDLE_VALUE.

Сразу оговорюсь: все недостающие описания можно найти на http://msdn.microsoft.comи еще по ряду адресов, которые вам подскажет поисковый сервер.

Из всех параметров функции CreateFile() особого пояснения требует dwFlagsAndAttributes. Работа с портом может быть организована в синхронном (nonoverlapped) или асинхронном (overlapped) режимах обработки, что и задается этим флагом. При синхронном режиме (когда параметр dwFlagsAndAttributes = 0) только один поток приложения может либо читать, либо писать в порт. Помните переговорное устройство в лифте? Нажали кнопку — можем только говорить, отпустили кнопку — можем только слушать.

Синхронный режим обработки прост в реализации. Если надо записать данные в порт, то вызываем функцию записи и ожидаем, пока она не завершится. Если же надо читать данные, то вызываем функцию чтения и ждем, пока она не отработает. Для простых задач синхронный режим обработки вполне подходит, однако в мире Windows он почти всегда обречен на неудачу. Ожидание операции чтения или записи воспринимается пользователем программы как «зависание».

Асинхронный режим (когда параметр dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED) позволяет производить операции чтения и записи в порт параллельно из разных потоков. В то время, пока один поток приложения принимает данные, другой поток может параллельно с первым передавать данные — как при разговоре по телефону, когда вы можете слушать и говорить одновременно. Данный режим обработки больше импонирует идее многозадачности Windows. Но за все надо платить: для реализации этого режима обработки требуется в два раза больше написанного кода, вдобавок, умения писать многопоточные программы. Какой режим выбрать — решайте сами. Но если уж разбираться в работе порта, то разбираться «по-взрослому», до конца, а потому и рассмотрим более сложный вариант — асинхронную обработку.

На практике открытие порта для асинхронного режима обработки из программы на Delphi выглядит примерно так:

OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

if hPort = INVALID_HANDLE_VALUE then

raise Exception.Create('Error opening port');

Функция возвращает описатель порта (hPort), который нам потом пригодится для вызова других функций работы с портом. Если в результате открытия порта описатель не получен, то возбуждается исключение с соответствующим текстом ошибки. Открыв порт, мы получаем его в свое распоряжение. Теперь с этим портом может работать только наша программа (точнее, только наш процесс). По окончании работы с портом его следует закрыть, вызвав функцию:

BOOL CloseHandle(

К-во Просмотров: 446
Бесплатно скачать Курсовая работа: Создание измерительного аппаратно-программного комплекса термометра на основе микроконтроллеров семьи ATMEGA