Использование прерываний с RC522

У меня есть проект, в котором используется модуль RFID RC522 с платой Arduino Uno и библиотекой RFID от miguelbalboa. Пример кода и любой другой код, который я нахожу в Интернете, объединяет устройство, чтобы узнать, есть ли новая карта, но я намерен работать с подходом, основанным на прерываниях. У меня есть необходимые знания для работы с оборудованием/arduino, но у меня возникают проблемы с созданием прерывания на выводе IRQ, когда присутствует карта. Кому-нибудь это удалось?

Изменить: Связь: RST -> 8

СС->9

МОСИ -> 11

МИСО -> 12

СКК -> 13

IRQ -> 2

Код:

#include <SPI.h>
#include <MFRC522.h>
#include <String.h>

#define RST_PIN     8 
#define SS_PIN      9

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Создаем экземпляр MFRC522

void setup() 
{
  Serial.begin(9600);       // Инициализируем последовательную связь с ПК
  while (!Serial);      // Ничего не делать, если последовательный порт не открыт (добавлено для Arduino на базе ATMEGA32U4)
  SPI.begin();          // Инициируем шину SPI
  mfrc522.PCD_Init();       // Инициализация MFRC522
  mfrc522.PCD_WriteRegister(MFRC522::ComIrqReg, 0x80); //Очистить прерывания
  mfrc522.PCD_WriteRegister(MFRC522::ComIEnReg, 0x7F); // Разрешить все прерывания
  mfrc522.PCD_WriteRegister(MFRC522::DivIEnReg, 0x14);
  Serial.println(F("Ready..."));
  attachInterrupt(0, isr, RISING);
}

void loop() 
{
}

void isr()
{
  Serial.println(F("Interrupt"));
  mfrc522.PCD_WriteRegister(MFRC522::ComIrqReg, 0x80); //Очистить прерывания
}

Результат: Я получаю только "Готово..." на последовательном мониторе, независимо от того, присутствует карта или нет.

, 👍4

Обсуждение

Добро пожаловать в Ардуино SE! Код? Проводка?, @Anonymous Penguin

@AnnonomusPenguin Я использовал только примеры кодов и проводки из [ссылки](https://github.com/miguelbalboa/rfid) (незначительное изменение, RST -> контакт 8 и SS -> контакт 9, для совместимости с Ethernet щит). Поскольку сейчас у меня нет доступа к осциллографу, я не могу проверить вывод прерывания, поэтому я написал скетч для объединения этого вывода и вывода его состояния с помощью последовательного трехстрочного кода. Он продолжает выдавать мне 0, независимо от того, присутствует карта или нет ... В документации [ссылка](http://www.nxp.com/documents/data_sheet/MFRC522.pdf) мало говорится о прерываниях, и они отношение к чтению карты., @Gustavo Sgarbi Campos

Этот код сам обрабатывает прерывания или вы его модифицировали?, @Anonymous Penguin

Библиотека не работает с прерываниями, они даже не используют вывод IRQ..., @Gustavo Sgarbi Campos

Так ты модифицировал код? Не могли бы вы добавить минимальный пример проблемы (с кодом и схемой) к вашему вопросу с правкой? Спасибо, @Anonymous Penguin

@AnnonomusPenguin отредактировал..., @Gustavo Sgarbi Campos

Вам придется сделать всю работу самостоятельно, потому что, кажется, никто еще не сделал! Прежде всего, вам нужно определить характеристики вывода IRQ. Напишите простую программу без ISR или чего-то особенного, которая просто опрашивает контакт IRQ и включает встроенный светодиод, когда он высокий, и выключает, когда он низкий. Если ничего не происходит, это может быть связано с тем, что IRQ является слишком коротким импульсом, чтобы его можно было увидеть. Сделайте одноразовую программу, которая ждет, пока IRQ не станет высоким (или низким), а затем зацикливается с включенным светодиодом. Возможно, вам придется включить внутренний подтягивающий резистор на Uno. Удачи..., @CharlieHanson


3 ответа


0

Прежде всего, я извиняюсь за английский язык, я его понимаю, но я использую переводчик Google, чтобы выразить свои мысли.

Я не использую Arduino, это интересная платформа (для ide, которая, по-видимому, является объектно-ориентированным программированием POO), но она сильно ограничена аппаратным обеспечением

Ну, вступая в тему, я тоже разрабатываю реализацию для MRFC522, и в даташите не приведены примеры как это сделать, а указано как включить прерывания (хотя я еще не пробовал)

но если я не ошибаюсь, задействованы следующие регистры:

ComIEnReg--> Биты управляющего регистра для включения и отключения передачи запросов на прерывание.

DivIEnReg--> управляющие биты для включения и отключения передачи запросов на прерывание.

ComIrqReg--> зарегистрируйте биты запроса на прерывание. (думаю, только для чтения)

DivIrqReg--> описания битов регистра (думаю, только для чтения)

Я думаю, что это просто правильная настройка первых двух, чтобы они могли генерировать прерывание на выводе irq. я не знаю, правильно ли следующее.

установите для ComIEnReg значение --> (в двоичном формате) 0b01111111 // разрешает все прерывания

установите для DivIEnReg значение --> 0b10000100 // Я не совсем понимаю MFIN (бит 4) и установите его на 0, но я установил CRCIEn на 1 (бит 2) и бит 7 на 1 "пин IRQ является стандартным выходом CMOS контакт"

// другая возможная конфигурация для DivIEnReg

  • ваш--> 0b00010100 -->0x14
  • попытка 1 --> 0b00000100 -->0x04
  • попытка 2 --> 0b10010100 -->0X94
  • попытка 3 --> 0b10000100 -->0X84

если вам удастся модуль сделать прерывание, было бы любезно прокомментировать, как вы это сделали

,

К сожалению, я не смог использовать контакт IRQ. Мой проект остановлен прямо сейчас, но я вернусь к нему немного позже и, возможно, разберусь. Я объединяю модуль, чтобы проверить новый тег на данный момент, и то, что я прочитал, похоже, что никто не смог использовать прерывание для обнаружения новых тегов. Я согласен с вами по поводу Arduino, он очень ограничен, но, поскольку я работаю только над POC (доказательство концепции), это идеальная платформа!, @Gustavo Sgarbi Campos

Как вы упомянули, «Arduino ограничен», можете ли вы поделиться другими альтернативами. Хотел бы изучить их, а также. Я полностью со стороны программного обеспечения, и хотел бы понять это больше., @karx


4

Из вашего кода:

void isr()
{
  Serial.println(F("Interrupt"));
  mfrc522.PCD_WriteRegister(MFRC522::ComIrqReg, 0x80); //Clear interrupts
}

Не выполняйте последовательную печать внутри ISR! В конце концов они его повесят. Что вам нужно сделать, так это иметь изменчивую переменную (например, логическое значение), установить ее в ISR, а затем проверить это в loop. Если он изменится, отобразите его. Например.

volatile bool cardPresent;

void loop() 
{
  if (cardPresent)
    {
    Serial.println(F("Interrupt"));
    mfrc522.PCD_WriteRegister(MFRC522::ComIrqReg, 0x80); //Очистить прерывания
    cardPresent = false;
    }

}

void isr()
{
  cardPresent = true;
}

Другое, что я мог бы сделать, это подключить осциллограф или логический анализатор к выводу IRQ и посмотреть, действительно ли он изменяется. В этом случае он должен вызвать прерывание.

,

4

Я довольно опоздал на эту вечеринку, но я искал способ, чтобы MFRC522 генерировал прерывание при обнаружении совместимой RFID-карты/брелока/наклейки/и т. д., и это один из хитов, которые я получил от моего поиска. Я пишу это сейчас для паломников, которые следуют тем же хлебным крошкам, что и я, в надежде, что это сэкономит им хотя бы немного времени.

Я попробовал что-то похожее на то, что было предложено, обнаружил, что меня прерывают довольно часто и постоянно, и немного больше изучил ситуацию.

MFRC522 не генерирует прерывания для обнаружения карты. Микроконтроллер (или микропроцессор) должен дать ему команду на передачу, а затем запросить его, чтобы увидеть, был ли какой-либо ответ. Это означает, что MCU не может перейти в спящий режим и быть разбуженным MFRC522, когда есть карта для чтения. В MFRC522 есть таймер, который может генерировать прерывание, но максимальный период этого таймера невелик, и таймер не управляет трансивером, он там для удобства приложения на MCU.

Запись 0x7F в "ComIEnReg" означает следующее:

  • Бит 7: IRqInv=0 — прерывания активны, высокий уровень
  • Бит 6: TxIEn=1 — прерывание передатчика разрешено
  • Бит 5: RxIEn=1 — прерывание приема разрешено
  • Бит 4: IdleIEn=1 — прерывание по простою включено
  • Бит 3: HiAlertIEn=1 — включено прерывание «Высокий уровень тревоги».
  • Бит 2: LoAlertIEn=1 — прерывание "Предупреждение о низком уровне" включено
  • Бит 1: ErrIEn=1 — прерывание по ошибке включено
  • Бит 0: TimerIEn=1 — прерывание таймера разрешено.

Биты в регистре "ComIrqReg" имеют следующее значение:

  • Бит 7: Set1 — при записи в 1 значение бита 1 в битах 6-0 записанного байта устанавливает соответствующий бит регистра; при записи 0 биты 6-0 очищают соответствующий бит регистра
  • Бит 6: TxIRq — устанавливается, когда последний бит данных Tx был отправлен.
  • Бит 5: RxIRq — устанавливается, когда получатель обнаруживает конец действительного потока данных.
  • Бит 4: IdleIRq — устанавливается, когда CommandReg изменяет поле команды на команду ожидания.
  • Бит 3: HiAlertIRq — устанавливается, когда установлен бит HiAlert в регистре Status1
  • Бит 2: LoAlertIRq — устанавливается, когда бит LoAlert в регистре Status1 установлен.
  • Бит 1: ErrIRq — устанавливается, когда устанавливается любой бит в ErrorReg
  • Бит 0: TimerIRq — устанавливается, когда TCounterValReg уменьшается до нуля

Запись 0x14 в "DivIEnReg" имеет следующее значение:

  • Бит 7: IRQPushPull=0 — IRQ является выходным контактом с открытым стоком.
  • Бит 6: зарезервировано=0 – эффект неизвестен.
  • Бит 5: зарезервировано=0 — эффект неизвестен
  • Бит 4: MfinActEn=1 — разрешить запросу активного прерывания MFIN запускать IRQ
  • Бит 3: зарезервировано=0 – ограниченно не определено.
  • Бит 2: CRCIEn=1 — разрешить биту DivIrqReg CRCIRq запускать IRQ.
  • Бит 1: зарезервировано=0 — не устанавливайте значение 1 под страхом ничего
  • Бит 0: зарезервировано=0 — не имеет другой цели, кроме как сбить с толку.

Регистр "DivIrqReg" соответствует "DivIrqEn" и имеет следующие определения битов:

  • Бит 7: Set2 — при записи как 1 значение бита 1 в битах 6-0 записанного байта устанавливает соответствующий бит регистра; при записи 0 биты 6-0 очищают соответствующий бит регистра
  • Бит 6: зарезервировано — не спрашивать
  • Бит 5: зарезервировано — не говорить
  • Бит 4: MfinActIRq — MFIN активен
  • Бит 3: зарезервирован — просто оставьте его равным нулю и медленно отойдите назад.
  • Бит 2: CRCIRq – значение 1 означает, что команда CalcCRC активна и все данные обрабатываются.
  • Бит 1: зарезервировано — здесь ничего не видно
  • Бит 0: зарезервировано — тебе повезло, панк?

Приведенные выше определения битов регистра были взяты из таблицы данных MFRC522 от NXP под названием " MFRC522 Стандартная производительность интерфейса MIFARE и NTAG», версия 3.9, 27 апреля 2016 г.

В библиотеке для MFRC522 есть пример прерывания, в котором используются более легкие средства опроса трансивера. см. https://github.com/miguelbalboa/rfid/tree/master/examples/MinimalInterrupt , но он не предоставляет средств для пробуждения вашего хоста из режима сна с низким энергопотреблением, когда кто-то машет своим волшебным кольцом над скрытой панелью у потайной двери, а это означает, что ваше секретное логово должно быть подключено к считывателю, даже если в остальном он беспроводной; либо так, либо ваши приспешники будут вечно менять батарейки.

,