IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Программирование (http://www.imho.ws/forumdisplay.php?f=40)
-   -   Проблема серийного порта в Windows 2000 (http://www.imho.ws/showthread.php?t=83809)

viktorgo 14.04.2005 17:29

Проблема серийного порта в Windows 2000
 
Есть следующая проблема. Я делаю софт который связывается с девайсом по RS-232. так вот - девайсу нужно видеть старт и стоп биты для уверенного приёма, а W2k, если шлешь много 0хFF, склеивает стринги и убирает старт и стоп биты. У кого-нибудь есть идея, что делать.

PSyton 22.04.2005 08:01

Что-то смутно вериться что проблема в Win2k скорее в правильности инициализации порта. Во всяком случае я что-то смутно припоминаю что при открытии порта задаются параметры его работы...

CEO 22.04.2005 10:47

Для того чтобы дать тебе толковый совет нужно видеть как ты программируешь 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


Часовой пояс GMT +4, время: 06:07.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.