|
|
  |
COM порт в win98 и winXP |
|
|
|
Jun 20 2007, 06:36
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 22-09-04
Из: Burbach, Germany
Пользователь №: 704

|
Цитата(Freeze Anti @ Jun 20 2007, 07:56)  Здравствуйте.
Я написал программу в СиБилдере 6-ом, передающую на ком-порт некоторую информацию. Программа довольно сносно работает в win98... Но в winXP почему-то принимает только последние фразы сообщений (я передаю просто текст)...
Так вот вопрос... Чем отличается работа с RS-232 в 98 и ХР?..
P.S. порт работает в асинхронном режиме, так как микроконтроллер, с которого передаются сообщения, не работает в синхронном режиме... Какими средствами осуществляете доступ к порту(открытие, передача/прием)? Прямой записью в регистры? Или используя специальную компоненту под Билдер? Дело в том, что в 98-й прямой доступ к портам возможен, а в ХР - увы
|
|
|
|
|
Jun 20 2007, 06:50
|

Частый гость
 
Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613

|
Я пользуюсь WinAPI.
Ну, разумеется, команды CreateFile, WriteFile, ReadFile, BuildCommDCB, SetCommState, SetCommTimeouts. Вроде и все...
Сам-то порт открывается, даже пересылает что-то... Но большая часть информации где-то теряется...
Если надо, могу код прислать...
--------------------
!!! All you need is LOVE !!!
|
|
|
|
|
Jun 20 2007, 07:07
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 22-09-04
Из: Burbach, Germany
Пользователь №: 704

|
Цитата(Freeze Anti @ Jun 20 2007, 09:50)  Я пользуюсь WinAPI.
Ну, разумеется, команды CreateFile, WriteFile, ReadFile, BuildCommDCB, SetCommState, SetCommTimeouts. Вроде и все...
Сам-то порт открывается, даже пересылает что-то... Но большая часть информации где-то теряется...
Если надо, могу код прислать... Может тут "собака и порылась"? WinAPI не пользовался - точно сказать не могу, но может то, что работает в 98-й не может работать или работает криво в ХР. Четвертый год пользуюсь компонентой ComPort Library (одна из последних версий прилагается). Программы, созданные с ее использованием работают и под 98-й и под 2000-й и под ХР.
|
|
|
|
|
Jun 20 2007, 11:53
|

Частый гость
 
Группа: Новичок
Сообщений: 153
Регистрация: 29-03-07
Из: Саратов
Пользователь №: 26 613

|
Попробовал эту библиотеку. Уже гораздо лучше. Спасибо огромное. Принимаю почти то, что и хотел, правда есть еще два вопроса. 1. Почему-то проглатывается несколько последних строчек. 2. Не очень понял, как программно выбрать порт. Когда я пытаюсь набрать Код cPort->Port = "COM1" мне выдается ошибка линковщика. На всякий случай код апишной программы. Если получится лучше и быстрей - оставлю этот вариант. Код if (RadioButton_Com1->Checked) { COMString = "COM1"; } if (RadioButton_Com2->Checked) { COMString = "COM2"; }
HANDLE port; int buf_out; char buf_in[255] = ""; AnsiString LogString; int i = 0; OVERLAPPED ovr; DWORD bc; DCB *dcb; COMMTIMEOUTS ct; dcb = (DCB*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DCB)); dcb->DCBlength = sizeof(DCB); BuildCommDCB("baud=2400 parity=N data=8 stop=1", dcb); dcb->fNull = TRUE; ct.ReadIntervalTimeout = 10; ct.ReadTotalTimeoutMultiplier = ct.ReadTotalTimeoutConstant = 100; ct.WriteTotalTimeoutMultiplier = ct.WriteTotalTimeoutConstant = 0; memset(&ovr, 0, sizeof(ovr)); ovr.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); port = CreateFile(COMString, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (port == INVALID_HANDLE_VALUE) { MessageBox(NULL, "Невозможно открыть порт для записи", "Ошибка", MB_OK); return; } SetCommState(port, dcb); SetCommTimeouts(port, &ct); buf_out = 0x5A; WriteFile(port, &buf_out, 1, &bc, &ovr); DWORD ReopenTime = GetTickCount(); CloseHandle(port); port = CreateFile(COMString, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (port == INVALID_HANDLE_VALUE) { MessageBox(NULL, "Невозможно открыть порт для чтения", "Ошибка", MB_OK); return; } SetCommState(port, dcb); HeapFree(GetProcessHeap(), 0, dcb); SetCommTimeouts(port, &ct); DWORD StartTime = GetTickCount(); bc = 1; bool StartRead = false; while ((GetTickCount() - StartTime) < 10000) { Application->ProcessMessages(); buf_in[i] = 0; ReadFile(port, &buf_in[i], 1, &bc, &ovr); PurgeComm(port, PURGE_RXCLEAR|PURGE_TXCLEAR); Sleep(1); i++; if (buf_in[i] == buf_in[i - 1] == ' ') buf_in[i] = 0; if (buf_in[i] != 0) LogString += Recode(buf_in[i]); if (i == 246) { Log->Lines->Add(LogString); i = 0; LogString = ""; } } Здесь Log - TMemo В 98-ой принимает более-менее нормально (Начальство довольно), а в ХР - только несколько несвязных фраз, почти все проглатывает.
Сообщение отредактировал Freeze Anti - Jun 20 2007, 11:54
--------------------
!!! All you need is LOVE !!!
|
|
|
|
|
Jun 20 2007, 12:54
|

Местный
  
Группа: Свой
Сообщений: 243
Регистрация: 22-09-04
Из: Burbach, Germany
Пользователь №: 704

|
Цитата(Freeze Anti @ Jun 20 2007, 14:53)  Попробовал эту библиотеку. Уже гораздо лучше. Спасибо огромное. Принимаю почти то, что и хотел, правда есть еще два вопроса. 1. Почему-то проглатывается несколько последних строчек. 2. Не очень понял, как программно выбрать порт. Когда я пытаюсь набрать Код cPort->Port = "COM1" мне выдается ошибка линковщика. 1.1 Поиграйте с таймаутам 1.2 Управление потоком какое? Аппаратное, программное, или вообще его нет? Не попадаются ли среди смволов XON или XOFF 2. СОМ1 не русским буквами случаем набрано  Ну и точка с запятой отсутствует :-) А вообще, если надо менять только номер порта (оставляя все настройки) можно использовать ComComboBox. На прилагаемом рисунке пояснение как его использовать.
Эскизы прикрепленных изображений
|
|
|
|
|
Jun 21 2007, 10:31
|
Частый гость
 
Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874

|
Глянул я код, чот ничо не понятно, кто кому и чего шлет?? Зачем сначала порт открывается, записывается, а потом закрывается снова открывается считывается?? Потом в порт пишется всего 1 байт 0x5A, где же текст?? Потом если используется аснхронный режим, то прежде чем закрыть порт н.б. уверенным что данные все же успешно туда записаны, т.е. использовать WaitForSingleObject. Потом какое-то странное считывание порта, вслед за асинхронным считыванием вызывается функция очистки буферов порта, а потом удивляемся - данные куда-то пропадают... Рекомндую порыться в инете (или MSDN) и добыть несколько рабочих примеров работы с COM-портом
|
|
|
|
|
Jun 26 2007, 17:33
|
Местный
  
Группа: Свой
Сообщений: 234
Регистрация: 30-03-07
Из: Одесса
Пользователь №: 26 621

|
Есть еще бааальшой нюанс. В ХР с СОМ портом лучше всего работать в асинхронном режиме. То есть в синхронном он может и будет работать, но при установке софта на другой комп могут возникнуть такие глюки, что мама дорогая. Для этого при вызове
port = CreateFile(COMString, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
последний аргумент передать не NULL, а адрес предварительно созданной структуры OVERLAPPED. Ну и работать надо с ним немного не так, а погембельнее. В MSDN должны быть примеры. К стати, при ближайшем рассмотрении кода я наблюдаю, что Порт открывается в синхронном режиме, а вызовы WriteFile(port, &buf_out, 1, &bc, &ovr); ReadFile(port, &buf_in[i], 1, &bc, &ovr);
идут уже асинхронные. Необходимо проверить возврат. Если запускается асинхронная операция на порту в асинхронном режиме, функция не будет дожидаться пока уйдут все данные, она вывалится с возвратом типа произошла ошибка( непомню точно идентификатор), хотя на самом деле это и не ошибка. Тогда надо вручную дожидаться конца асинхронной операции.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|