Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.52/142: Рейтинг темы: голосов - 142, средняя оценка - 4.52
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 204
1

Распознавание RFID

18.08.2014, 00:04. Показов 26713. Ответов 52
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток!
Делаю один девайс, в котором нужно считывать RFID карты (125 кгц), аналоговую часть взял здесь http://www.serasidis.gr/circuits/RFID_r ... reader.htm, вместо тиньки стоит атмега8. На сайте есть и код, но там сделано тупо в цикле, а мне нужно на прерываниях.
Застрял в самом начале. Проблема в том, что я не могу понять, как вычислить период, так как из-за большой скорость передачи данных (в отличии от RC5) я осцилом не могу увидеть, что там карта передает в начале. Теоретически, вот начало (потому что много единичек): (смотрите пикчу ниже).
На желтые и зеленые линии прошу не обращать внимания, это я дорисовал. Во первых, интересует, почему на первых восьми столбиках ширина активного уровня короче, чем ширина не активного?
Во вторых, какая должна быть длина низкого уровня между двумя первыми столбиками? У меня получилось чуть больше 500 мкс, это правильно? Дело в том, что моя прога в начале определяет длину периода (1 бита) и она почему то получается 1500 мкс, но я хз, что микроконтроллер поймал.
Вот кусок кода:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#define sbi(reg,bit) (reg |= (1<<bit))
#define cbi(reg,bit) (reg &= ~(1<<bit))
#define ibi(reg,bit) (reg ^= (1<<bit))
#define CheckByt(reg,bit) (reg&(1<<bit))
 
#define   SIT_CAPT_ON(l)   {l ? sbi(TCCR1B, ICES1) : cbi(TCCR1B, ICES1);}
#define CAPT_ON (CheckByt(TCCR1B, ICES1))
 
#define   SIT_COMP_INTERRUPT_ENABLED(l)   {l ? sbi(TIMSK, OCIE1A) : cbi(TIMSK, OCIE1A);}
 
void RFID_Init(void)
{
cbi(DDRB, 0); cbi(PORTB, 0);   // icp to input
 
RFID.bcounter = 0;
RFID.receiving = false;
RFID.period = 0;
RFID.haveData = false;
 
SIT_COMP_INTERRUPT_ENABLED(0);
OCR1A = 0;
 
//Если ICESn =0, то падающий фронт приводит к захвату,  ICESn = 1, то нарастающий фронт.
TCCR1B = _BV(ICNC1) | _BV(CS10);
SIT_CAPT_ON(0);
TIMSK |= _BV(TICIE1);
 
SIT_CAPT_ON(1);   // включаем захват по наростающему. В результате, прерывание будет вызвано когда будет передана первая половина первого бита (1).
}
 
void RFID_Start(void)
{
RFID.bcounter = 0;
RFID.receiving = false;
RFID.period = 0;
RFID.haveData = false;
SIT_CAPT_ON(0);
}
 
ISR(TIMER1_CAPT_vect)
{
if (RFID.haveData) return;
 
volatile uint16_t   capture = ICR1;
 
if (!RFID.period) {
if (CAPT_ON) RFID.period = capture;   // save period
 
ibi(TCCR1B, ICES1); // capture on different level
return;
}
// период получен, первый бит теперь отсутствует, от стартовых остались только 8
 
itoa(RFID.period, RFID.buffer, 10);
RFID.bcounter = strlen(RFID.buffer);
RFID.haveData = trui;
}
Если кто то выложит рабочий код приема RFID, работающего на прерываниях, буду сильно благодарен)))))
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.08.2014, 00:04
Ответы с готовыми решениями:

RFID
Собственно сабаж=) Никто не знает никакой нормальной литературы описывающей эту технологию? Если...

RFID считыватель
Приветствую! Не встречал ли кто-нибудь где-нибудь простой статейки на тему &quot;как прочитать/записать...

RFID-считыватель 125 кГц на ATmega16
Доброго времени суток. Преамбула: хочу сделать для себя RFID-считыватель 125 кГц на ATmega16 . Уже...

Grove - 125KHz RFID Reader + AVR
Сильно не пинать. Вопрос в следующем. Есть вот это и вот такая штука. В мою голову залезла мысль....

Эмуляция RFID ключа домофона на микроконтроллерах AVR
Доброго времени, форумчане. Требуется склонировать ключ от домофона типа RFID. Доступные мне...

52
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
19.08.2014, 12:34 41
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Ymk
Цитата Сообщение от ShodS
Вспомните кривой писк на нигнитофонах для загрузки программ в спектрумы... это манчестер...
в спектруме не манчестер:)Да ладно...

Цитата Сообщение от BrMysho
ShodS, пасибки! Буду пробовать. А можно еще и схему?
Там же рабочий файл протеуса есть...
Если нет протеуса, то вот схемка... Там при нажатии кнопок первая мега отправляет код RFID карты, а вторая мега его принимает и кидает номер карты в терминал...

Цитата Сообщение от BrMysho
И еще, получается, что в вашем коде прерывание по таймеру вызывается каждые 64 цикла? Не многовато ли?
Это вы про код на mega8, и про такты контроллера? И почему решили что каждые 64 такта - прерывание?

Там прерывания происходят когда прошло 3\4 времени манчестерского бита, ну и непосредственно когда приходит сам следующий бит...
Если частота манчестера 2кгц (например RFID карта), то период следования битов - 0,5 мсек... а это огого сколько тактов...
0
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 204
19.08.2014, 16:02 42
Сори, я протупил. Только что проспался, теперь вроде мозг норм работает.
Скажите, пожалуйста, а что будет, если на вход поступит сначала несколько десятков ошибочных периодов, а затем манчестерский код, Ваша прошивка его зафиксирует или нужно чтобы сразу передавался манчестерский код?
Как я и писал выше, у меня в начале на вход попадает какой то мусор, а потом уже манчестерский код. Пробовал отлавливать начало по 9 единицам, а потом читать остальные биты. В итоге, эти биты были одинаковые для одной и той же карты, но разные для разных карт, с чего можно сделать вывод, что биты успешно прочитаны, но так как 9 бит может быть не только в начале, прочитаная последовательность битов не является верной:(
0
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 204
19.08.2014, 20:20 43
С горем пополам удалось отфильтровать мусор и принять рабочие данные. Итак, беру USB ридер, тыкаю в него RFID метку (брелок), мне выдает 30067971210 (это его серийный номер).
Вот какие биты выдает мой ридер:
1111111110000001111000000000000110000001101101001100011010011110.
Как видим, в начале 9 единиц, в конце 0, как и должно быть. Вот разделил (9 начальных единичек убрал):
Код
-----VERSION-----
0000
0
0111
1

-----TAG SERIAL NUMBER-----
0000
0
0000
0
0011
0
0000
0
1101
1
0100
1
1000
1
1010
0

-----COLUMN PORITY BITS-----
1111

-----STOP BIT-----
0
Как вычислить column parity bits я еще не понял, но остальные биты четности совпадают. Могу предположить, что пакет пришел правильный. Но как связан номер 30067971210 (считанный покупным ридером) с тем, который прочитал мой ридер?
0
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
19.08.2014, 20:33 44
Ну так сложи все данные в кучку:

Код
-----VERSION-----
0000
0111
0000
0000
0011
0000
1101
0100
1000
1010
-----COLUMN PORITY BITS-----
получится 0000011100000000001100001101010010001010 в двоичном, это и есть 30067971210 в десятичном
0
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 204
19.08.2014, 20:34 45
PS: как вычислить column parity bits уже понял.
Stiit.mi, Хм, а я сразу что то не то вычислил))))
0
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 204
20.08.2014, 02:48 46
Товарищи, никто не подскажет, как можно сделать prymtf для uint64_t? %llu не работает, выводит пустую строку.
Ну или просто как вывести uint64_t в строку, не обязательно через prymtf.
PS: пишу в Atmel studyo 6
0
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
20.08.2014, 12:59 47
C
1
prymtf("%lu%lu", var/1000000000, var%1000000000)
Или в шестнадцатеричном выводи, если разницы нет
0
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 204
20.08.2014, 14:17 48
Пасибо! Работает)))
0
0 / 0 / 0
Регистрация: 07.11.2012
Сообщений: 204
20.08.2014, 15:21 49
Вобщем, все готово.
Исходя с того, что в начале мусор, могу сделать вывод, что определить время периода не возможно.
Как работает код:
1. Ждем пока придет 9 единичек, для этого включаем захват по нарастающему, если первые 9 нарастающих равны длине указанного периода, то продолжаем, если нет, начинаем сначала.
2. Принимаем биты в кольцевой буфер.
3. Когда пришло 64 бита, проверяем их (чтобы в начале было 9 единичек, в конце 0, совпадал паритет). Если проверка не прошла, переходим к пункту 2.
4. Если за 3/4 периода не было перехода (который должен быть в середине бита), переходим к пункту 1.
Работа довольно стабильная. Исходники прилагаю.
0
otix_omd_r
02.04.2015, 13:47 50
Цитата Сообщение от ShodS
Чет вы там с декодированием слишком мудрите... там все просто делается... вот как я декодировал...

1) Входим в обработчик прерывания при любом перепаде, хоть из 0 в 1, хоть из 1 в 0...
2) Выключаем внешнее прерывание на период длиной в 3\4 слота бита.Вложение:
3) Проверка на корректность длительности замера
Если замер не попадает в окно допустимых значений - инициализируем прием сначала...pic2.png

4) Значение принятого бита (уровень в линии после прерывания) задвигаем в байт приемник ByteIn

Подскажите пожалуйста, а как согласно этой схеме определять значение MAN_PERIOD_LEN?
0 / 0 / 0
Регистрация: 03.06.2018
Сообщений: 4
14.06.2018, 15:31 51
Конечно уже прошло 4 года, но сейчас я пытаюсь сделать RFID-ридер 125 кГц на атмеге 16/32, и застрял на этапе вычисления периода между фронтами.

Не могли бы Вы скинуть еще раз исходник своей работы?

P.S. Может быть кто-нибудь тут поможет с решением моей проблемы?
0
1280 / 1185 / 175
Регистрация: 02.12.2013
Сообщений: 4,883
14.06.2018, 16:05 52
Использовать режим захвата таймера. Режим захвата позволяет генерировать прерывание TIMERx_CAPT_vect при изменении логического уровня соответствующего вывода микроконтроллера. При первом прерывании по захвату, устанавливаем соответствующий флаг начала измерения, и обнуляем счетный регистр. При втором прерывании по захвату, сбрасываем флаг и смотрим сколько насчитал таймер.
1
0 / 0 / 0
Регистрация: 03.06.2018
Сообщений: 4
14.06.2018, 17:41 53
Витальич,
Использовать режим захвата таймера. Режим захвата позволяет генерировать прерывание TIMERx_CAPT_vect при изменении логического уровня соответствующего вывода микроконтроллера. При первом прерывании по захвату, устанавливаем соответствующий флаг начала измерения, и обнуляем счетный регистр. При втором прерывании по захвату, сбрасываем флаг и смотрим сколько насчитал таймер.
Это выглядит примерно так?

C
1
2
3
4
5
6
7
8
9
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
    ICR1 = TCNT1;
    TCNT1 = 0x00;
    //TIFR |= 0x20;
    //tgl(TCCR1B,ICES1);
    if (TCCR1B == 0x42) {TCCR1B = 0x02; edge = 1;} else {TCCR1B = 0x42; edge = 0;}
    time = ICR1; 
}
Тогда еще один вопрос, как дальше определить что между фронтами период или 2 периода (или 1/2 T и T), чтобы можно было декодировать манчестера? Теперь не могу поймать первые 9 единиц, точнее не знаю как кодом это реализовать
0
14.06.2018, 17:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.06.2018, 17:41
Помогаю со студенческими работами здесь

RFID reader на stm32
Здравствуйте! Захотелось сделать мне rfid reader. У меня есть stm32f4discovery и вот такая платка....

RFID RC522 протокол обмена
Переделал модуль как в этой статье. Хочу подключить модуль к PIC через UART. Пытался нагуглить, но...

Прошу помощи RFID Мультиплексор на MSP430F2370
Добрый день.Уважаемые форумчане нужна ваша помощь.Я новичок и хотелось бы разобраться.Нашел мануал...

Возможно-ли купить RFID/NFC-метку и оплачивать покупки?
Или такое невозможно? МК сможет работать с NFC, RFID?

Android и распознавание распознавание различных устройств
Есть Android-клиент и web-сервер. Требуется распознавать различные устройства одного пользователя....

Rfid
Купил комплект uno В нем попалась карточка, брелок, RC522 Решил побаловаться Нашел скетч,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
53
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru