Современные технологии автоматизации» («СТА») —  журнал для квалифицированных специалистов по промышленной автоматизации Форум СТА — современные технологии автоматизации Домашняя страница
Домашняя страница форума CTA Домашняя страница форума CTA > II. АСУТП и SCADA > Программное обеспечение
  Активные темы Активные темы
  FAQ FAQ  Искать в форуме   Зарегистрироваться Зарегистрироваться  Вход в систему Вход в систему

5510E/TCP - потери при передаче через RS232

 Ответить Ответить Страница  12>
Автор
Сообщение
Марат Смотреть выпадающим
Новичок
Новичок


Присоединился: 02 Февраль 2011
Online Status: Offline
Публикации: 25
Свойства публикации Свойства публикации   Ответить, цитируя автора - Марат Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Тема сообщения: 5510E/TCP - потери при передаче через RS232
    Опубликовано: 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
Свойства публикации Свойства публикации   Ответить, цитируя автора - Александр Горский Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 16 Март 2011 14:04

А с какой периодичностью производится посылка буфера?

Наверх
Марат Смотреть выпадающим
Новичок
Новичок


Присоединился: 02 Февраль 2011
Online Status: Offline
Публикации: 25
Свойства публикации Свойства публикации   Ответить, цитируя автора - Марат Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 16 Март 2011 14:42

хм... даже не знаю как ответить.

// 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
Свойства публикации Свойства публикации   Ответить, цитируя автора - Александр Горский Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 16 Март 2011 16:16

Возможно тут и ответ. Контроллер обмена еще не завершил передачу буфера, а ему идут уже новые данные.

На большой скорости передача буфера успевает завершиться и проблем у вас нет.
На малой скорости обмена - не успевает.
Поробуйте, как вариант, в цикле передачи добавить какую нибудь задержку после каждой посылки.
 
for(i=0;i<4096;i++)  
{
com_tx(buf) ;
вот_здесь;
}
Наверх
poison Смотреть выпадающим
Участник
Участник
Аватар

Присоединился: 02 Декабрь 2010
Online Status: Offline
Публикации: 68
Свойства публикации Свойства публикации   Ответить, цитируя автора - poison Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 17 Март 2011 09:06
Добрый день!
Насколько я знаю, есть альтернатива функции 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);
}


Наверх
poison Смотреть выпадающим
Участник
Участник
Аватар

Присоединился: 02 Декабрь 2010
Online Status: Offline
Публикации: 68
Свойства публикации Свойства публикации   Ответить, цитируя автора - poison Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 17 Март 2011 09:31
Насчет функции которую вы используете. У вас происходит переполнение аппаратного буфера который размером 16 байт, ваша ошибка вы слишком быстро отправляете информацию. Вам нужно производить анализ состояния аппаратного буфере или делать задержку после передачи 16 байт информации.
Кстати посмотрите здесь как реализовывается передача
http://forum.cta.ru/forum_posts.asp?TID=3919 
Наверх
Марат Смотреть выпадающим
Новичок
Новичок


Присоединился: 02 Февраль 2011
Online Status: Offline
Публикации: 25
Свойства публикации Свойства публикации   Ответить, цитируя автора - Марат Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 17 Март 2011 10:13

хм, понятно, что происходит переполнение. И понятно, что не успевает. 

Вопрос - как это победить? как определить, что буфер полон и нужно ждать?

из описания:

/***

com_tx
Syntax:
void com_tx(char c)
Description:
com_tx() sends a single character by waiting until the transmit buffer
isn’t full
, then putting the character into it. The interrupt driver will
then send the character once it is at the head of the transmit queue
and a transmit interrupt occurs.
Parameter Description
c The value you would like to send.

***/

я пробовал ставить пустую команду после посылки каждого байта {asm nop;} и даже { for (x=0;x<500;x++) asm nop; } но все равно есть потери, на скорости 1200 baud (для теста) количество nop-ов чтоб посылалось без потерь  достигало 5000... И все равно это как-то стремно.... и неправильно...

проверка com_tx_empty() перед посылкой, кстати, тоже не помогла. Да что говорить - если не в лом - просто попробуйте сами. Вдруг это только у меня такой косяк? 


Наверх
Марат Смотреть выпадающим
Новичок
Новичок


Присоединился: 02 Февраль 2011
Online Status: Offline
Публикации: 25
Свойства публикации Свойства публикации   Ответить, цитируя автора - Марат Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 17 Март 2011 10:29
про новые функции... попробую :-) потом расскажу.
Наверх
poison Смотреть выпадающим
Участник
Участник
Аватар

Присоединился: 02 Декабрь 2010
Online Status: Offline
Публикации: 68
Свойства публикации Свойства публикации   Ответить, цитируя автора - poison Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 17 Март 2011 12:55
Попробовал я у себя ваш код, да верно есть пропуски в передачи даже проверка 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
Свойства публикации Свойства публикации   Ответить, цитируя автора - Марат Ответить, цитируя автора -  ОтветитьОтвет Прямая ссылка на эту публикацию Опубликовано: 17 Март 2011 14:23

Да!

Теперь все нормально передается, даже без вынужденных задержек :)

Это верное решение :))))    И еще маленький вопросик: я правильно понимаю, что если использовать другой порт просто меняем базовый адрес, например COM2 == 0x02F8, COM4 = 0x02E8  ?

И можно ли это применять, если поставить в COM-порты режим 485 ? /* просто я еще пока не могу попробовать с 485, плата сгорела :( */

P.S. Видимо косяки с передачей данных на DK8070 (см.ранее) тоже изза этого...

Наверх
 Ответить Ответить Страница  12>

Переход на форум Права доступа на форуме Смотреть выпадающим

Bulletin Board Software by Web Wiz Forums® version 9.64
Powered by Web Wiz Forums Free Express Edition
Copyright ©2001-2009 Web Wiz