1. Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
  2. Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
  3. Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
  4. За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
  5. Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
  6. Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
  7. Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.

Работа с двумя платами TE1-PCI от Элкус

PLC, прочие контроллеры, промышленные компьютеры, операторские панели
Ответить

Автор темы
UlrichVonRekkenin
новенький
новенький
Сообщения: 1
Зарегистрирован: 22 май 2012, 22:27
Имя: Лебедев Олг Владимирович
Страна: Россия
город/регион: СПб

Работа с двумя платами TE1-PCI от Элкус

Сообщение UlrichVonRekkenin »

Добрый день!

Начал работать с платой сопряжения по мультиплексному каналу TE1-PCI от фирмы Элкус.
У меня две платы вставлены в PCI слоты одного компьютера.
Используется 32-битная ОС Windows 7.
Собирается исполняемый файл в Borland Develper Studio 2006 - Borland® C++Builder® Preview for Microsoft® Windows™ Version 10.0.2151.25345.
Драйвер ELCUS ELECTRONIC CO (дата разработки 10.02.2006).

У меня проблема с обменом сообщений между двумя платами,
одна из которых контроллер канала=КК, а другая - оконечное устройство=ОУ.

В функции main приводится код, который я использую.
Размерность передаваемых массивов выбирается как SZ=32.
Во первых, функции bcputblk, bcgetblk отрабатывают таким образом,
что массивы записываются не совсем правильно.

А именно (я попутно смотрю базу с помощью tmk.exe -- тестовой программе для просмотра отдельных слов сообщения и другой детальной информации; устройство может работать в ней и как КК и ОУ).

Во-первых,
при обределении USE_BLK=NO , USE_BCSTARTX=NO , USE_MODE=NO
в этом случае всякий массив (произвольной длины от 1..32 слов) прекрасно передается в обоих направлениях, все работает прекрасно. Но тот же самый эффект должен достигаться и при использовании функций из семейства bcputblk\\bcgetblk (об этом далее). Эти конструкции описаны в примерах. Но в примерах кода слишкоом много кода, который на данном этапе мне не нужен (там производится обработка прерываний, ожиданий и обработка ситуации "обонент занят").

Во-вторых,
при обределении USE_BLK=YES , USE_BCSTARTX=NO , USE_MODE=NO
передается в обоих направлениях (связка КК-ОУ и обратно ОУ-КК) только первая половина массива. Остальная часть (ту которую вернули Оу-КК) заполнена нулями.

В-третьих,
при обределении USE_BLK=YES , USE_BCSTARTX=NO , USE_MODE=YES
возможно, (для п.2) причина неправильного "поведения" в режиме работы ОУ... Попробовал установить//поменять режим rtdefmode - включил флаговый режим и работу с аппаратным битом. В результате получил мусор... Первая половина возвращенного массива сдвинута <<4 и смещена на 1 адрес//элемент.

В-четвертых,
при обределении USE_BLK=NO , USE_BCSTARTX=NO , USE_MODE=YES
в этом случае передается почти правильно, но элементы сдвинуты на 1. Из-за этого сравнение не проходит.

Если кто-то работал с этими платами или знает в чем я ошибаюсь -
буду признателен.

С уважением, Олег Л.

Код: Выделить всё

#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#include "wdmtmkv2.cpp"
//=======================================================
void lastOne()
{
const short SZ = 32,
            Base = 1,
            rtAddr = 0x1B, /*27*/
            rtSubAddr = 0x1E;    /*30*/
int awBuf[SZ], back[SZ], bcBack[SZ], foo[SZ];
int KS, OS, size, i;
TTmkEventData tmkEvD;

#define YES 1
#define NO 0
#define USE_BLK YES // первый в сигнатуре.
#define USE_BCSTARTX NO  // 2-й в сигнатуре.
#define USE_MODE YES  // 3-й в сигнатуре.
#define FLAG_MODE NO
#define RESIZE_SZ NO

#if RESIZE_SZ==YES
  size = 2 * SZ;
#else
  size = 1 * SZ;
#endif


for (register int i=0; i<size; i++)
  {
  awBuf[i] = (rtSubAddr<<2) | i & 0x1F ;
  back[i] = bcBack[i] = 0;
  }

TmkOpen();

// Подготовить 0-плату в режиме КК.
if (tmkconfig(0))
{
  printf("tmkconfig(0) error\n");
}
  bcreset();
  bcdefbase(Base);


// Подготовить 1-плату в режиме ОУ.
if (tmkconfig(1))
{
  printf("tmkconfig(1) error\n");
}
  rtreset();
  rtdefaddress(rtAddr);
#if USE_MODE==YES
  int rtMode = rtgetmode();
  if (rtdefmode(rtMode
#if FLAG_MODE==YES
  |RT_FLAG_MODE
#endif
  |RT_HBIT_MODE)) std::cout << "\nThere is an error with rtdefmode.\n";
  rtMode = rtgetmode();
#endif
  rtdefsubaddr(RT_TRANSMIT, rtSubAddr);
  rtclrflag();
  rtdefsubaddr(RT_RECEIVE, rtSubAddr);
  rtclrflag();


//{-> Подготовка сообщения.
tmkselect(0);
  KS = CW(rtAddr, RT_RECEIVE, rtSubAddr, size);
  bcputw(0, KS);

#if USE_BLK==YES
  bcputblk(1, awBuf, size); Sleep(200);
#else
  for (i=0; i<SZ; i++) bcputw(i+1, awBuf[i]); Sleep(200);
#endif
//<-}


//{-> Отправка через МКИО сообщения.
#if USE_BCSTARTX==YES
  bcstartx(Base, DATA_BC_RT | CX_STOP | CX_BUS_A | CX_NOSIG); Sleep(200);
#else
  bcstart(Base, DATA_BC_RT); Sleep(200);
#endif
  tmkgetevd(&tmkEvD);
//<-}


//{-> Перезапись информационных слов из п\адреса приема
//    в подадрес передачи.
tmkselect(1);
#if USE_BLK==YES
  rtgetblk(0, back, size);
#else
  for (i=0; i<SZ; i++) back[i]=rtgetw(i); Sleep(200);
#endif

  rtdefsubaddr(RT_TRANSMIT, rtSubAddr);
#if USE_BLK==YES
  rtputblk(0, back, size);
#else
  for (i=0; i<SZ; i++) rtputw(i, back[i]); Sleep(200);
#endif
//<-}



//{-> Запрос подготовленного сообщения из ОУ.
tmkselect(0);
  KS = CW(rtAddr, RT_TRANSMIT, rtSubAddr, size);
  bcputw(0, KS); Sleep(200);
  #if USE_BCSTARTX==YES
    bcstartx(Base, DATA_RT_BC | CX_STOP | CX_BUS_A | CX_NOSIG); Sleep(200);
  #else
    bcstart(Base, DATA_RT_BC); Sleep(200);
  #endif
//<-}


//{-> Подготовка полученного массива для сравнения с исходным.
#if USE_BLK==YES
  bcgetblk(2, bcBack, size);
#else
  for (i=0; i<SZ; i++) bcBack[i]=bcgetw(i+2); Sleep(200);
#endif
  showMassiveAndCheck(SZ, awBuf, bcBack);
//<-}


#undef YES
#undef NO
#undef USE_BLK
#undef USE_BCSTARTX
#undef USE_MODE
return;
}

Код: Выделить всё

bool showMassiveAndCheck(int sz, int mas1[], int mas2[])
{
// Compare two massive. If they are same it returns true.
bool hasError;

hasError = false;

printf("\n\n\t\tPlata-0 \t Plata-1\n");
for (register int j=0; j<sz; j++)
  {
  if (mas1[j]!=mas2[j])
    {
    printf("i= %2d :\t\t0x%X \t\t 0x%X \t(bad)\n", j, mas1[j], mas2[j]);
    hasError = true;
    }
  else
    {
    printf("i= %2d :\t\t0x%X \t\t 0x%X \n", j, mas1[j], mas2[j]);
    }
  }

if (!hasError) printf("All is good. The massives are same!!!\n\n");
return (hasError);
}

Naska_igorevna
новенький
новенький
Сообщения: 1
Зарегистрирован: 26 июл 2021, 15:42
Имя: Анастасия
Страна: Россия

Работа с двумя платами TE1-PCI от Элкус

Сообщение Naska_igorevna »

Здравствуйте, знаю, что прошло много лет, скажите пожалуйста, Вы разобрались, в чем была ошибка?
Ответить

Вернуться в «Средний уровень автоматизации (управляющий)»