imho.ws |
![]() |
![]() |
![]() |
# 1 |
Guest
Сообщения: n/a
|
Проблема серийного порта в Windows 2000
Есть следующая проблема. Я делаю софт который связывается с девайсом по RS-232. так вот - девайсу нужно видеть старт и стоп биты для уверенного приёма, а W2k, если шлешь много 0хFF, склеивает стринги и убирает старт и стоп биты. У кого-нибудь есть идея, что делать.
|
![]() |
# 2 |
Junior Member
Регистрация: 19.04.2002
Адрес: Дом
Пол: Male
Сообщения: 187
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Что-то смутно вериться что проблема в Win2k скорее в правильности инициализации порта. Во всяком случае я что-то смутно припоминаю что при открытии порта задаются параметры его работы...
__________________
Дураки не динозавры - они не вымрут... |
![]() |
![]() |
# 3 |
Full Member
Регистрация: 31.08.2003
Адрес: где-то между Марсом и Юпитером
Сообщения: 998
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Для того чтобы дать тебе толковый совет нужно видеть как ты программируешь com-порт, что используешь.
Например в Delphi, используя winAPI: Открытие порта: hPort := CreateFile(‘COM1’, GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if hPort = INVALID_HANDLE_VALUE then raise Exception.Create('Error opening port'); Основные параметры последовательного порта описываются структурой DCB. Она содержит массу полей, каждое из которых соответствует определенному параметру настройки порта. Например: BaudRate — скорость передачи данных. Возможно указание констант —CBR_100, CBR_300, CBR_600, CBR_1200, …, CBR_256000. Parity — схема контроля четности. Может содержать одно из следующих значений: EVENPARITY, MARKPARITY, NOPARITY, ODDPARITY, SPACEPARITY. ByteSize — число информационных бит в передаваемых и принимаемых байтах. StopBits — количество стоповых бит. Может быть ONESTOPBIT, ONE5STOPBIT, TWOSTOPBIT. Настройку порта желательно производить сразу после его открытия. var Dcb: TDcb; … if not GetCommState(hPort, Dcb) then raise Exception.Create('Error setting port state'); Dcb.BaudRate := CBR_9600; Dcb.Parity := NOPARITY; Dcb.ByteSize := 8; Dcb.StopBits := ONESTOPBIT; if not SetCommState(hPort, Dcb) then raise Exception.Create('Error setting port state'); Еще одна операция, которая нам понадобится сразу после открытия порта — его сброс. BOOL PurgeComm( HANDLE hFile, DWORD dwFlags );Вызов этой функции очищает очередь приема/передачи и завершает все находящиеся в ожидании запросы ввода/вывода. hFile — описатель открытого порта. dwFlags — производимые действия в виде набора флагов PURGE_TXABORT, PURGE_RXABORT, PURGE_TXCLEAR, PURGE_RXCLEAR. Прием данных будет происходить по событийной схеме; программа будет ожидать прием одного или нескольких символов (байт). Для перевода порта в этот режим необходимо вызвать функцию SetCommMask() с флагом EV_RXCHAR: if not SetCommMask(hPort, EV_RXCHAR) then raise Exception.Create('Error setting port mask');Прием и передача данных выполняется функциями ReadFile() и WriteFile(), то есть теми же самыми функциями, которые используются для работы с дисковыми файлами. Вот их описание: BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped ); BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped ); hFile — описатель открытого порта. lpBuffer — адрес буфера. nNumberOfBytesToRead/nNumberOfBytesToWrite — число ожидаемых к приему или предназначенных для передачи байт. lpNumberOfBytesRead/lpNumberOfBytesWritten — число фактически принятых или переданных байт. lpOverlapped — адрес структуры OVERLAPPED, используемой для асинхронных операций. Передача данных является довольно быстрой операцией, поэтому как правило ее выполняют из главного потока приложения. На Delphi это выглядит так: var dwWrite: DWORD; OverWrite: TOverlapped; WriteBytes: array of Byte; … begin OverWrite.hEvent := CreateEvent(nil, True, False, nil); if OverWrite.hEvent = Null then raise Exception.Create('Error creating write event'); … if (not WriteFile(hPort, WriteBytes, SizeOf(WriteBytes), dwWrite, @OverWrite)) and (GetLastError <> ERROR_IO_PENDING) then raise Exception.Create('Error writing port'); end;В данном примере функция WriteFile() выполняет асинхронную запись массива байтов WriteBytes в порт. Она сразу возвращает управление, и запись в порт происходит параллельно с выполнением основного кода потока. Если результат WriteFile() равен False, то это значит, что на момент возврата управления передача массива байтов еще не закончилась. Поэтому код ошибки выполнения WriteFile() в данном случае должен быть равен ERROR_IO_PENDING. Переменная OverWrite — overlapped-структура, необходимая для асинхронных операций. Вот ссылки, которые, возможно, тебе помогут: http://www.delphikingdom.ru/asp/view...ing/ports1.htm http://msdn.microsoft.com/library/de...sdn_serial.asp
__________________
Старые игры раздают здесь |
![]() |