реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> COM порт в win98 и winXP
Freeze Anti
сообщение Jun 20 2007, 04:56
Сообщение #1


Частый гость
**

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



Здравствуйте.

Я написал программу в СиБилдере 6-ом, передающую на ком-порт некоторую информацию. Программа довольно сносно работает в win98... Но в winXP почему-то принимает только последние фразы сообщений (я передаю просто текст)...

Так вот вопрос... Чем отличается работа с RS-232 в 98 и ХР?..

P.S. порт работает в асинхронном режиме, так как микроконтроллер, с которого передаются сообщения, не работает в синхронном режиме...


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
ALexx
сообщение Jun 20 2007, 06:36
Сообщение #2


Местный
***

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



Цитата(Freeze Anti @ Jun 20 2007, 07:56) *
Здравствуйте.

Я написал программу в СиБилдере 6-ом, передающую на ком-порт некоторую информацию. Программа довольно сносно работает в win98... Но в winXP почему-то принимает только последние фразы сообщений (я передаю просто текст)...

Так вот вопрос... Чем отличается работа с RS-232 в 98 и ХР?..

P.S. порт работает в асинхронном режиме, так как микроконтроллер, с которого передаются сообщения, не работает в синхронном режиме...


Какими средствами осуществляете доступ к порту(открытие, передача/прием)?
Прямой записью в регистры? Или используя специальную компоненту под Билдер?

Дело в том, что в 98-й прямой доступ к портам возможен, а в ХР - увы sad.gif
Go to the top of the page
 
+Quote Post
Freeze Anti
сообщение Jun 20 2007, 06:50
Сообщение #3


Частый гость
**

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



Я пользуюсь WinAPI.

Ну, разумеется, команды CreateFile, WriteFile, ReadFile, BuildCommDCB, SetCommState, SetCommTimeouts. Вроде и все...

Сам-то порт открывается, даже пересылает что-то... Но большая часть информации где-то теряется...

Если надо, могу код прислать...


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
ALexx
сообщение Jun 20 2007, 07:07
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 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-й и под ХР.
Прикрепленные файлы
Прикрепленный файл  CPort264.zip ( 182.07 килобайт ) Кол-во скачиваний: 149
 
Go to the top of the page
 
+Quote Post
Warlord
сообщение Jun 20 2007, 07:31
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874



WinAPI с COM-портом под Билдером работает корректно - опробовано на практике. Так что код в студию!
Go to the top of the page
 
+Quote Post
Freeze Anti
сообщение Jun 20 2007, 11:53
Сообщение #6


Частый гость
**

Группа: Новичок
Сообщений: 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 !!!
Go to the top of the page
 
+Quote Post
ALexx
сообщение Jun 20 2007, 12:54
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 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 не русским буквами случаем набрано 07.gif Ну и точка с запятой отсутствует :-)
А вообще, если надо менять только номер порта (оставляя все настройки) можно использовать
ComComboBox. На прилагаемом рисунке пояснение как его использовать.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Freeze Anti
сообщение Jun 21 2007, 04:53
Сообщение #8


Частый гость
**

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



1.1 С таймаутами игрался. Все без толку. Доходит до некоторого места и перестает принимать.
1.2 Я вообще не трогал управление потоком. Очень не хочется переделывать программу для микроконтроллера (Это мне прибор таскать в другую комнату, чтобы перепрошить). Если дело в этом, то как следует поступить?

2. Попробовал использовать ComComboBox. Все равно вылетает ошибка линкера.


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
ALexx
сообщение Jun 21 2007, 07:14
Сообщение #9


Местный
***

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



Цитата(Freeze Anti @ Jun 21 2007, 07:53) *
1.1 С таймаутами игрался. Все без толку. Доходит до некоторого места и перестает принимать.
1.2 Я вообще не трогал управление потоком. Очень не хочется переделывать программу для микроконтроллера (Это мне прибор таскать в другую комнату, чтобы перепрошить). Если дело в этом, то как следует поступить?

2. Попробовал использовать ComComboBox. Все равно вылетает ошибка линкера.


Киньте кодом мне на ящик dealex77<гав>ukr.net - посмотрю
Go to the top of the page
 
+Quote Post
Warlord
сообщение Jun 21 2007, 10:31
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874



Глянул я код, чот ничо не понятно, кто кому и чего шлет?? Зачем сначала порт открывается, записывается, а потом закрывается снова открывается считывается?? Потом в порт пишется всего 1 байт 0x5A, где же текст?? Потом если используется аснхронный режим, то прежде чем закрыть порт н.б. уверенным что данные все же успешно туда записаны, т.е. использовать WaitForSingleObject. Потом какое-то странное считывание порта, вслед за асинхронным считыванием вызывается функция очистки буферов порта, а потом удивляемся - данные куда-то пропадают... Рекомндую порыться в инете (или MSDN) и добыть несколько рабочих примеров работы с COM-портом
Go to the top of the page
 
+Quote Post
Freeze Anti
сообщение Jun 21 2007, 12:04
Сообщение #11


Частый гость
**

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



Спасибо большое за помощь в решении моего вопроса.

Задача уже решена.

Почему не получилось с API, я так и не понял, но с библиотекой все отлично работает (даже лучше и проще, чем с API).

В программе, написанной с использованием библиотеки была ошибка не в пересылке данных, а в выводе данных на экран. Я немного неправильно инкрементировал счетчик итераций в цикле, поэтому и вывод на экран был соответственным.


--------------------
!!! All you need is LOVE !!!
Go to the top of the page
 
+Quote Post
oran-be
сообщение Jun 26 2007, 17:33
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 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);

идут уже асинхронные. Необходимо проверить возврат. Если запускается асинхронная операция на порту в асинхронном режиме, функция не будет дожидаться пока уйдут все данные, она вывалится с возвратом типа произошла ошибка( непомню точно идентификатор), хотя на самом деле это и не ошибка. Тогда надо вручную дожидаться конца асинхронной операции.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 16:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01466 секунд с 7
ELECTRONIX ©2004-2016