|
ATTiny2313 + DS1990 и его имитатор в виде считывателя карт, Для хорошо знающих 1-wire |
|
|
|
May 28 2007, 17:56
|

Местный
  
Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254

|
Товариши приключилась сия трабла собрал девайс которы по считыванию DS1990 счелкает релюшкой, стало интересно купил Перковский считыватель PERCo-RP-15MW так как он может имулировать DS1990 с надеждой на то что когда я его подключу то он считает ключь с карты и передаст его по 1-wire но этого так и не произошло, хотя попытка попасть в прирывание по спадающему фронту проходит, но данные не передаються. подскажите в чем может быть косяк? Пишу в CVAVR 1.25.3 использую стандартную функцию поиска из стандартной библы. PDF от читывателя, ВНИМАНИЕ 1,5Мб !!!!Ниже прикладываю скины наиболле инфорамтивных страниц из пдф, может у меня с таймингами что невпоряде, знающие глянти плиз. Зарание всем благодарен.
Эскизы прикрепленных изображений
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 17)
|
May 29 2007, 07:41
|
Частый гость
 
Группа: Участник
Сообщений: 177
Регистрация: 25-08-05
Из: Ставрополь
Пользователь №: 7 964

|
Цитата(TamTam @ May 28 2007, 21:56)  Товариши приключилась сия трабла собрал девайс которы по считыванию DS1990 счелкает релюшкой, стало интересно купил Перковский считыватель PERCo-RP-15MW так как он может имулировать DS1990 с надеждой на то что когда я его подключу то он считает ключь с карты и передаст его по 1-wire но этого так и не произошло Делал 2 года тому назад интерфейс к этому считывателю на Меге8 4 МГц (что под рукой было). Правда без прерываний и на асме. Весь проект положить к сожалению не могу, но вот набор подпрограмм для работы с данным считывателем по 1-wire:
1wire.zip ( 1.66 килобайт )
Кол-во скачиваний: 352Считыватель подключал к 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 Надеюсь поможет. Удачи!
|
|
|
|
|
May 29 2007, 10:38
|

Местный
  
Группа: Свой
Сообщений: 293
Регистрация: 14-03-06
Пользователь №: 15 254

|
Цитата(vesago @ May 29 2007, 11:17)  Надеюсь не забыл перед подачей питания объединить розовый проводок с белым? нет не забыл :-)) Цитата(ksv198 @ May 29 2007, 11:41)  Делал 2 года тому назад интерфейс к этому считывателю на Меге8 4 МГц (что под рукой было). Правда без прерываний и на асме. Весь проект положить к сожалению не могу, но вот набор подпрограмм для работы с данным считывателем по 1-wire:
1wire.zip ( 1.66 килобайт )
Кол-во скачиваний: 352Считыватель подключал к 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 получаем номер карты
|
|
|
|
|
Oct 9 2008, 07:26
|
Частый гость
 
Группа: Свой
Сообщений: 130
Регистрация: 30-07-08
Из: Moscow
Пользователь №: 39 302

|
Цитата(vesago @ May 29 2007, 15:14)  Хост постоянно шлет сброс считывателю. По прерванию или просто в основном процессе. Если карта не поднесена, последний ни как не реагирует. Если карта находит ся в поле считываетля, то на каждый сброс считыватель отвечает присутствием. Хост как увидал присутствие, шлет команду 33h, потом читает ответ, считает контрольную сумму и т.д. Вообще прекрасно алгоритм реализован Леонидом Ивановичем на телесисах в проектах. Делаю как часть проекта считывание таблеток ds1990 и обязательно нужно читать emarin карты. Прикупили самые простые считыватели CP-Z производства IronLogic CPZВ результате ds1990 читаю без проблем, а считыватель читается с CRC Error. Алгоритм стандартный: в цикле делаю present pulse, если есть ответ, то читаю id, задержки и длительности по datasheet Кто работа с этим считывателем, подскажите, что у него там за заморочки, скорее всего с задержками? P.S. Производитель молчит как в танке, ни ответа от него ни привета.
Сообщение отредактировал TechMike - Oct 9 2008, 07:27
|
|
|
|
|
Oct 9 2008, 07:53
|
Частый гость
 
Группа: Свой
Сообщений: 130
Регистрация: 30-07-08
Из: Moscow
Пользователь №: 39 302

|
Цитата(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; // выходим }
Сообщение отредактировал TechMike - Oct 9 2008, 08:03
|
|
|
|
|
Oct 15 2008, 11:19
|
Частый гость
 
Группа: Свой
Сообщений: 130
Регистрация: 30-07-08
Из: Moscow
Пользователь №: 39 302

|
Цитата(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) ); }
|
|
|
|
|
Oct 15 2008, 13:01
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Присоединюсь к совету 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-хмс развертке осциллографа все будет хорошо видно.
|
|
|
|
|
Oct 19 2008, 08:17
|
Частый гость
 
Группа: Свой
Сообщений: 130
Регистрация: 30-07-08
Из: Moscow
Пользователь №: 39 302

|
Цитата(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; }
|
|
|
|
|
Oct 20 2008, 16:47
|
Частый гость
 
Группа: Свой
Сообщений: 130
Регистрация: 30-07-08
Из: Moscow
Пользователь №: 39 302

|
Цитата(vesago @ Oct 19 2008, 12:08)  Ранее со своим оборудованием мы пользовали ридеры прокс, сечас полностью перешли на арон логик. Ни разу не было проблем. Возможно, что тайминги у них отличаются от DS1990, но не смертельно. То что код у вас при считывании явно не искажается не показатель. Если есть сомнения попробуйте считать альтернативным оборудованием - охранным прибором или прибором контроля доступа. Возможно вы некорректно считтаете контрольную сумму - на DS1990 случайно сошлась, тоже самое, возможно так считалась DS1990, что сошлась КС. Проверил работу считывателя на контролере Z5R, все считывается корректно, обе имеющие метки распознаются и каждая выполняет свои функции в зависимости от запрограммированой функции. Мой же МК считывает обе метки как F9CF7FFEF39FFFFF и соответственно выдает CRC ERROR. Какие задержки еще можно покрутить?
|
|
|
|
|
Oct 21 2008, 18:40
|
Частый гость
 
Группа: Свой
Сообщений: 130
Регистрация: 30-07-08
Из: Moscow
Пользователь №: 39 302

|
Задача решена, благодаря форумчанам сахары Проблемы с 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; // выходим }
|
|
|
|
|
May 13 2009, 18:32
|
Участник

Группа: Участник
Сообщений: 15
Регистрация: 3-11-06
Из: Москва
Пользователь №: 21 958

|
Народ, а что с проектом под КВАВР? потому как ща сам столкнулся с этой же проблемой. На кол посадить инженеров разработавших этот мостик, в инструкции написанно что полная эмуляция, а в итоге так накосячить с таймигами... Вообщем, если есть этот проект в CVAVR - выложите пожалуйста, оч неохото трахать мозг на переконвертирование...
|
|
|
|
|
Dec 16 2010, 11:09
|
Группа: Новичок
Сообщений: 1
Регистрация: 16-12-10
Пользователь №: 61 661

|
Цитата(TechMike @ Oct 20 2008, 22:47)  Проверил работу считывателя на контролере Z5R, все считывается корректно, обе имеющие метки распознаются и каждая выполняет свои функции в зависимости от запрограммированой функции. Мой же МК считывает обе метки как F9CF7FFEF39FFFFF и соответственно выдает CRC ERROR.
Какие задержки еще можно покрутить? Ну, я бы порекомендовал прочесть вот эту статью по проблемам 1-wire при программировании на языках высокого уровня. может быть поможет.
Сообщение отредактировал MayDay - Dec 16 2010, 11:10
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|