5510E/TCP - потери при передаче через RS232 |
Ответить | Страница 12> |
Автор | |
Новичок Присоединился: 02 Февраль 2011 Online Status: Offline Публикации: 25 |
Опубликовано: 16 Март 2011 12:27 |
почему то не достоверно передаются данные, если их посылать из ADAM в PC по RS232 COM1? при передаче более 16 байт происходят потери. Как пример, считываю из файла символы ('1','2','3','4'...) в массив, потом массив передаю как com_tx(buf[i]) на PC на приемe запущен HyperTerminal - он получает символы 123456789012345679013579... то есть получаем какбы пропуски (а все должно идти по порядку). Я не понимаю, почему так получается, но первые 16 байт _всегда_ нормально приходят, а пропуски зависят от скорости порта (чем выше скорость, тем больше передается байт без пропусков, чем ниже скорость, тем быстрее начинают случаться пропуски) Это только у меня так или у кого-то такое было? ... Пока я решил этот вопрос изменением протокола обмена (по 16 байт макс передаю), но не думаю, что это правильно.... |
|
Действительный член Присоединился: 04 Сентябрь 2006 Категория: Russian Federation Online Status: Offline Публикации: 206 |
|
А с какой периодичностью производится посылка буфера? |
|
Новичок Присоединился: 02 Февраль 2011 Online Status: Offline Публикации: 25 |
|
хм... даже не знаю как ответить. // block for transmit { int i; char buf[4096]; // создаем буфер for(i=0;i<4096;i++) buf[i] = '0'+ i%9; // чтоб было '0','1','2',... '9','0','1','2' ... for(i=0;i<4096;i++) com_tx(buf[i]); } как я понимаю, com_tx дожидается освобождения очереди посылки и пихает байт (rtfm). и.... если после посылки каждого байти вставить adv_printf("послали %c\n",buf[i]); то пропусков в передаче (или на PC-приеме) нет... все ок. |
|
Действительный член Присоединился: 04 Сентябрь 2006 Категория: Russian Federation Online Status: Offline Публикации: 206 |
|
Возможно тут и ответ. Контроллер обмена еще не завершил передачу буфера, а ему идут уже новые данные. На большой скорости передача буфера успевает завершиться и проблем у вас нет.
На малой скорости обмена - не успевает.
Поробуйте, как вариант, в цикле передачи добавить какую нибудь задержку после каждой посылки.
for(i=0;i<4096;i++)
{
com_tx(buf) ;
вот_здесь;
}
|
|
Участник Присоединился: 02 Декабрь 2010 Online Status: Offline Публикации: 68 |
|
Добрый день!
Насколько я знаю, есть альтернатива функции com_tx(buf); Попробуйте более новые функции: #include "5510drv.h" void main(void) { char sendcmd[30] = {‘1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’0’, ‘1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’0’, ‘1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,’0’,}; SIO_Open(COM1); SIO_SetState(COM1, (unsigned long)9600, NO_PARITY, DATA8, STOP1); SIO_SendBytes(COM1, 30, sendcmd); SIO_Close(COM1); } |
|
Участник Присоединился: 02 Декабрь 2010 Online Status: Offline Публикации: 68 |
|
Насчет функции которую вы используете. У вас происходит переполнение аппаратного буфера который размером 16 байт, ваша ошибка вы слишком быстро отправляете информацию. Вам нужно производить анализ состояния аппаратного буфере или делать задержку после передачи 16 байт информации.
Кстати посмотрите здесь как реализовывается передача http://forum.cta.ru/forum_posts.asp?TID=3919 |
|
Новичок Присоединился: 02 Февраль 2011 Online Status: Offline Публикации: 25 |
|
хм, понятно, что происходит переполнение. И понятно, что не успевает. Вопрос - как это победить? как определить, что буфер полон и нужно ждать? из описания: /*** com_tx ***/ я пробовал ставить пустую команду после посылки каждого байта {asm nop;} и даже { for (x=0;x<500;x++) asm nop; } но все равно есть потери, на скорости 1200 baud (для теста) количество nop-ов чтоб посылалось без потерь достигало 5000... И все равно это как-то стремно.... и неправильно... проверка com_tx_empty() перед посылкой, кстати, тоже не помогла. Да что говорить - если не в лом - просто попробуйте сами. Вдруг это только у меня такой косяк? |
|
Новичок Присоединился: 02 Февраль 2011 Online Status: Offline Публикации: 25 |
|
про новые функции... попробую :-) потом расскажу.
|
|
Участник Присоединился: 02 Декабрь 2010 Online Status: Offline Публикации: 68 |
|
Попробовал я у себя ваш код, да верно есть пропуски в передачи даже проверка com_tx_empty() перед посылкой не помогает. Пришлось дизассемблировать библиотеку comm.lib, косяк есть в этом куске программы (функция com_general_tx).
_TEXT:04AA inc _tx_num _TEXT:04AE ; #line 884 _TEXT:04AE sti _TEXT:04AF ; #line 886 _TEXT:04AF dec _tx_num ИМХО библиотека comm.lib сделана очень паршива, куча старых ненужных косячных функций, которые компилятся вместе с проектом, в итоге размер файла получается слишком большой и многие пользователи используют косячные функции в место более новых. Вот исправленная программа 100% рабочая с использованием косячной функции: #include "5510drv.h" void main(void) { com_install(1); // COM1 в ADAM идет через 0-модем на COM2 PC com_set_format(8,0,1); // 8N1 com_set_speed((unsigned long)9600); int i; char buf[4096]; // создаем буфер for(i=0;i<4096;i++) buf[i] = '0'+ i%10; // чтоб было '0','1','2',... '9','0','1','2' ... for(i=0;i<4096;i++) { while ((inportb (0x03F8 + 5) & 0x20) == 0) ;//аппаратный анализ свободы буффера для com1 регистр lsr com_tx(buf[i]); } com_tx_string("FINISH"); com_deinstall(); } |
|
Новичок Присоединился: 02 Февраль 2011 Online Status: Offline Публикации: 25 |
|
Да! Теперь все нормально передается, даже без вынужденных задержек :) Это верное решение :)))) И еще маленький вопросик: я правильно понимаю, что если использовать другой порт просто меняем базовый адрес, например COM2 == 0x02F8, COM4 = 0x02E8 ? И можно ли это применять, если поставить в COM-порты режим 485 ? /* просто я еще пока не могу попробовать с 485, плата сгорела :( */ P.S. Видимо косяки с передачей данных на DK8070 (см.ранее) тоже изза этого... |
|
Ответить | Страница 12> |
Переход на форум | Права доступа на форуме Вы не можете публиковать новые темы в этом форуме Вы не можете отвечать на сообщения в этом форуме Вы не можете удалять Ваши сообщения на этом форуме Вы не можете редактировать Ваши сообщения на этом форуме Вы не можете создавать голосования на этом форуме Вы не можете выражать своё мнение в голосованиях на этом форуме |