Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Теряются биты при обмене через СОМ-порт


Автор: 3EHbKA 19.11.2004, 23:03
Здравствуйте, многоуважаемые.

Возникла у меня непонятная мне проблема:
Есть устройство, которое передает и принимает информацию, подлючено она к СОМ-порту.
Я написал прием, все работат нормально.
Одноко при передаче ИНОГДА возникает такая непонятная ошибка:

Отправляю: 00000 01010 11101 00100 11011 11100 01100 11000
0 A 1D 4 1B 1C C 18

приходит 0000 0101 1110 0010 1101 1110 0110 1100 11111
0 5 E 2 D E 6 C 1F

т.е. приходит на 1 байт больше, а в предыдущих теряется 1 бит.
Самое странное в том, что это динамическая ошибка и возникает примерно в 30% случаях. Никакой закономерности ее возникновения я не заметил. Может 10 раз выполниться без ошибки, а потом 3 раза с ошибкой, может чередоваться.

Пишу в порт просто:

Код

WriteFile(CommHandle, strg[1], Length(strg), KolByte, @Ovr);


Настройки порта:
Код


  GetCommState(CommHandle,DCB);
  DCB.BaudRate:=100;
  DCB.Parity:=NOPARITY;
  DCB.ByteSize:=7;
  DCB.StopBits:=ONESTOPBIT;
  DCB.Flags:=RTS_CONTROL_ENABLE;
  EscapeCommFunction(CommHandle,SETDTR);


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

Автор: maxim1000 20.11.2004, 00:30
вот одна из возможных причин:
частота, на которой работает COM-порт, получается делением одной и той же частоты на разные делители
это приводит к тому, что реальная частота не так-то и часто совпадает с "заказанной"
если посмотреть спецификацию протокола UART, можно заметить, что для корректной работы необходимо, чтобы частоты устройств отличались не более, чем на 10% (если учесть наличие переходных процессов, условие, наверное, будет еще более жестким)
гипотеза такая: ПК не может обеспечить частоту 100 с нужной точностью
это легко проверить с помощью осциллографа...

Автор: 3EHbKA 20.11.2004, 10:42
Про частоту устройств я знаю, только читал, что отличие должно быть не более 5% на малых скоростях (у меня 100 бод), но это не суть важно.
Дело в том, что с этим же устройством работает программа, написаная на асме, работает нормально без сбоев!
Я пробовал менять частоту от 98 до 110 при скорости отличной от 100 прием/передача дополняется другими ошибками: пропадают и появляются другие биты, например отсылаю 0000111, а приходит 0000110.
А с помощью асцилографа обязательно проверю, как только найду его.

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

Автор: maxim1000 20.11.2004, 11:44
очень странно... UART не располагает к появлению лишних битов...
а как с временными промежутками между последовательными пакетами? (будет ли ошибка, если их увеличить)
еще неплохо бы попробовать передавать все время одно и то же значение (возможно, ошибка станет чуть-чуть понятнее)
Цитата
Дело в том, что с этим же устройством работает программа, написаная на асме, работает нормально без сбоев!

тогда нужно смотреть, чем отличается механизм работы с COM-портом в двух программах

Автор: 3EHbKA 20.11.2004, 13:35
Дело в том, что биты не появляются, а пропадает 1 бит, а вот появляется дополнительный байт.
Устройство подключено через адаптер:
http://www.kvant.ru/1.jpg
Что Вы имеете в виду под "одним и тем же значением"? Всегда передавать один и тот же символ? К примеру я передаю 0001111, а принимается 000111, т.е. пропал последний бит.

Автор: p0s0l 20.11.2004, 14:20
Я этим никогда не занимался... Поэтому только спрошу (возможно очень глупые вопросы smile, но хоть знать буду ):
Может SetCommState забыл ? smile
Что значит DCB.ByteSize:=7 ? Почему не 8 ? Может из-за этого "съедается" 1 бит (младший или старший в байте...) ?
В примере передаются куски по 5 бит. А в памяти хранится байтами по 8 бит... При передаче "обрезаются" 3 бита в каждом байте или как ? И как ты узнаешь, что получило устройство ?

Автор: 3EHbKA 20.11.2004, 15:55
1. SetCommState я не забыл, просто скопировал на одну строчку меньше, а на сайте у меня глюк какой-то со скриптами, поэтому не могу изменить.

2. DCB.ByteSize:=7 потому что принимается 7 битное слово, а значемые только 5, почему так я не знаю, не я устройство делал. Принимаю я все без проблем, а вот с отправкой проблеммы, делаю все по аналогии - записываю 5 бит, остальные не трогаю.

3. У устройства есть такая возможность - смотреть полученную информацию.

Автор: DonPager 20.11.2004, 16:47
возможно ты "перегоняешь устройство" попробуй делать перед отправкой каждого байта задержку исходя из скорости передачи (для 19200 - 1024микросекунд(!), 38400 - 512 )- в общем определи экспереиментально

Автор: maxim1000 20.11.2004, 16:55
можно попробовать определить зависимость ошибки от передаваемого значения, когда четко ясно, когда появляется ошибка, уже можно что-то думать...
еще при просмотре переданных и принятых данных у меня появилось ощущение, что неплохо бы попробовать разное количество стартовых бит...

Автор: 3EHbKA 20.11.2004, 18:07
Задержку делать тоже пробовал, только не по Вашей формуле, а наобум, ничего не получилось.
При установке зедержли в 196608 микросекунд = 196 милесекунд тоже ничего не выходит.

Автор: 3EHbKA 20.11.2004, 19:25
to maxim1000:
в том то и проблема, что нет какой-то закономерности появления ошибки, ошибки появляются непонятно из-за чего. Шлю одно и тоже примерно через равные промежутки времени(шлю в ручную путем нажатия на кнопку). Причем нет какой закономерности шлю я сразу после ответа или же через 20-30 секунд.
Цитата
еще при просмотре переданных и принятых данных у меня появилось ощущение, что неплохо бы попробовать разное количество стартовых бит...

Вы наверное имели в виду стоповые биты?

УРАААААААААА!!!!
Пока писал этописьмо эксперементировал с задержками, количеством стоповых битов, длиной слова... и О ЧУДО!!! Все заработало!!!

Дело было вот в чем:
т.к. у меня нет никакой документации по этому девайсу прием и передачу приходилось писать в слепую! Начинал писать с приема. Т.к. получилось с 7 битами и 1 стопом я решил, что так все и работает. НО сейчас попробовал 6 бит и 2 стоповых и все заработало!!!
Непонятно лишь одно. Почему ошибка у меня была динамическая. Но это уже не важно, главное что истина обнаружена!!! Надо это отметить. Пойду за винцом сгоняю.

ВСЕМ ОГРОМНОЕ СПАСИБО ЗА ПОМОЩЬ В ЭТОМ НЕ ЛЕГКОМ ДЕЛЕ.
ДАЖЕ НЕ ЗНАЮ КАК ВЫРАЗИТЬ ВАМ СВОЮ БЛАГОДАРНОСТЬ.
БОЛЬШОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)