Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATTiny2313 + DS1990 и его имитатор в виде считывателя карт
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
TamTam
Товариши приключилась сия трабла собрал девайс которы по считыванию DS1990 счелкает релюшкой, стало интересно купил Перковский считыватель PERCo-RP-15MW так как он может имулировать DS1990 с надеждой на то что когда я его подключу то он считает ключь с карты и передаст его по 1-wire но этого так и не произошло, хотя попытка попасть в прирывание по спадающему фронту проходит, но данные не передаються. подскажите в чем может быть косяк? Пишу в CVAVR 1.25.3 использую стандартную функцию поиска из стандартной библы.
PDF от читывателя, ВНИМАНИЕ 1,5Мб !!!!

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

Зарание всем благодарен.
vesago
Надеюсь не забыл перед подачей питания объединить розовый проводок с белым?
ksv198
Цитата(TamTam @ May 28 2007, 21:56) *
Товариши приключилась сия трабла собрал девайс которы по считыванию DS1990 счелкает релюшкой, стало интересно купил Перковский считыватель PERCo-RP-15MW так как он может имулировать DS1990 с надеждой на то что когда я его подключу то он считает ключь с карты и передаст его по 1-wire но этого так и не произошло

Делал 2 года тому назад интерфейс к этому считывателю на Меге8 4 МГц (что под рукой было). Правда без прерываний и на асме. Весь проект положить к сожалению не могу, но вот набор подпрограмм для работы с данным считывателем по 1-wire:
Нажмите для просмотра прикрепленного файла
Считыватель подключал к PORTB,0. Вход управления звуком считывателя к PORTB,1 (пищать для индикации). r0 используется в CRC8calc;
temp =r20
temp1 =r21
flash =r23
;
.dseg
buf_out: .byte 20 ;резервируем выходной буфер USART
buf_in: .byte 20 ;резервируем входной буфер USART
b1w_out: .byte 8 ;резервируем выходной буфер 1wire
b1w_in: .byte 8 ;резервируем входной буфер 1wire
Надеюсь поможет.
Удачи!
TamTam
Цитата(vesago @ May 29 2007, 11:17) *
Надеюсь не забыл перед подачей питания объединить розовый проводок с белым?


нет не забыл :-))

Цитата(ksv198 @ May 29 2007, 11:41) *
Делал 2 года тому назад интерфейс к этому считывателю на Меге8 4 МГц (что под рукой было). Правда без прерываний и на асме. Весь проект положить к сожалению не могу, но вот набор подпрограмм для работы с данным считывателем по 1-wire:
Нажмите для просмотра прикрепленного файла
Считыватель подключал к PORTB,0. Вход управления звуком считывателя к PORTB,1 (пищать для индикации). r0 используется в CRC8calc;
temp =r20
temp1 =r21
flash =r23
;
.dseg
buf_out: .byte 20 ;резервируем выходной буфер USART
buf_in: .byte 20 ;резервируем входной буфер USART
b1w_out: .byte 8 ;резервируем выходной буфер 1wire
b1w_in: .byte 8 ;резервируем входной буфер 1wire
Надеюсь поможет.
Удачи!


я боюсь что у меня логика считывания со считывателя нарушена. немоглибы вы прокоментировать, как надо делать, к примеру:
1 подносим карту
считыватель должен дать данные о том что он считал карту ?
2 запускаем программу считывания 1 по таймеру или по прирыванию если считыватель дает какието данные
3 получаем номер карты
vesago
Хост постоянно шлет сброс считывателю. По прерванию или просто в основном процессе. Если карта не поднесена, последний ни как не реагирует. Если карта находит ся в поле считываетля, то на каждый сброс считыватель отвечает присутствием. Хост как увидал присутствие, шлет команду 33h, потом читает ответ, считает контрольную сумму и т.д. Вообще прекрасно алгоритм реализован Леонидом Ивановичем на телесисах в проектах.
TechMike
Цитата(vesago @ May 29 2007, 15:14) *
Хост постоянно шлет сброс считывателю. По прерванию или просто в основном процессе. Если карта не поднесена, последний ни как не реагирует. Если карта находит ся в поле считываетля, то на каждый сброс считыватель отвечает присутствием. Хост как увидал присутствие, шлет команду 33h, потом читает ответ, считает контрольную сумму и т.д. Вообще прекрасно алгоритм реализован Леонидом Ивановичем на телесисах в проектах.


Делаю как часть проекта считывание таблеток ds1990 и обязательно нужно читать emarin карты. Прикупили самые простые считыватели CP-Z производства IronLogic CPZ
В результате ds1990 читаю без проблем, а считыватель читается с CRC Error.
Алгоритм стандартный: в цикле делаю present pulse, если есть ответ, то читаю id, задержки и длительности по datasheet

Кто работа с этим считывателем, подскажите, что у него там за заморочки, скорее всего с задержками?

P.S. Производитель молчит как в танке, ни ответа от него ни привета.
vesago
Это у вас явно с времянками косяк. Подтяжку ставьте поменьше - 1.6k и поиграйте с времянками. Особенно времением после начала слота.
TechMike
Цитата(vesago @ Oct 9 2008, 11:33) *
Это у вас явно с времянками косяк. Подтяжку ставьте поменьше - 1.6k и поиграйте с времянками. Особенно времением после начала слота.


Насчет времянок это и ежу понятно, прошу более конкретно про конкретные тайминги плс?
Резюк сейчас 4ком, был 3.3ком, все равно crc error.

Так как осциллограф у меня доисторический и аналоговый, поймать, что выдает считыватель не получилось.
Читаю таблетку вот так (mega16+8мгц кварц):

//******************************************************************************
// Функция чтения ключа iButton
//Date: 09.04.2008
//Autor: Eugene Samoylov

// input:
// *code - указатель на буфер для ключа 8 байт
// TM - пин регистра ввода вывода откуда производится чтение
// output:
// 0 - ок;
// 1 - нет импульса присутствия;
// 2 - ненормальное состояние линии (КЗ?)
// 3 - ошибка CRC
//******************************************************************************
BYTE ReadKey(BYTE *code, BYTE TM)
{
BYTE tcnt, Data, i;

// импульс сброса
SETBIT(DDR_TM, TM); // выход
CLRBIT(PORT_TM, TM); // низкий уровень
__delay_cycles(clkMhz * 500); // 500 мкс низкого уровня
CLRBIT(DDR_TM, TM); // вход
SETBIT(PORT_TM, TM); // c подтяжкой

// детектирования импульса присутствия
tcnt = 0;
__delay_cycles(clkMhz * 10);
while(PIN_TM & (1 << TM))
{
__delay_cycles(clkMhz * 10);
tcnt ++;
// если нет - выходим
if(tcnt > 10) return 1;
}

// детектирования готовности ключа
tcnt = 0;
__delay_cycles(clkMhz * 10);
while(!(PIN_TM & (1 << TM)))
{
__delay_cycles(clkMhz * 20);
tcnt ++;
// если линия все еще в низком уровне - гдето КЗ
if(tcnt > 15) return 2;
}

__delay_cycles(clkMhz * 20);
Data = 0x33;
// если да - передача команды
for(tcnt = 0; tcnt < 8; tcnt ++)
{
if(!(Data & (1 << tcnt)))
{
// если 0 сформировать задний фронт + 60 мкс + передний фронт
SETBIT(DDR_TM, TM); // выход
CLRBIT(PORT_TM, TM); // низкий уровень
__delay_cycles(clkMhz * 45);
SETBIT(PORT_TM, TM); // высокий уровень
}
else
{
// если 1 сформировать задний фронт + 15 мкс + передний фронт + 45 мкс
SETBIT(DDR_TM, TM); // выход
CLRBIT(PORT_TM, TM); // низкий уровень
__delay_cycles(clkMhz * 5);
SETBIT(PORT_TM, TM); // высокий уровень
__delay_cycles(clkMhz * 45);
}
__delay_cycles(clkMhz * 10);
}

// чтение данных
for(i = 0; i < 8; i++) // байтовый цикл
{

Data = 0;

for(tcnt = 0; tcnt < 8; tcnt ++) // битовый цикл
{
// даем строб 5 мкс
SETBIT(DDR_TM, TM); // выход
CLRBIT(PORT_TM, TM); // низкий уровень
__delay_cycles(clkMhz * 5);
// переключаемся на вход с подтяжкой
CLRBIT(DDR_TM, TM); // вход
SETBIT(PORT_TM, TM); // подтяжка
// ждем 10 мкс
__delay_cycles(clkMhz * 15);
// читаем данные
Data >>=1; // сдвигаем рег.данных
if(PIN_TM & (1 << TM))
{
Data |= (1 << 7);// 1
}
__delay_cycles(clkMhz * 45);
}

code[i] = Data;
}

// проверка CRC
if (CRC_calc(code) == 0)
{
return 0;
}

return 3;
// выходим
}
vesago
Пожалуйста, когда приводите код, пользуйте соответсвующие средства этого форума для форматирования. Трудно читать. У вас как я понял момент считывания лежит где-то около 20 мкс от начала слота. Попробуйте снизить это значение до мкс 13. Т.е. задержку не 15 ставить а 8. Ну и в конце увеличить. Чтобы подогнать осциллограф не нужен. Выкидывайте считанные данные в терминал без проверки контрольной суммы и все сами увидите.
TechMike
Цитата(vesago @ Oct 10 2008, 12:38) *
Пожалуйста, когда приводите код, пользуйте соответсвующие средства этого форума для форматирования. Трудно читать. У вас как я понял момент считывания лежит где-то около 20 мкс от начала слота. Попробуйте снизить это значение до мкс 13. Т.е. задержку не 15 ставить а 8. Ну и в конце увеличить. Чтобы подогнать осциллограф не нужен. Выкидывайте считанные данные в терминал без проверки контрольной суммы и все сами увидите.


Что то не получается, проблема(ошибка считывания) та же, может я чего в коде не то изменил, уже глова не варит......:?
Код
BYTE ReadKey(BYTE *code, BYTE TM)
{
BYTE tcnt, Data, i;

  // импульс сброса
  SETBIT(DDR_TM,  TM);                    // выход
  CLRBIT(PORT_TM, TM);                    // низкий уровень
  __delay_cycles(clkMhz * 500);           // 500 мкс низкого уровня
  CLRBIT(DDR_TM,  TM);                    // вход
  SETBIT(PORT_TM, TM);                    // c подтяжкой

  // детектирования импульса присутствия
  tcnt = 0;
  __delay_cycles(clkMhz * 10);
  while(PIN_TM & (1 << TM))
  {
  __delay_cycles(clkMhz * 10);
  tcnt ++;
  // если нет - выходим
  if(tcnt > 10) return 1;
  }

  // детектирования готовности ключа
  tcnt = 0;
  __delay_cycles(clkMhz * 10);
  while(!(PIN_TM & (1 << TM)))
  {
  __delay_cycles(clkMhz * 20);
  tcnt ++;
  // если линия все еще в низком уровне - гдето КЗ
  if(tcnt > 15) return 2;
  }

  __delay_cycles(clkMhz * 20);
  Data = 0x33;
  // если да - передача команды
  for(tcnt = 0; tcnt < 8; tcnt ++)
  {
    if(!(Data & (1 << tcnt)))
    {
    // если 0 сформировать задний фронт + 60 мкс + передний фронт
      SETBIT(DDR_TM,  TM);                    // выход
      CLRBIT(PORT_TM, TM);                    // низкий уровень
      __delay_cycles(clkMhz * 45);
      SETBIT(PORT_TM, TM);                    // высокий уровень
    }
    else
    {
    // если 1 сформировать задний фронт + 15 мкс + передний фронт + 45 мкс
      SETBIT(DDR_TM,  TM);                    // выход
      CLRBIT(PORT_TM, TM);                    // низкий уровень
      __delay_cycles(clkMhz * 5);
      SETBIT(PORT_TM, TM);                    // высокий уровень
      __delay_cycles(clkMhz * 45);
    }
  __delay_cycles(clkMhz * 10);
  }

  // чтение данных
  for(i = 0; i < 8; i++) // байтовый цикл
  {

    Data = 0;

    for(tcnt = 0; tcnt < 8; tcnt ++)          // битовый цикл
    {
    // даем строб 5 мкс
      SETBIT(DDR_TM,  TM);                    // выход
      CLRBIT(PORT_TM, TM);                    // низкий уровень
      __delay_cycles(clkMhz * 5);
    // переключаемся на вход с подтяжкой
      CLRBIT(DDR_TM,  TM);                    // вход
      SETBIT(PORT_TM, TM);                    // подтяжка
    // ждем 10 мкс
      __delay_cycles(clkMhz * 8); // БЫЛА ЗАДЕРЖКА  15 !!!
    // читаем данные
      Data >>=1;                            // сдвигаем рег.данных
      if(PIN_TM & (1 << TM))
      {
      Data |= (1 << 7);// 1
      }
    __delay_cycles(clkMhz * 38); //БЫЛА ЗАДЕРЖКА 45 !!!
    }

    code[i] = Data;
  }

  // проверка CRC
  if (CRC_calc(code) == 0)
  {
    return 0;
  }

return 3;
  // выходим
}

//******************************************************************************
//  Функция делающая задержку от 4 до 65000 тактов процессора (inline!!!)
//******************************************************************************
void __delay_cycles(WORD __count)
{
        __count >>= 2;
       __asm__ volatile (
        "1: sbiw %0,1" "\n\t"
        "brne 1b"
        : "=w" (__count)
        : "0" (__count)
        );
}
xemul
Присоединюсь к совету vesago: организуйте все-таки вывод полученных данных (независимо от кривости CRC) в терминал.
По остальному коду:
имхо, зря дергаете в 0/1 сам пин - если не требуется strong pull-up (а для чтения таблеток он не требуется), достаточно установить пин в 0 и переключать только DDR;
имхо, перед сбросом стОит контролировать шину на 1;
имхо, удобнее биты передавать/принимать как-то так:
Код
BYTE bitmask;

  Data = 0x33;
  // если да - передача команды
  for(bitmask = 1; bitmask; bitmask <<= 1)
  {
    SETBIT(DDR_TM,  TM);                    // выход
    if(!(Data & bitmask))
      __delay_cycles(clkMhz * 45);
      CLRBIT(DDR_TM,  TM);                    // вход
    else
    {
      __delay_cycles(clkMhz * 5);
      CLRBIT(DDR_TM,  TM);                    // вход
      __delay_cycles(clkMhz * 40);
    }
  __delay_cycles(clkMhz * 10);
  }

Неплохо бы узнать точность эмуляции ванварного слейва в CPZ. Для этого, н-р, заводите в двухмиллисекундном цикле сначала только ResetPulse - PresenceDetect, определяете допуски по таймингам для них, потом добавляете в цикл передачу ReadROM и чтение только первого байта, определяете остальные допуски.
На 2-хмс развертке осциллографа все будет хорошо видно.
TechMike
Вывожу в терминал внезависимости от кривости CRC прочитаный серийник ключа, он всегда постоянный и не меняется(щюуџ 1), т.е читаю все постоянно одно и тоже.
Попробовал уже отчаявшись посмотреть, что выдаст iButton Viewer {32-bit}.
Он ds1990 читает на ура, а вот со считывателя отказывается читать сирийник, просто не обнаруживает такой девайс, что-то они там намудрили с таймингами блин
vesago
Ранее со своим оборудованием мы пользовали ридеры прокс, сечас полностью перешли на арон логик. Ни разу не было проблем. Возможно, что тайминги у них отличаются от DS1990, но не смертельно. То что код у вас при считывании явно не искажается не показатель. Если есть сомнения попробуйте считать альтернативным оборудованием - охранным прибором или прибором контроля доступа. Возможно вы некорректно считтаете контрольную сумму - на DS1990 случайно сошлась, тоже самое, возможно так считалась DS1990, что сошлась КС.
TechMike
Цитата(vesago @ Oct 19 2008, 12:08) *
Ранее со своим оборудованием мы пользовали ридеры прокс, сечас полностью перешли на арон логик. Ни разу не было проблем. Возможно, что тайминги у них отличаются от DS1990, но не смертельно. То что код у вас при считывании явно не искажается не показатель. Если есть сомнения попробуйте считать альтернативным оборудованием - охранным прибором или прибором контроля доступа. Возможно вы некорректно считтаете контрольную сумму - на DS1990 случайно сошлась, тоже самое, возможно так считалась DS1990, что сошлась КС.



Я вот тоже считал, что иронложик нормально все имулирует и по этому и взял CP-Z их производства, но оказалось все не так просто.
CRC для ds1990 пробовал на 3-х таблетках, все без сбоев, буквально 10 из 10 касаний, если подключить считыватель к контролеру того же ironlogic'а, то он функционирует как часы.

CRC считаю совершенно тривиальным способом, уже обмусоливалось на форумах:
Код
//******************************************************************************
//  Функция подсчёта CRC для полинома {10011001} (протокол iButton)
//******************************************************************************
BYTE CRC_calc(BYTE *data)
{//uint8_t _crc_ibutton_update(uint8_t crc, uint8_t data)
BYTE j, i, crc = 0;

    for(j = 0; j < 8; j ++)
    {
        crc = crc ^ data[j];
        for (i = 0; i < 8; i++)
        {
            if (crc & 0x01) crc = (crc >> 1) ^ 0x8C;
            else            crc >>= 1;
        }
    }
return crc;
}
TechMike
Цитата(vesago @ Oct 19 2008, 12:08) *
Ранее со своим оборудованием мы пользовали ридеры прокс, сечас полностью перешли на арон логик. Ни разу не было проблем. Возможно, что тайминги у них отличаются от DS1990, но не смертельно. То что код у вас при считывании явно не искажается не показатель. Если есть сомнения попробуйте считать альтернативным оборудованием - охранным прибором или прибором контроля доступа. Возможно вы некорректно считтаете контрольную сумму - на DS1990 случайно сошлась, тоже самое, возможно так считалась DS1990, что сошлась КС.


Проверил работу считывателя на контролере Z5R, все считывается корректно, обе имеющие метки распознаются и каждая выполняет свои функции в зависимости от запрограммированой функции.
Мой же МК считывает обе метки как F9CF7FFEF39FFFFF и соответственно выдает CRC ERROR.

Какие задержки еще можно покрутить?
TechMike
Задача решена, благодаря форумчанам сахары Проблемы с CP-Z
Код для истории, может кому пригодится:
Код
//******************************************************************************
//Autor: Eugene Samoylov
//Descr: Модуль работы со TouchMemory
//          Функция чтения ключа iButton
// input:
// *code - указатель на буфер для ключа 8 байт
// TM - пин регистра ввода вывода откуда производится чтение
// output:
// 0 - ок;
// 1 - нет импульса присутствия;
// 2 - ненормальное состояние линии (КЗ?)
// 3 - ошибка CRC
//******************************************************************************
BYTE ReadKey(BYTE *code, BYTE TM)
{
BYTE tcnt, Data, i;

  // импульс сброса
  SETBIT(DDR_TM,  TM);                    // выход
  CLRBIT(PORT_TM, TM);                    // низкий уровень
  __delay_cycles(clkMhz * 500);           // 500 мкс низкого уровня
  CLRBIT(DDR_TM,  TM);                    // вход
  SETBIT(PORT_TM, TM);                    // c подтяжкой

  // детектирования импульса присутствия
  tcnt = 0;
  __delay_cycles(clkMhz * 10);
  while(PIN_TM & (1 << TM))
  {
  __delay_cycles(clkMhz * 10);
  tcnt ++;
  // если нет - выходим
  if(tcnt > 10) return 1;
  }

  // детектирования готовности ключа
  tcnt = 0;
  __delay_cycles(clkMhz * 10);
  while(!(PIN_TM & (1 << TM)))
  {
  __delay_cycles(clkMhz * 20);
  tcnt ++;
  // если линия все еще в низком уровне - гдето КЗ
  if(tcnt > 15) return 2;
  }

  __delay_cycles(clkMhz * 20);
  Data = 0x33;
  // если да - передача команды
  for(tcnt = 0; tcnt < 8; tcnt ++)
  {
    if(!(Data & (1 << tcnt)))
    {
    // если 0 сформировать задний фронт + 60 мкс + передний фронт
      SETBIT(DDR_TM,  TM);                    // выход
      CLRBIT(PORT_TM, TM);                    // низкий уровень
      __delay_cycles(clkMhz * 90);
      SETBIT(PORT_TM, TM);                    // высокий уровень
    }
    else
    {
    // если 1 сформировать задний фронт + 15 мкс + передний фронт + 45 мкс
      SETBIT(DDR_TM,  TM);                    // выход
      CLRBIT(PORT_TM, TM);                    // низкий уровень
      __delay_cycles(clkMhz * 8);
      SETBIT(PORT_TM, TM);                    // высокий уровень
      __delay_cycles(clkMhz * 80);
    }
  __delay_cycles(clkMhz * 10);
  }

  // чтение данных
  for(i = 0; i < 8; i++) // байтовый цикл
  {

    Data = 0;

    for(tcnt = 0; tcnt < 8; tcnt ++)          // битовый цикл
    {
    // даем строб 5 мкс
      SETBIT(DDR_TM,  TM);                    // выход
      CLRBIT(PORT_TM, TM);                    // низкий уровень
      __delay_cycles(clkMhz * 13); //было 5
    // переключаемся на вход с подтяжкой
      CLRBIT(DDR_TM,  TM);                    // вход
      SETBIT(PORT_TM, TM);                    // подтяжка
    // ждем 10 мкс
      __delay_cycles(clkMhz * 2); //было 15 !!!
    // читаем данные
      Data >>=1;                            // сдвигаем рег.данных
      if(PIN_TM & (1 << TM))
      {
      Data |= (1 << 7);// 1
      }
    __delay_cycles(clkMhz * 55); //было 45 !!!
    }

    code[i] = Data;
  }

  // проверка CRC
  if (CRC_calc(code) == 0)
  {
    return 0;
  }

return 3;
  // выходим
}
Andreisela
Народ, а что с проектом под КВАВР? потому как ща сам столкнулся с этой же проблемой.
На кол посадить инженеров разработавших этот мостик, в инструкции написанно что полная эмуляция, а в итоге так накосячить с таймигами...
Вообщем, если есть этот проект в CVAVR - выложите пожалуйста, оч неохото трахать мозг на переконвертирование...
MayDay
Цитата(TechMike @ Oct 20 2008, 22:47) *
Проверил работу считывателя на контролере Z5R, все считывается корректно, обе имеющие метки распознаются и каждая выполняет свои функции в зависимости от запрограммированой функции.
Мой же МК считывает обе метки как F9CF7FFEF39FFFFF и соответственно выдает CRC ERROR.

Какие задержки еще можно покрутить?


Ну, я бы порекомендовал прочесть вот эту статью по проблемам 1-wire при программировании на языках высокого уровня.
может быть поможет.
santa2.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.