|
|
|
Работа с СОМ портом, Win2000 |
|
|
|
May 24 2005, 10:44
|
Частый гость
Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040
|
Цитата(_VM @ Mar 29 2005, 03:20) А я что-то не соображу, почему из 2-х разных потоков одновременно читать/писать неполучится И я тоже не рад этой особенности XP. Еще раз подтверждаю (опять "влетел") - дело не в разных потоках. Если в программе возможно обращение к порту ОДНОВРЕМЕННОЕ из разых потоков, под XP аппликэйшн зависнет насмерть. А для WIN98 нет проблем. Это касается всех функций использующих idComDev ( где idComDev это : HANDLE idComDev = ::CreateFile.......) В том числе и ::GetCommModemStatus ::GetCommMask ::EscapeCommFunction ::SetCommState(idComDev, &dcb).. И видимо вообще для всех. В случае применения синхронизации для использования этих функций из разных потоков никаких проблем не обнаружено.
--------------------
- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
|
|
|
|
|
May 25 2005, 05:52
|
Участник
Группа: Свой
Сообщений: 27
Регистрация: 28-04-05
Пользователь №: 4 557
|
[/quote] Так REALTIME_PRIORITY_CLASS это вроде и есть приоритет процесса Скажу больше - для приоритета есть еще и динамический диапазон определяемый относительно базового. Правда для такого REALTIME приоритета процесса, поток все равно получился 15. Не знаю почему. Глубоко не ковырялся. [/quote] Обратимся к книге Джеффри Рихтера "Windows Создание эфективных win-32 приложений". " -Концепция класса приоритета вводит некоторых в заблуждение. Они делают отсюда вывод, будто процессы учавствуют в распределении процессорного времени. Так вот, процессы никогда не получают прцессорное время - оно выделяется лишь потокам. Класс приоритета процесса - сугубо абстрактная концепция, введенная Microsoft с единственной целью: скрыть от разработчика внутреннее устройство планировщика". Приоритет потока всегда относителен к классу приоритета его процесса. Изменение приоритета процесса не влияет на относительный приоритет потока, но сказывается на их уровне приоритета в системе. Клас приоритета потока Относительный приоритет Idle Bellow Normal Above High Real-time потока Normal Normal Time-Critical 15 15 15 15 15 31 Highest 6 8 10 12 15 26 Above Normal 5 7 9 11 14 25 Normal 4 6 8 10 13 24 Bellow Normal 3 5 7 9 12 23 Lowest 2 4 6 8 11 22 Idle 1 1 1 1 1 16 Уровень 0 зарезервирован. Кроме того, уровни 17-21 и 27-30 в обычном приложении тоже не доступны.Вы можете пользоваться ими, только если пишите драйвер устройства, работающего в режиме ядра. И еще одно: уровень приоритета потока в процессе с классом real time не может опускаться ниже 16. а потока с любым другим классом поднималься выше 15. И еше : 1. Планировщик не документирован полностью 2 Microsoft не разрешает в полной мере использовать особенности планировщика 3. Microsoft предупреждает, что алгоритмп ланировщика постоянно меняется, и не рекомендует писать программы в расчете на текущий алгоритм. Вот так обстаят дела
|
|
|
|
|
Jun 22 2005, 11:46
|
Участник
Группа: Новичок
Сообщений: 25
Регистрация: 28-03-05
Пользователь №: 3 734
|
Цитата(yuriyc @ May 25 2005, 08:52) Обратимся к книге Джеффри Рихтера "Windows Создание эфективных win-32 приложений". " -Концепция класса приоритета вводит некоторых в заблуждение. Они делают отсюда вывод, будто процессы учавствуют в распределении процессорного времени. Так вот, процессы никогда не получают прцессорное время - оно выделяется лишь потокам. Класс приоритета процесса - сугубо абстрактная концепция, введенная Microsoft с единственной целью: скрыть от разработчика внутреннее устройство планировщика". ... Уровень 0 зарезервирован. Кроме того, уровни 17-21 и 27-30 в обычном приложении тоже не доступны.Вы можете пользоваться ими, только если пишите драйвер устройства, работающего в режиме ядра. И еще одно: уровень приоритета потока в процессе с классом real time не может опускаться ниже 16. а потока с любым другим классом поднималься выше 15. 2yuriyc: Спасибо за информацию. Я пользовался в основном "Windows 98. Руководство разработчика. Бен Эззель, Джим Блейни". Правда _измеренный_ приоритет потока THREAD_PRIORITY_TIME_CRITICAL в REALTIME_PRIORITY_CLASS не поднимался выше 15. Но я проверил опытным путем. Запустил бесконечный цикл с этим приоритетом, в результате повесилась даже мышка . 2all: Кто нибудь знает, каким образом можно точно переключить RTS после передачи слова? Автоматический вариант не подходит Происходит или большая задержка между концом слова и переключением или RTS переключается раньше.
|
|
|
|
|
Jun 28 2005, 13:26
|
Участник
Группа: Свой
Сообщений: 27
Регистрация: 28-04-05
Пользователь №: 4 557
|
[/quote] 2all: Кто нибудь знает, каким образом можно точно переключить RTS после передачи слова? Автоматический вариант не подходит Происходит или большая задержка между концом слова и переключением или RTS переключается раньше. [/quote] Как вариант: можно отследить событие/прерывание возникающее по окончанию передачи байта. И ручками выставить RTS.
|
|
|
|
|
Jun 29 2005, 07:03
|
Участник
Группа: Новичок
Сообщений: 25
Регистрация: 28-03-05
Пользователь №: 3 734
|
Цитата(yuriyc @ Jun 28 2005, 16:26) Как вариант: можно отследить событие/прерывание возникающее по окончанию передачи байта. И ручками выставить RTS. Отлов прерываний WIN32? Это если только на уровне драйвера. Других способов не знаю. Событие - возврат из функции записи в порт. При этом если сразу выставить RTS, а потом посмотреть на осциллограф то получится что RTS выставляется в СЕРЕДИНЕ передаваемого слова, то есть надо вводить программную задержку, при этом она (задержка) должна определяться для каждой машины отдельно. RTS выставляю EscapeCommFunction(...). 2vm1: Вы правы, но к сожалению преобразователь интерфейса уже есть и изменить его нельзя, поэтому управлять RTS могу только с машины. Причем добавлять какое-либо оборудование тоже нельзя - все задокументировано и согласовано
|
|
|
|
|
Jul 7 2005, 06:54
|
Частый гость
Группа: Свой
Сообщений: 107
Регистрация: 27-06-05
Из: Россия
Пользователь №: 6 324
|
Вот примерчик для Borland C++ Builder из моей тестовой программки. hCOM, dcb, и sTO обьявлены глобально ( HANDLE hCOM, DCB dcb, COMMTIMEOUTS sTO), в классе MainForm, cbBaudRate - комбо-бокс на главной форме с выбором скорости обмена.
int __fastcall TMainForm::InitComm(int portno) ///////////////////////////////////////////////////////////////////////////// // // Инициализация COM-порта с номером portno. Если инициализация прошла // успешно, то функция возвращает 0, в противном случае один из следующих // кодов: // -1 не удалось получить доступ к COM-порту // -2 не удалось получить доступ к блоку dcb // -3 не удалость перенастроить порт // -4 ошибка при настройке тайм-аутов // ///////////////////////////////////////////////////////////////////////////// { char portname[8]; int result; DWORD val;
sprintf(portname,"COM%d",portno); //
hCOM = CreateFile( portname, // GENERIC_READ|GENERIC_WRITE, // Пробуем получить доступ 0, // к COM-порту NULL, // OPEN_EXISTING, // FILE_ATTRIBUTE_NORMAL, // NULL // );
if( hCOM != INVALID_HANDLE_VALUE ) {//*1*----------------------------------------------------------------- // Настройка параметров порта //-------------------------------------------------------------------- if( GetCommState(hCOM,&dcb) ) {//*2* switch( cbBaudRate->ItemIndex ) { case 0: { dcb.BaudRate=CBR_4800; break; } case 1: { dcb.BaudRate=CBR_9600; break; } case 2: { dcb.BaudRate=CBR_19200; break; } case 3: { dcb.BaudRate=CBR_38400; break; } case 4: { dcb.BaudRate=CBR_57600; break; } case 5: { dcb.BaudRate=CBR_115200; break; } default: dcb.BaudRate=CBR_9600; }// end of switch (cbxBaudRate)
dcb.ByteSize = 8; // в байте 8 битов dcb.fBinary = True; // альтернативы как бы нет
dcb.fNull = False; //
dcb.fOutxCtsFlow = False; // disable TS output flow control dcb.fOutxDsrFlow = False; // disable DSR output flow control dcb.fErrorChar = False; // disable error replacement
dcb.fAbortOnError = True; // abort reads/writes on error
dcb.fDtrControl = DTR_CONTROL_DISABLE; // DTR flow control disable dcb.fRtsControl = RTS_CONTROL_DISABLE; // RTS flow control dcb.fDsrSensitivity = False; // DSR sensitivity disable
dcb.fOutX = False; // disable XON/XOFF out flow control dcb.fInX = False; // disable XON/XOFF in flow control
dcb.XonLim = 256; // transmit XON threshold dcb.XoffLim = 2048; // transmit XOFF threshold
dcb.XonChar = 0x7F; // Tx and Rx XON character dcb.XoffChar = 0x7F; // Tx and Rx XOFF character
dcb.EvtChar = 0x02; // received event character dcb.ErrorChar = 0x00; // error replacement character dcb.EofChar = 0x03; // end of input character
dcb.fTXContinueOnXoff = False; // XOFF continues Tx (????)
if( !SetCommState(hCOM, &dcb) ) { CloseHandle(hCOM); hCOM = INVALID_HANDLE_VALUE; return( -3); } } else { CloseHandle(hCOM); hCOM = INVALID_HANDLE_VALUE; return( -2); }//*2*
}//*1* else return( -1);
//--------------------------------------------------------------------- // Настройка тайм-аутов //---------------------------------------------------------------------
if( GetCommTimeouts(hCOM, &sTO) ) { sTO.ReadTotalTimeoutConstant = 250; sTO.ReadTotalTimeoutMultiplier = 3; sTO.ReadIntervalTimeout = 2; sTO.WriteTotalTimeoutConstant = 100; sTO.WriteTotalTimeoutMultiplier = 5;
if( !SetCommTimeouts( hCOM, &sTO ) ) { CloseHandle( hCOM ); hCOM = INVALID_HANDLE_VALUE; return( -4); } } else { CloseHandle(hCOM); hCOM = INVALID_HANDLE_VALUE; return( -4); }
PurgeComm(hCOM,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); ClearCommError(hCOM,&val,NULL);
return( 0 ); }//<<< End of InitComm() >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Ну а дальше через функции ReadFile и WriteFile. 1. Передача:
len = 5; fSucs = WriteFile( hCOM, &txbuf[0], len, &len, NULL );
if( !fSucs ) { Errors = CE_BREAK|CE_FRAME|CE_IOE|CE_MODE|CE_OVERRUN|CE_RXOVER|CE_RXPARITY|CE_TXFULL; ClearCommError(hCOM, &Errors, NULL); }
2. Прием:
len = 5; fSucs = ReadFile( hCOM, &rxbuf[0], len, &len, NULL );
if( fSucs && (len==5) ) { принято } else { сбросить ошибки как при передаче}
Количество принятых байт проверять желательно, так как иногда функция возвращает вроде все ОК, хотя считано 0 байтов. Что это за глюк не разбирался.
По переключению RTS. Автоматический вариант проходит - сам когда-то писал утилитку для заливки в кассу базы товаров по 485 интерфейсу. Долго мучался, но в конце-концов разобрался - хитрость там какая-то с настройками com-порта, давно это было, попрбую найти в архивах примерчик.
|
|
|
|
|
Apr 2 2007, 00:55
|
Группа: Новичок
Сообщений: 3
Регистрация: 1-04-07
Пользователь №: 26 691
|
Помогите плиз. Взялся за курсовик.Для начала надо написать прогу для работы с мобилой через com порт. Я в этом совсем не ничего не понимаю.Объясните новичку Скиньте кто что может.Буду очень благодарен
|
|
|
|
|
Jun 23 2007, 17:13
|
Группа: Новичок
Сообщений: 6
Регистрация: 22-03-07
Из: Пермь
Пользователь №: 26 413
|
Запоздало, но тем не менее..
Прикрепленные файлы
Serial.zip ( 136.29 килобайт )
Кол-во скачиваний: 280
|
|
|
|
|
Jul 1 2007, 11:15
|
специалист
Группа: Свой
Сообщений: 279
Регистрация: 3-05-07
Из: г. Москва
Пользователь №: 27 506
|
Я делал так в Visual Studio 2005: Инициализация: SerialPort system_port; system_port = new SerialPort(); system_port.PortName = "COM1"; system_port.BaudRate = 115200; system_port.DtrEnable = true; system_port.ReadBufferSize = 100000; system_port.DataReceived += new SerialDataReceivedEventHandler(system_port_DataReceived); system_port.Open(); system_port.DiscardOutBuffer(); system_port.DiscardInBuffer(); А далее по событию, которое вызывается, когда приходит байт в буфер COM-порта (объемом 100000 байт) пишете свою процедуру обработки принятых данных: void system_port_DataReceived(object sender, SerialDataReceivedEventArgs e) { byte newbyte; while (system_port.BytesToRead >=3) // К примеру, если пришло более трех байт { newbyte=(byte)system_port.ReadByte(); ...... // Тут пишем свою часть обработки принятых данных } } Передавать данные также просто: записываем в выходной буфер - и всё. Вот пример передачи 7-байтного пакета с хэшем data = new byte[7]; data[0] = 183; data[1] = 5; data[2] = 0xA0; data[3] = 0x01; data[4] = 0x01; data[5] = 0x00; data[6] = (byte)(data[1] ^ data[2] ^ data[3] ^ data[4]); system_port.Write(data, 0, data.Length); Всё общение использует только класс SerialPort. Преимущества такого решения в следующем: 1. Поддержка с Win98 (только dotNet 2.0 поставить надо) по WinXP и даже Vista. 2. Программа не занимает ресурсов ПК для постоянного опроса COM-порта. Пришел байт - сработало событие. Не пришел - можете выполнять любые другие действия. 3. Как следствие из пункта 2 программа может быть легко использована в многозадачном приложении. 4. Никаких драйверов писать не надо. Код максимально простой. Читаем MSDN как использовать SerialPort и всё. 5. Есть возможность устанавливать таймер на ожидание прихода данных, просто в данном примере он не использован. Недостаток - Windows не операционная система реального времени, а поэтому НЕТ четкого временного интервала, в течение которого будет передан байт в линию из выходного буфера COM-порта. Но на практике, я общался со скоростью 115200 и реальной информационной ёмкостью 72000 как в сторону ПК, так и в сторону железа - проблем не было, хотя параллельно работал Emule.
|
|
|
|
|
Aug 8 2007, 06:58
|
Участник
Группа: Новичок
Сообщений: 43
Регистрация: 7-07-05
Из: г.Магнитогорск
Пользователь №: 6 618
|
Подскажите как cport310 прицепить к Borland
|
|
|
|
|
Aug 28 2007, 13:25
|
Участник
Группа: Участник
Сообщений: 48
Регистрация: 29-11-06
Из: Екатеринбург
Пользователь №: 22 890
|
Судя по Вашей переписке - лето было боевое. Есть очень простое решение COM - Delphi + компонент Async32. http://www.tmssoftware.com/http://www.tmssoftware.com/ta32.htmDownloads Asynchronous serial communications made easy for your Delphi & C++Builder applications Вообще не нужно знать. Задать нужную скорость (константа) - максимум усилий. Работает везде, есть рабочий пример, если ваш контроллер выдаёт символы - их сразу увидите. На Delphi (если не пробывали) писать намного удобней чем на С (мне так кажется). Я правда из-за Async32 остался на Delphi 3 (кто-то ухмыльнётся), когда-то для более старших не получилось и руки не дошли, на сайте то есть, сейчас время жалко. Главное хочется уйти на USB, вот для этого нужен компонент. К стати компонент Delphi 3 есть сам исходный текст - я раз заглянул и мне хватило навсегда. Понял мне в калашный ряд не стоит... Такие вещи будут жить и потом. Иногда приходиться иметь дело с самоделками, хороши до времени. Пример с Win XP. С уважением badik
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|