Techmike (21.10.2008 16:36, просмотров: 19359)
Делаю как часть проекта считывание таблеток ds1990 и обязательно нужно читать emarin карты. Прикупили самые простые считыватели CP-Z производства IronLogic, по отзывам должны быть надежны и не прихотливы. В результате таблетку ds1990 читаю без проблем, а со считывателя брелки читаются с CRC Error и всегда один и тот же серийник.
Алгоритм стандартный: в цикле делаю present pulse, если есть ответ, то читаю id, задержки и длительности по datasheet
На таблетку 5кОм на землю, тело 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;
// выходим
}