Re[2]: Прошу помочь! Работа с COM портом через API
От:
Аноним
Дата:
18.10.03 11:27
Оценка:
Здравствуйте, GDV, Вы писали:
GDV>Здравствуйте Nick_Y, вы писали:
NY>>Как через API настроить порт таким образом, чтобы можно было посылать в него пакеты, дожидаться, пока они уйдут из буфера и принимать ответ из порта ? NY>>Меня интересует установка таймаутов ожидания на прием и передачу или передача как OVERLAPPED. NY>>Заранее благодарен.
GDV>Я работал с модемом через WIN32Api, могу посветовать книгу (названия сейчас под рукой нет GDV>но если заинтересуешься , то пришлю), а в MSDN набери функцию SetupComm а там по ссылкам найдешь весь пригодный API, если возникнут конкретные вопросы пиши
Если можно, то и мне бы книжицу (meteorgroup@ua.fm), или хотя бы намек на злачное место, где ее найти. Заранее большое спасибо.
Re[3]: Прошу помочь! Работа с COM портом через API
IX>Приведу пример выполнения настройки порта и выполнения чтения/записи данных.
IX> #include <windows.h> IX> #include <string.h>
IX> . . .
IX> DCB dcb; IX> COMMTIMEOUTS ct; IX> HANDLE port; IX> DWORD bc;
IX> char *buf_out="Test string"; IX> char *buf_in;
IX> . . .
IX> dcb.DCBlength=sizeof(DCB); IX> BuildCommDCB("baud=9600 parity=N data=8 stop=1",&dcb); IX> dcb.fNull=TRUE;
IX> ct.ReadIntervalTimeout=10; IX> ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0; IX> ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0;
IX> port=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
IX> SetCommState(port,dcb); IX> SetCommTimeouts(port,&ct); IX> PurgeComm(port,PURGE_TXCLEAR|PURGE_RXCLEAR); IX> SetupComm(port,256,256);
IX> . . .
IX> buf_in=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,strlen(buf_out)+1); IX> WriteFile(port,buf_out,strlen(buf_out),&bc,NULL); IX> ReadFile(port,buf_in,strlen(buf_out),&bc,NULL);
IX> HeapFree(GetProcessHeap(),0,buf_in); IX> CloseHandle(port);
IX> . . .
IX> Если на COM2 установить перемычку между сигналами TxD и RxD, то переменная IX> buf_in, после выполнения ReadFile, будет содержать ту же информацию, что и IX> buf_out. Других пояснений пример не требует, все уже было подробно IX> рассмотрено раньше. IX> Иногда требуется срочно передать символ, имеющий определенное специальное IX> значение, а в очереди передатчика уже есть данные, которые нельзя терять. IX> В этом случае можно воспользоваться функцией:
Вопрос следующий:
Не могу понять почему срабатывает эта часть кода: IX> WriteFile(port,buf_out,strlen(buf_out),&bc,NULL); IX> ReadFile(port,buf_in,strlen(buf_out),&bc,NULL);
ведь передача NotOverlapped, по идее если эту самую перемычку не постатиь — должно происходить зависание потока, исполняющего этот код, т. к. происходит ожидание приёма данных.
Re[3]: Прошу помочь! Работа с COM портом через API
Здравствуйте, IgoX, Вы писали: IX>Как я уже говорил, с последовательными и параллельными портами в Win32 работают как с файлами. Следовательно, начинать надо с открытия порта как файла. Использовать привычные функции open и fopen при этом нельзя, необходимо воспользоваться функцией CreateFile. Эта функция предоставляется Win32 API. Ее прототип выглядит так:
WINDOWS:
А почему нельзя пользоваться fopen и open?
Я вот, например, пользуюсь — и вроде ничего.
Конечно никаких штук с timeout проделывать нельзя и как следствие нельзя запрограммировать свой протокол, нельзя обеспечить НЕблокирующий ввод. Но просто последовательно читать-писать вроде получается. Правда при этом надо хитрить: fflush на чтение/запись корректно не работает, но мне удалось победить это с помощью поля _flag структуры FILE.
Вот такой у меня код в итоге получился:
void PUTBYTE(char x){
COM_FILE->_flag=_IORW|_IOMYBUF|_IOREAD;//ONLY VISUAL C++
fwrite(&x,1,1,COM_FILE);
COM_FILE->_flag=_IORW|_IOMYBUF|_IOWRT;//ONLY VISUAL C++
}
char GETBYTE(){
char ch = 0;
fread(&ch,1,1,COM_FILE);
return ch;
}
int OpenCom(){
if (COM_FILE != NULL){
//already opened
return -1;
}
//cygwin COM_FILE = fopen (SERIAL_NAME,O_RDWR|O_NOCTTY | O_NONBLOCK | O_BINARY);
COM_FILE = fopen (SERIAL_NAME,"rb+");
//cygwin fcntl(COM_FILE,F_SETFL,O_NONBLOCK);
return COM_FILE;
};
CYGWIN
А под cygwin даже хитрить не надо. fflush работает очень даже корректно. Хотя ввод по-прежнему неблокирующий. UNIX
Знаю только теоретически: fopen и open ВПОЛНЕ корректно работают с com-портами. Только нужно при этом использовать fcntl для установки режимов ввода-вывода. То есть под *nix нет даже проблем с блокировкой ввода...
ВЫВОДКороче говоря, если нам не нужно регулировать скорость передачи данных по rs-232, fopen/open вполне работают... ВЫ МОЖЕТЕ СПРОСИТЬ: а как же установить скорость передачи данных на своём конце связи?
Но в том-то и дело, что в начале можно настроить скорость передачи данных на своём com-порте с помощью другой проги. (Например, HyperTerm) а затем запустить свою прогу. И всё работает!!!
Re[2]: Прошу помочь! Работа с COM портом через API
От:
Аноним
Дата:
19.06.04 06:57
Оценка:
Здравствуйте, volk, Вы писали:
V> На delphi.vitpc.com лежит неплохая статья (может быть, даже не одна). Есть там и исходник.
Уважаемый volk, не могли бы оставить свой e-mail или icq.. пообщаться хочеться...
или свяжитесь со мной по: email: sergun@hostel7.susu.ac.ru; icq: 30655536
Re[3]: Прошу помочь! Работа с COM портом через API
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Bai, Вы писали:
Bai>>Здравствуйте Nick_Y, Вы писали:
NY>>>Как через API настроить порт таким образом, чтобы можно было посылать в него пакеты, дожидаться, пока они уйдут из буфера и принимать ответ из порта ? NY>>>Меня интересует установка таймаутов ожидания на прием и передачу или передача как OVERLAPPED. NY>>>Заранее благодарен.
Bai>>Есть у меня пример Bai>>все прозрачно если есть желание могу отправить Bai>>пиши
Да и я не против. Плизз : pashka_root@freemail.lt
Re[3]: Прошу помочь! Работа с COM портом через API
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Bai, Вы писали:
Bai>>Здравствуйте Nick_Y, Вы писали:
NY>>>Как через API настроить порт таким образом, чтобы можно было посылать в него пакеты, дожидаться, пока они уйдут из буфера и принимать ответ из порта ? NY>>>Меня интересует установка таймаутов ожидания на прием и передачу или передача как OVERLAPPED. NY>>>Заранее благодарен.
Bai>>Есть у меня пример Bai>>все прозрачно если есть желание могу отправить Bai>>пиши
Если можно, то и мне примерчик: popusoill@mail.ru
Заранее огромное спасибо.
Re[4]: Прошу помочь! Работа с COM портом через API
Здравствуйте, Flexer, Вы писали:
F>Вопрос следующий: F>Не могу понять почему срабатывает эта часть кода: IX>> WriteFile(port,buf_out,strlen(buf_out),&bc,NULL); IX>> ReadFile(port,buf_in,strlen(buf_out),&bc,NULL); F>ведь передача NotOverlapped, по идее если эту самую перемычку не постатиь — должно происходить зависание потока, исполняющего этот код, т. к. происходит ожидание приёма данных.
для этого и настраивают таймеры.
Наскока я понял за выходные То IX> ct.ReadIntervalTimeout=10; IX> ct.ReadTotalTimeoutMultiplier=ct.ReadTotalTimeoutConstant=0; IX> ct.WriteTotalTimeoutMultiplier=ct.WriteTotalTimeoutConstant=0;
вот эта конструкция вернет управление через 10 милисекунд.