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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Работа с COM-портом
CSB
сообщение Feb 2 2007, 17:11
Сообщение #1


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Тема не раз поднималась, но все таки остались вопросы.
Есть датчик, который посылает на ПК некие промежуточные результаты. На ПК все нормально принимается и обсчитывется конечный результат. Пакеты по 8 байт. Скорость UART 115200 kbps. Использую ReadFile() и CPort ( В CPort тоже используется ReadFile() ). Но как только частота передачи возрастает до 1000 посылок в секунду, то в винде начинатся проблемы: приходят неполные пакеты, часто приходит только заголовок пакета, а остальная часть нули или заголовок может оказаться в середине пакета. Увеличение приемного буфера в винде не решило проблемы. При отключении графики и прочего пакеты иногда принимаются нормально. Но без отображения результатов никак.

ЗЫ
В Terminal все принимается нормально - там есть возможность записать в лог принимаемые байты.
Пробовал DLPortIО, но так и не понял как подружить COM с этим драйвером.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Feb 3 2007, 00:37
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



А каким образом вызывается ReadFile()? По событию, таймеру, в отдельном потоке?


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 3 2007, 02:28
Сообщение #3


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



В потоке
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Feb 3 2007, 04:07
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



А portmonом его? Такое впечетление, что принимается оно правильно, а из буфера вынимается не в тот момент.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 3 2007, 12:24
Сообщение #5


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Дык, я ж говорю, что терминальной программой все нормально принимается (то что она несколько зависает, то ничего - главное все пакеты целые). Дело именно в моей программе =)

Этим читаю:
Код
procedure InComm1(var i:byte;var IsIn:boolean);
var
bytes1:dword;
begin
     IsIn:=false;
     clearcommerror(hcom1,com_error,@stat1);

   if stat1.cbInQue>0
   then
    begin
       if  readfile(hcom1,databuf1,bufsize1,bytes1,nil)
       then
        begin
         i:=databuf1;
         IsIn:=true;
        end
       else
        showmessage('Ошибка приема');
    end;

end;


Читаю просто вызовом функции в потоке.
(та же проблема остается при использовании CPort310)
Go to the top of the page
 
+Quote Post
lolikandr
сообщение Feb 3 2007, 12:45
Сообщение #6


Участник
*

Группа: Свой
Сообщений: 56
Регистрация: 25-06-05
Пользователь №: 6 300



ReadFile() вызывается в отдельном потоке по какому событию? При помощи SetCommMask или еще как?
PS: Пока писал, ответ появился. Почитайте что-нибудь типа такого:
http://www.delphimaster.ru/articles/comport2/index.html
Сразу скажу, что лучше Overlapped режим.
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 3 2007, 16:05
Сообщение #7


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Сегодня выяснилось, что и в Terminal приходят обрывки пакетов, реже чем в моей программе, но все-таки они есть. portmon показывает, что там приходят именно обрывки sad.gif Сейчас железо очередной раз перепроверяю. Попробую снизить скорость.

Блин, где же собака порылась ?

Сообщение отредактировал CSB - Feb 3 2007, 16:08
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Feb 3 2007, 22:25
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата(CSB @ Feb 3 2007, 16:05) *
Попробую снизить скорость

Скорость чего? Ваши 8 байт раз в 1мс только на 115200 и пролезут (если я математику не забыл)
Go to the top of the page
 
+Quote Post
_Sam_
сообщение Feb 3 2007, 22:38
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 278
Регистрация: 18-01-05
Из: Санкт-Петербург
Пользователь №: 2 031



Может в паузе между байтами или пакетами?
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 4 2007, 00:43
Сообщение #10


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Цитата
Скорость чего? Ваши 8 байт раз в 1мс только на 115200 и пролезут (если я математику не забыл)

Скорость передачи. Это тестовая задача, потому можно варьировать некоторыми параметрами. Просто буду снимать меньше показаний и все. Такое впечатление, что пакеты теряются по дороге к ПК, хотя если смотреть по JTAG'у, то все нормально.
Математика: 115200 kbps - это 11520 kBps (10 байт кадр). У меня получается 8 kBps. Поэтому остается некоторый запас.
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 4 2007, 00:53
Сообщение #11


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Цитата
Может в паузе между байтами или пакетами?
Не понял что вы имели в виду. (Паузы между пакетами разные - зависят от воздействия на датчик.)

Ну путь винда как-то отделяет во времени пакеты, но теряться-то при этом они не должны, т.к. входного буфера должно вполне хватать.
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Feb 4 2007, 01:33
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата(CSB @ Feb 4 2007, 00:43) *
Скорость передачи. ...

Я имел ввиду, что на 57600 уже не пролезет.

Цитата(CSB @ Feb 4 2007, 00:43) *
... (10 байт кадр). ...

Бит? т.е. без контроля - тока старт и стоп.

Обычно, хвосты теряются из-за ошибок передающей стороны - когда выдаете следующий байт не дождавшись "ухода" предыдущего в линию.
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 4 2007, 12:13
Сообщение #13


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Цитата
Бит? т.е. без контроля - тока старт и стоп.

угу, конечно бит.

Цитата
Обычно, хвосты теряются из-за ошибок передающей стороны - когда выдаете следующий байт не дождавшись "ухода" предыдущего в линию.

Следующий байт записываю в регистр передачи только по окончанию передачи предыдущего байта.
Go to the top of the page
 
+Quote Post
_Sam_
сообщение Feb 4 2007, 16:03
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 278
Регистрация: 18-01-05
Из: Санкт-Петербург
Пользователь №: 2 031



С байтами понятно вы их не затираете.
Между пакетами тоже у вас пауза выдерживается, но независмо от ПК насколько я понял.

Стартовый байт есть в пакете? Байт стаффинг или 9битный формат передачи для стартового байта используется?
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 4 2007, 18:24
Сообщение #15


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Пакет обрамлен стартовыми и оконечными байтами (при таком обрамлении пакета мне проще онадизировать целостность пакета). Формат передачи: 10 бит, стартовый бит + 8 бит данных + 1 стоп-бит. Все стандартно.
Go to the top of the page
 
+Quote Post
immelstorm
сообщение Feb 4 2007, 22:45
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 8-10-06
Пользователь №: 21 094



В принципе, можно попробовать работать с портом напрямую.
Я писал прогу, работающую как цифровой осциллограф, у меня получились следующие результаты:

Погрешность измерения временных интервалов:
На частоте до 1 кГц: не более 1%;
На частоте 1-10 кГц: не более 10%;
На частоте 10-50 кГц: не более 50%;

Вот кусок кода, отвечающий за доступ к порту:

//Маска битов для определения линии запуска
WaitMask:=$0;
if CTS_Start.Checked then WaitMask:=WaitMask or $10;
if DSR_Start.Checked then WaitMask:=WaitMask or $20;
if RI_Start.Checked then WaitMask:=WaitMask or $40;
if DCD_Start.Checked then WaitMask:=WaitMask or $80;

//Настройка порта
with SPort do begin
OpenDriver;
WriteByte(Base+3,$83);
WriteWord(Base,$0001);
WriteByte(Base+3,$3);
end;

HoldByte:=0;
WR:=SPort.ReadByte(Base+4);
SPort.WriteByte(Base+4,WR and $FC);
if HoldRTS.Checked then HoldByte:=HoldByte or $02;
if HoldDTR.Checked then HoldByte:=HoldByte or $01;

//Зарядка конденсатора, ожидание переходных процессов.
StartTimer.Enabled:=true;
While StartTimer.Enabled and (Aborted = false) do begin
//Держать сигналы
WR:=SPort.ReadByte(Base+4);
SPort.WriteByte(Base+4,WR or HoldByte);
Application.ProcessMessages;
end;

//Ожидание первого импульса.
D:=SPort.ReadByte(Base+6) and WaitMask;
//D1:=D and WaitMask;

repeat
Application.ProcessMessages;

WR:=SPort.ReadByte(Base+4);
SPort.WriteByte(Base+4,WR or HoldByte);

D1:=SPort.ReadByte(Base+6);
D1:=D1 and WaitMask;
until (D<>D1) or Aborted;

//Байт для удержания RTS и/или DTR
WR:=SPort.ReadByte(Base+4);
SPort.WriteByte(Base+4,WR or $02);

//Включение таймеров
HighResTimer1.Enabled:=true;
HighResTimer1.StartTimeMeasure;
STime:=GetTickCount;

while ((GetTickCount-STime)<MeasureTime) and (not Aborted) do begin
//RTS / DTR
SPort.WriteByte(Base+4,WR);
//Сигналы
D:=SPort.ReadByte(Base+6);
if D<>D1 then begin
HighResTimer1.StopTimeMeasure;
Time:=HighResTimer1.GetTimeDifference;
HighResTimer1.StartTimeMeasure;
SetLength(Data, I+1);
Data[I,0]:=Time+Data[I-1,0];
Data[I,1]:=D;
D1:=D;
Inc(I);
end;
end;

EndTime:=GetTickCount;

HighResTimer1.StopTimeMeasure;


Разумеется, нужно знать спецификации UART.
Сразу предупреждаю: в windows работа с железками в реальном времени возможна только из RING 0. Всё остальное - разные степени приближения.


--------------------
Go to the top of the page
 
+Quote Post
_Sam_
сообщение Feb 5 2007, 23:53
Сообщение #17


Местный
***

Группа: Свой
Сообщений: 278
Регистрация: 18-01-05
Из: Санкт-Петербург
Пользователь №: 2 031



Цитата
Пакет обрамлен стартовыми и оконечными байтами (при таком обрамлении пакета мне проще онадизировать целостность пакета). Формат передачи: 10 бит, стартовый бит + 8 бит данных + 1 стоп-бит. Все стандартно.

1.Байт стаффинг используется? Что например получится если один из неадресных байтов будет таким же как адресный?
2.Вы говорили что пакеты неполные получаете => целостность пакетов нарушена. Если п.1 не поможет попробуйте оставить всё как есть, но передавать из железяки всё время одинаковый пакет типа
s 1 2 3 4 5 e, где s, e стартовый и стоповый байты, а цифирки - значения передаваемых байтов. Может локализуете проблему.
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 6 2007, 09:32
Сообщение #18


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Байт стаффинг не используется: пакет-то обрамлен с двух сторон и имеет фиксированную длину, поэтому отличать адресный байт от неадресного просто.

Цитата
2.Вы говорили что пакеты неполные получаете => целостность пакетов нарушена. Если п.1 не поможет попробуйте оставить всё как есть, но передавать из железяки всё время одинаковый пакет типа
s 1 2 3 4 5 e, где s, e стартовый и стоповый байты, а цифирки - значения передаваемых байтов. Может локализуете проблему.
Передавал и смотрел в железяку JTAG'ом - отправлялось все нормально. Кабель для связи - экранированный.
Go to the top of the page
 
+Quote Post
lolikandr
сообщение Feb 6 2007, 09:52
Сообщение #19


Участник
*

Группа: Свой
Сообщений: 56
Регистрация: 25-06-05
Пользователь №: 6 300



Была такая же бага (потери кусков данных), когда читал просто в цикле по такому же принципу:
Код
if stat1.cbInQue>0  then

И тоже терминальной программой все нормально принималось.
Только, когда использовал компонент TComm от AsyncPro и событие OnRxChar, получил все данные без потерь от непрерывного потока на обычном COM-порту при скорости 115200.
На том же компоненте удалось получать данные и при скорости 921600 на виртуальном COM-порту от FTDI.
По поводу проверки железа - Rx и Tx закорачивается в конце кабеля. Пишется микрокусок программы (а то и отдельная микропрограмма) на передачу-прием-контроль. Сразу видно, что не так. Для виндовс программы тоже желательно провести такую процедуру, чтобы быть увереным в своей программе.
Go to the top of the page
 
+Quote Post
Joy
сообщение Feb 6 2007, 10:44
Сообщение #20


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

Группа: Свой
Сообщений: 89
Регистрация: 28-10-05
Из: Киев
Пользователь №: 10 227



Цитата(CSB @ Feb 2 2007, 16:11) *
Тема не раз поднималась, но все таки остались вопросы.
Есть датчик, который посылает на ПК некие промежуточные результаты. На ПК все нормально принимается и обсчитывется конечный результат. Пакеты по 8 байт. Скорость UART 115200 kbps. Использую ReadFile() и CPort ( В CPort тоже используется ReadFile() ). Но как только частота передачи возрастает до 1000 посылок в секунду, то в винде начинатся проблемы: приходят неполные пакеты, часто приходит только заголовок пакета, а остальная часть нули или заголовок может оказаться в середине пакета. Увеличение приемного буфера в винде не решило проблемы. При отключении графики и прочего пакеты иногда принимаются нормально. Но без отображения результатов никак.

ЗЫ
В Terminal все принимается нормально - там есть возможность записать в лог принимаемые байты.
Пробовал DLPortIО, но так и не понял как подружить COM с этим драйвером.

была похожая проблемма: никак не удавалось получить полный пакет. решил с помощью побайтового приема (ReadFile() в цикле принимает один байт, который потом складывается в буфер)
Go to the top of the page
 
+Quote Post
CSB
сообщение Feb 6 2007, 16:25
Сообщение #21


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

Группа: Новичок
Сообщений: 100
Регистрация: 9-03-06
Пользователь №: 15 088



Цитата
терминальной программой все нормально принималось.

Повторюсь: проблема была выявлена и при работе с терминалом.

Цитата
решил с помощью побайтового приема

По-байтовый прием и делаю.

Тут на форуме читал, что ReadFile() весьма медленная функция и нужно писать свой драйвер или юзать что-то типа DriverLINX Port IO. Но DriverLINX Port IO пока так и не смог прикрутить к СОМ-порту.
Go to the top of the page
 
+Quote Post
_Sam_
сообщение Feb 6 2007, 20:39
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 278
Регистрация: 18-01-05
Из: Санкт-Петербург
Пользователь №: 2 031



Цитата
Тут на форуме читал, что ReadFile() весьма медленная функция и нужно писать свой драйвер

Ну хз. Ни в Win98 ни в WinXP подобной проблемы у меня не было, хотя пакеты имели бо'льший размер!
ReadFile должна возвращать количество принятых байт, возвращает 8? Было бы неплохо посмотреть код настройки ком порта.
Go to the top of the page
 
+Quote Post
AndrewKirs
сообщение Feb 9 2007, 17:41
Сообщение #23


Участник
*

Группа: Свой
Сообщений: 63
Регистрация: 5-05-06
Пользователь №: 16 804



По-моему, надо использовать асинхронный режим IO (CreateFile с флагом OVERLAPPED), и буфер достаточно большого размера (ну хоть несколько Кб).
Go to the top of the page
 
+Quote Post
Georgy
сообщение Feb 23 2007, 02:08
Сообщение #24


Уставать стал
****

Группа: Свой
Сообщений: 603
Регистрация: 11-07-05
Из: Севастополь
Пользователь №: 6 692



А ни слова про длительность и амплитуду импульсов.
Проверьтесь - было дело, бодался с таким явлением, оптопара H11Ll1 уродовала длительность. После подбора тока диода сбои истребились.
Удачи!


--------------------
Коллектив-Большая Сила!
Go to the top of the page
 
+Quote Post
amw
сообщение Feb 26 2007, 19:15
Сообщение #25


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 22-09-05
Из: Kharkov
Пользователь №: 8 847



Убедится в наличии паузы по сигналу Rx между пакетами.
Установить ПРАВИЛЬНО таймауты - SetCommTimeouts()
Проверят количество принятых байт после ReadFile()


--------------------
- А мораль отсюда такова: всякому овощу свое время. Или, хочешь, я это сформулирую попроще: никогда не думай, что ты иная, чем могла бы быть иначе, чем будучи иной в тех случаях, когда иначе нельзя не быть.
© Lewis Carroll. Alice's adventures in wonderland.
Go to the top of the page
 
+Quote Post

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

 


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


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