|
WinAPI - Serial communications, COM-порт по трем проводам |
|
|
|
Jan 6 2015, 13:31
|

Частый гость
 
Группа: Участник
Сообщений: 189
Регистрация: 21-01-10
Пользователь №: 54 971

|
Раньше никогда не сталкивался с необходимостью осваивать WinAPI в части работы с COM-портами, другие способы коммуникации как-то больше волновали. А теперь вот не могу справится с простейшей на мой первоначальный взгляд задачей - реализация асинхронного обмена через "банальный" COM-порт. К COM-порту подключен модем, "понимающий" стандартный набор AT-команд. Вот и решил я далеко не ходить и не разгребать глюки готовых классов и модулей, реализованных другими разработчиками. Лицензионные продукты для своей простой задачи не вижу смысла покупать. Вот пал выбор на WinAPI. Вроде бы и информации в сети валом и msdn внимательно почитал, но у меня то ли неправильно выстроился алгоритм программы то ли дядюшка билли со своими извращенными алгоритмами всевозможных ограничений прав доступа к памяти мешает. Прошу помощи. Успешно открываю порт Код -- kernel32 - подгружаемая библиотека WinAPI-функций -- comid - номер открываемого порта -- handle - итоговый указатель на порт handle = kernel32.CreateFileA("\\\\.\\COM" .. comid, GENERIC_READ+GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0) Далее я создаю и заполняю структуры BCD и COMMTIMEOUTS. Сохраняю настройки с помощью функций SetCommState, SetCommTimeouts - обе возвращают TRUE. Код DCB.BaudRate = CBR_9600; DCB.ByteSize = 8; DCB.Parity = NOPARITY; DCB.StopBits = ONESTOPBIT; DCB.fBinary = 1; DCB.fOutxCtsFlow = 0; DCB.fOutxDsrFlow = 0; DCB.fDtrControl = DTR_CONTROL_DISABLE; DCB.fDsrSensitivity = 0; DCB.fNull = 0; DCB.fRtsControl = RTS_CONTROL_DISABLE; DCB.fAbortOnError = 0;
COMMTIMEOUTS.ReadIntervalTimeout = 10; COMMTIMEOUTS.ReadTotalTimeoutMultiplier = 1; COMMTIMEOUTS.ReadTotalTimeoutConstant = 100; COMMTIMEOUTS.WriteTotalTimeoutMultiplier = 0; COMMTIMEOUTS.WriteTotalTimeoutConstant = 0; Далее пытаюсь отправить данные в порт Код -- data - массив с данными -- b - указатель на переменную типа DWORD "счетчик байт" -- t - указатель на буфер с данными -- n - кол-во данных в массиве data local n = Table.Count(data); local b = MemoryEx.Allocate(4); local t = MemoryEx.Allocate(n); if (b and t) then -- сброс счетчика байт MemoryEx.Fill(b, 4, 0, MEMEX_BYTE); -- заполнение буфера данными из массива data local c = 1; repeat MemoryEx.Byte(t + c - 1, data[c]); c = c + 1; until c > n; -- запись в порт if (kernel32.WriteFile(handle, t, n, b, 0) == 0) then local e = kernel32.GetLastError(); Dialog.Message("error", e); end end После попытки записать что-либо в порт функция возвращает 5, т.е. ACCESS DENIED. Что я упустил?
--------------------
Не так страшна автоматизация, как её малюют.
|
|
|
|
|
 |
Ответов
|
Dec 25 2016, 06:55
|

Частый гость
 
Группа: Участник
Сообщений: 189
Регистрация: 21-01-10
Пользователь №: 54 971

|
В общем приходится периодически возвращаться к этой теме  видимо, хочешь не хочешь, а освоить работу с com-портами мне придется. На текущий момент повспоминал все что было, решил создать простенькое windowed приложение для теста com-портов. Так вот, возвращаясь к ранее обсуждаемой на этом форуме проблеме, сообщаю, что как и ранее открыть порт удается, настроить тоже (проверяю записаны ли настройки непосредственно по поинтеру зарезервированного под них куска памяти). Записать данные удалось (вроде бы тут должно быть "уррра!!!"), но только в одном случае - при открытии порта функцией CreateFile я передаю ей параметр dwDesiredAccess равный GENERIC_WRITE. Если при вызове этой функции я указываю GENERIC_READ + GENERIC_WRITE, то запись в порт не происходит. Порт открываю пока обычном режиме (NOT OVERLAPPED). Вопрос: если я открываю порт в НЕ асинхронном режиме, то я могу открыть его только "в одностороннем режиме", т.е. открываю порт для записи, потом закрываю порт и если мне нужно получить ответ от устройства, то я снова открываю порт но уже в режиме чтения и читаю данные? Бредовенько как-то.. В инете куча примеров где в 100% случаев права при вызове функции CreateFile указываются именно как "GENERIC_READ | GENERIC_WRITE", что за фигня у меня, у кого какие мысли?
--------------------
Не так страшна автоматизация, как её малюют.
|
|
|
|
|
Dec 26 2016, 06:02
|

Гуру
     
Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514

|
Цитата(aaarrr @ Dec 25 2016, 10:51)  Есть такая мысль, что (GENERIC_READ + GENERIC_WRITE) в вашем случае оказывается не равно (GENERIC_READ | GENERIC_WRITE). хмм... Код #define GENERIC_READ 0x80000000 #define GENERIC_WRITE 0x40000000 #define GENERIC_EXECUTE 0x20000000 #define GENERIC_ALL 0x10000000 будут они равны, хоть ОРь, хоть складывай
|
|
|
|
|
Dec 27 2016, 15:22
|
Знающий
   
Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088

|
Цитата(toweroff @ Dec 26 2016, 09:02)  будут они равны, хоть ОРь, хоть складывай При сложении будет учтен знак, если константы signed.
--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
|
|
|
|
Сообщений в этой теме
vazz WinAPI - Serial communications Jan 6 2015, 13:31 Xenia Попробуйте заменить
FILE_FLAG_OVERLAPPED
на
FILE_... Jan 6 2015, 14:22 vazz Xenia, я пробовал играться с этим флагом. Я так по... Jan 6 2015, 14:42 Палыч Поскольку Вы при открытии файла указали флаг FILE_... Jan 6 2015, 14:31 vazz Цитата(Палыч @ Jan 6 2015, 18:31) Посколь... Jan 6 2015, 14:53 Xenia Ну, а номер COM-порту вы назначили? Jan 6 2015, 14:43 vazz Неужели ни у кого нет опыта написания библиотеки/м... Jan 14 2015, 10:25 juvf Цитата(vazz @ Jan 14 2015, 15:25) Неужели... Jan 19 2015, 08:28 SM Да есть опыт... Но ничего такого не видно, почему ... Jan 14 2015, 12:27 RabidRabbit До кучи
CODE
bool CComm6055::exchangeData( QByte... Jan 14 2015, 12:39        zltigo Цитата(jorikdima @ Dec 28 2016, 03:42) Ни... Jan 12 2017, 20:35  k155la3 Цитата(aaarrr @ Dec 25 2016, 10:51) Есть ... Dec 28 2016, 07:34 vazz спасибо большое за ответы! дело оказалось дейс... Jan 12 2017, 18:14 ar__systems Цитата(vazz @ Jan 12 2017, 13:14) в дальн... Jan 13 2017, 02:54
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|