2050
.pdfуправление программными и аппаратными средствами с территориально распределенных станций и т.п.
Способы обмена данными разнообразны как по устройствам, использующимся для обмена, так и по протоколам обмена данными. Используемые протоколы обмена обычно связаны с передающими и принимающими устройствами. Так, например, протоколы TCP/IP и IPX/SPX используются в информационных сетях. Для передачи файлов в глобальных сетях используют протокол FTP (File Transfer Protocol), позволяющий переписать файлы с дисков удаленного сервера на локальный диск компьютера. А протоколы Xmodem, Ymodem, Zmodem для соединения компьютеров по последовательному порту с использованием модемов. Передача может вестись посредством последовательных и параллельных портов, через сетевые платы и модемы.
В ПЭВМ устройствам обмена присвоены некоторые стандартизированные имена (COMx – последовательный порт, LPTx – параллельный порт принтера), которые используются для программного обращения к данным устройствам.
Одним из наиболее простых способов обмена данными является обмен по последовательному порту. Последовательная передача данных предполагает, что данные передаются с использованием единственной линии. При этом биты байта передаются по очереди, с использованием одного провода.
Самый распространенный последовательный интерфейс IBM-совместимых ПЭВМ - это RS-232С.
Одним из важнейших вопросов компьютерной техники, является возможность обмена данными между ЭВМ. Основными задачами обмена данными являются:
быстрое перемещение данных на большие расстояния;
многократное дублирование данных на разные носители;
создание баз данных клиент-сервер;
81
управление программными и аппаратными средствами с территориально-рассредоточенных станций и т.п.
Способы обмена данными разнообразны как по устройствам, использующимся для обмена, так и по правилам ведения приема и передачи данных. Одним из наиболее простых способов обмена данными является обмен по последовательному порту. Самый распространенный порт IBM-совместимых ПЭВМ - это RS-232. В данном разделе будет рассмотрен способ передачи, минующий дополнительные устройства (модемы).
5.2. Функции Win32 API для обмена данными по RS-232
Функции получения информации при обмене данными всегда применяются в приложениях, где необходимо осуществить настройку параметров до начала приема или передачи.
Основные информационные функции обмена по последовательному порту RS-232:
GetCommTimeouts;
GetCommProperties;
GetCommState.
GetCommTimeouts позволяет получить временные параметры ограничивающие прием и передачу устройства, на которое указывает идентификатор, получаемый функцией
CreateFile.
Синтаксис: BOOL GetCommTimeouts(hFile,lpCommTimeouts)
HANDLE hFile; // идентификатор устройства обмена LPCOMMTIMEOUTS lpCommTimeouts; // указатель на структуру
COMMTIMEOUTS
Описание структуры COMMTIMEOUTS приведено в приложении.
82
GetCommProperties позволяет получить свойства коммуникационного устройства, идентификатор которого получен функцией CreateFile.
Синтаксис: BOOL GetCommProperties(hFile,lpCommProp)
HANDLE hFile; // идентификатор устройства обмена LPCOMMPROP lpCommProp; // указатель на структуру
COMMPROP
GetCommState позволяет получить свойства текущего сеанса приема/передачи данных для устройства, идентификатор которого получен функцией CreateFile.
Синтаксис: BOOL GetCommState(hFile,lpDCB)
HANDLE hFile; // идентификатор устройства обмена LPDCB lpDCB; // указатель на структуру DCB
Описание структуры DCB приведено в приложении.
Малый набор функций возвращает десятки видов информации, как о текущем сеансе, так и об устройстве передачи. Данные функции позволяют получить следующую информацию:
временные характеристики обмена:
o время, в течение которого должен быть получен следующий символ при приеме;
oвремя, в миллисекундах, на каждый принимаемый символ;
o время, в миллисекундах, прибавляемое к общему времени приема;
oвремя, в миллисекундах, на каждый передаваемый символ;
oвремя, в миллисекундах, прибавляемое к общему времени передачи;
свойства устройства обмена:
83
o тип устройства; o версия пакета;
o максимальный размер внутреннего буфера для передачи в байтах;
o размер внутреннего буфера для передачи в байтах; o максимальный размер внутреннего буфера для
приема в байтах;
o размер внутреннего буфера для приема в байтах;
o максимальная скорость передачи в битах на секунду (bps);
oподдерживаемые режимы и возможности;
oустанавливаемые параметры;
oустанавливаемые скорости передачи;
oподдерживаемые количества информационных бит;
oподдерживаемые количества стоповых бит;
oподдерживаемые паритеты;
параметры текущего сеанса связи:
oтекущая скорость передачи в bps;
o количество информационных бит; o количество стоповых битов;
o значение символа XON для приема и передачи; o значение символа XOFF для приема и передачи; o значение символа "конец вводимых данных";
o значение символа "событие" и т.д.
Получение временных характеристик обмена
Компоненты Edit1-Edit5 выводят временные характеристики обмена, описанные в структуре
COMMTIMEOUTS. TEdit *Edit1;
TEdit *Edit2;
TEdit *Edit3;
TEdit *Edit4;
TEdit *Edit5; void main()
{
HANDLE hFile;
84
COMMTIMEOUTS lpCommTimeouts; char str[25];
hFile=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NU LL,OPEN_EXISTING,NULL,NULL);
if (hFile!=INVALID_HANDLE_VALUE)
{
GetCommTimeouts(hFile,&lpCommTimeouts); Edit1->Text=ultoa(lpCommTimeouts.ReadIntervalTimeout,str,10); Edit2-
>Text=ultoa(lpCommTimeouts.ReadTotalTimeoutMultiplier,str,10); Edit3-
>Text=ultoa(lpCommTimeouts.ReadTotalTimeoutConstant,str,10); Edit4-
>Text=ultoa(lpCommTimeouts.WriteTotalTimeoutMultiplier,str,10); Edit5-
>Text=ultoa(lpCommTimeouts.WriteTotalTimeoutConstant,str,10);
}
CloseHandle(hFile);
}
Получение типа устройства
Компонента Edit1 выводит тип устройства.
TEdit *Edit1; void main()
{
HANDLE hFile; COMMPROP lpCommProp;
hFile=CreateFile("COM2:",GENERIC_READ|GENERIC_WRITE,0,N ULL,OPEN_EXISTING,NULL,NULL);
if (hFile!=INVALID_HANDLE_VALUE)
{
GetCommProperties(hFile,&lpCommProp); switch (lpCommProp.dwProvSubType)
{
case PST_FAX: - - Edit1->Text="FAX";break;
case PST_LAT: - - Edit1->Text="протокол LAT";break; case PST_MODEM: - Edit1->Text="модем";break; case PST_NETWORK_BRIDGE: Edit1->Text="сетевой
мост";break;
85
case PST_PARALLELPORT: Edit1->Text="параллельный порт";break;
case PST_RS232: - Edit1->Text="RS-232";break; case PST_RS422: - Edit1->Text="RS-422";break; case PST_RS423: - Edit1->Text="RS-423";break; case PST_RS449: - Edit1->Text="RS-449";break;
case PST_TCPIP_TELNET: Edit1->Text="протокол TCP/IP
Telnet®";break;
case PST_UNSPECIFIED: Edit1->Text="не задан";break; case PST_X25: - - Edit1->Text="стандарт X.25";break;
}
}
CloseHandle(hFile);
}
Получение текущей скорости обмена данными
Компонента Edit1 выводит текущую скорость обмена данными на передающей или принимающей станции.
TEdit *Edit1; void main()
{
HANDLE hFile; DCB lpDCB;
hFile=CreateFile("COM2:",GENERIC_READ|GENERIC_WRITE,0,N ULL,OPEN_EXISTING,NULL,NULL);
if (hFile!=INVALID_HANDLE_VALUE)
{
GetCommState(hFile,&lpDCB); switch (lpDCB.BaudRate)
{
case CBR_110: Edit1->Text="110"; break; case CBR_300: Edit1->Text="300"; break; case CBR_600: Edit1->Text="600"; break; case CBR_1200: Edit1->Text="1200"; break; case CBR_2400: Edit1->Text="2400"; break; case CBR_4800: Edit1->Text="4800"; break; case CBR_9600: Edit1->Text="9600"; break; case CBR_14400: Edit1->Text="14400"; break; case CBR_19200: Edit1->Text="19200"; break;
86
case CBR_38400: Edit1->Text="38400"; break; case CBR_56000: Edit1->Text="56000"; break; case CBR_57600: Edit1->Text="57600"; break; case CBR_115200: Edit1->Text="115200"; break; case CBR_128000: Edit1->Text="128000"; break; case CBR_256000: Edit1->Text="256000"; break;
}
}
CloseHandle(hFile);
}
Получение информации при обмене данными по последовательному порту имеет первостепенное значение. Так как, во-первых, важно знать каким способом, и с какими особенностями будет вестись передача и прием. А во-вторых, обмен будет происходить корректно лишь при полной согласованности всех параметров на передающей и принимающей сторонах.
Настройка параметров, так же как и передача и прием осуществляется с использованием управляющих функций. Основные управляющие функции Win32 API для обмена по последовательному порту:
SetCommTimeouts;
SetCommState;
WriteFile;
ReadFile.
SetCommTimeouts устанавливает временные параметры, ограничивающие прием и передачу устройства, на которое указывает идентификатор, получаемый функцией
CreateFile.
Синтаксис: BOOL SetCommTimeouts(hFile,lpCommTimeouts)
HANDLE hFile; // идентификатор устройства обмена LPCOMMTIMEOUTS lpCommTimeouts; // указатель на структуру
COMMTIMEOUTS
87
SetCommState позволяет установить свойства текущего сеанса приема/передачи данных для устройства, идентификатор которого получен функцией CreateFile.
Синтаксис: BOOL GetCommState(hFile,lpDCB)
HANDLE hFile; // идентификатор устройства обмена LPDCB lpDCB; // указатель на структуру DCB
Из названия функций можно понять, какие параметры, возвращаемые информационными функциями можно изменить. Также видно, что многоцелевые функции чтения и записи, применяемые для файловой системы имеют место и в данном случае. Необходимо помнить об обслуживающих функциях, которыми являются CreateFile (открытие устройства) и CloseHandle (закрытие устройства).
Приведенные функции позволяют осуществить:
изменение временных характеристик обмена:
o изменение времени, в течение которого должен
быть получен следующий символ при приеме;
o изменение времени, в миллисекундах, на каждый принимаемый символ;
oизменение времени, в миллисекундах, прибавляемое к общему времени приема;
oизменение времени, в миллисекундах, на каждый передаваемый символ;
oизменение времени, в миллисекундах, прибавляемое к общему времени передачи;
параметры текущего сеанса связи:
oизменение текущей скорости передачи в bps;
o изменение количества информационных битов; o изменение количества стоповых битов;
oизменение значения символа XON для приема и передачи;
oизменение значения символа XOFF для приема и передачи;
88
oизменение значения символа, замещающего байты при ошибке;
oизменение значения символа "конец вводимых данных";
o изменение значения символа "событие" и т.п;
передача данных;
прием данных.
Изменение количества информационных и стоповых битов
Компонента RadioGroup1 назначает разрешенные количества информационных и стоповых битов (5-1, 5-1.5, 6-1, 6-2, 7-1, 7-2, 8-1 и 8-2).
TRadioGroup *RadioGroup1; void main()
{
HANDLE hFile; DCB lpDCB;
hFile=CreateFile("COM2:",GENERIC_READ|GENERIC_WRITE,0,N ULL,OPEN_EXISTING,NULL,NULL);
if (hFile!=INVALID_HANDLE_VALUE)
{
GetCommState(hFile,&lpDCB); switch (RadioGroup1->ItemIndex)
{
case 0: lpDCB.ByteSize=5; lpDCB.StopBits=ONESTOPBIT; break; case 1: lpDCB.ByteSize=5; lpDCB.StopBits=ONE5STOPBITS;
break;
case 2: lpDCB.ByteSize=6; lpDCB.StopBits=ONESTOPBIT; break; case 3: lpDCB.ByteSize=6; lpDCB.StopBits=TWOSTOPBITS; break; case 4: lpDCB.ByteSize=7; lpDCB.StopBits=ONESTOPBIT; break; case 5: lpDCB.ByteSize=8; lpDCB.StopBits=TWOSTOPBITS; break; case 6: lpDCB.ByteSize=8; lpDCB.StopBits=ONESTOPBIT; break; case 7: lpDCB.ByteSize=8; lpDCB.StopBits=TWOSTOPBITS; break;
}
SetCommState(hFile,&lpDCB);
}
89
Передача данных
По COM2 передается текст из свойства Text компоненты Edit1. Отправляемая строка помещается в буфер (256 символов), который изначально заполняется нулями.
TEdit *Edit1; void main()
{
HANDLE hFile; char lpBuffer[256];
DWORD lpNumberOfBytesWrite; memset(lpBuffer,sizeof(lpBuffer),0);
hFile=CreateFile("COM2",GENERIC_WRITE,0,NULL,OPEN_EXISTI NG,NULL,NULL);
if (hFile==INVALID_HANDLE_VALUE)
{
char message[]="Ошибка открытия устройства \"COM2\" !!!\n - - ";
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMA
T_MESSAGE_FROM_SYSTEM,
NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL,SUBLANG_D EFAULT),
(LPTSTR)&lpMsgBuf,0,NULL);
strcat(message,(LPTSTR)lpMsgBuf); MessageBox(NULL,message,"Сообщение",MB_OK); LocalFree(lpMsgBuf );
}
else
{
strcpy(lpBuffer,Edit1->Text.c_str());
WriteFile(hFile,lpBuffer,sizeof(lpBuffer),&lpNumberOfBytesWrite,NUL L);
}
CloseHandle(hFile);
}
90