|
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. Что я упустил?
--------------------
Не так страшна автоматизация, как её малюют.
|
|
|
|
|
 |
Ответов
|
Jan 19 2015, 08:28
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(vazz @ Jan 14 2015, 15:25)  Неужели ни у кого нет опыта написания библиотеки/модуля для работы с com-портом с использованием WinAPI? Опыт есть. Один раз настроил и забыл. Копипаст из проекта в проект. Работает как часы. Код bool MainWindow::openComPort(bool is19200) { std::string nameComPort = comPort->currentText().toStdString(); std::wstring wComPort; wComPort.resize(nameComPort.size()); for(unsigned int i=0; i<nameComPort.size(); i++) wComPort[i] = (WCHAR)nameComPort.at(i); wComPort.insert(0, L"\\\\.\\"); port=CreateFile( wComPort.c_str(), GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(port == INVALID_HANDLE_VALUE) { QApplication::restoreOverrideCursor(); QMessageBox::critical(this, "Spyhole error", QString("Can not open com port %1").arg(QString::fromStdString(nameComPort))); return false; } else { GetCommState(port,&dcb); //memset(&dcb, 0, sizeof(DCB)); dcb.DCBlength=sizeof(DCB); std::wstring config;
std::string tConfig = is19200 ? "baud=19200 parity=N data=8 stop=1" : "baud=115200 parity=N data=8 stop=1"; config.resize(tConfig.size()); for(unsigned int i=0; i<tConfig.size(); i++) config[i] = (WCHAR)tConfig.at(i);
BuildCommDCB(config.c_str(),&dcb); dcb.fNull=FALSE; ct.ReadIntervalTimeout=1000; ct.ReadTotalTimeoutMultiplier=0; ct.ReadTotalTimeoutConstant=5000; if( !SetCommState(port,&dcb)) { CloseHandle(port); port = NULL; QApplication::restoreOverrideCursor(); QMessageBox::critical(this, "Spyhole error", QString("Cann't set config of %1").arg(QString::fromStdString(nameComPort))); return false; } SetCommTimeouts(port,&ct); PurgeComm(port,PURGE_TXCLEAR|PURGE_RXCLEAR); SetupComm(port,4500,4500); } return true; } Код bool MainWindow::readCurve(CURVE curve, unsigned char *replay) { unsigned char command[20]; ...
WriteFile(port,command, 8, &BytesCnt, NULL);
ReadFile(port, replay, 4000, &BytesCnt, NULL); if(BytesCnt != 4000 ) { QApplication::restoreOverrideCursor(); QMessageBox::critical(this, "Spyhole error", QString("Can not receive 4000 byte. Received %1 bytes").arg(BytesCnt)); return false; } return true; }
|
|
|
|
Сообщений в этой теме
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 SM Да есть опыт... Но ничего такого не видно, почему ... Jan 14 2015, 12:27 RabidRabbit До кучи
CODE
bool CComm6055::exchangeData( QByte... Jan 14 2015, 12:39 vazz В общем приходится периодически возвращаться к это... Dec 25 2016, 06:55 aaarrr Цитата(vazz @ Dec 25 2016, 09:55) что за ... Dec 25 2016, 07:51  toweroff Цитата(aaarrr @ Dec 25 2016, 10:51) Есть ... Dec 26 2016, 06:02   gerber Цитата(toweroff @ Dec 26 2016, 09:02) буд... Dec 27 2016, 15:22    toweroff Цитата(gerber @ Dec 27 2016, 18:22) При с... Dec 27 2016, 21:03     jorikdima Цитата(toweroff @ Dec 27 2016, 13:03) Ну ... Dec 27 2016, 21:42      zltigo Цитата(jorikdima @ Dec 27 2016, 23:42) Ст... Dec 27 2016, 21:51       jorikdima Цитата(zltigo @ Dec 27 2016, 13:51) А Вам... Dec 28 2016, 01:42        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
|
|
|