Функция параметра rxAlign в функции PCD_ReadRegister в библиотеке MFRC522

Я пытаюсь перенести библиотеку Arduino MFRC522 (с GitHub) на микроконтроллеры ARM. Моя проблема связана с функцией PCD_ReadRegister:

/**
 * Reads a number of bytes from the specified register in the MFRC522 chip.
 * The interface is described in the datasheet section 8.1.2.
 */
void MFRC522::PCD_ReadRegister( byte reg,       ///< The register to read from. One of the PCD_Register enums.
                                byte count,     ///< The number of bytes to read
                                byte *values,   ///< Byte array to store the values in.
                                byte rxAlign    ///< Only bit positions rxAlign..7 in values[0] are updated.
                                ) {

    if (count == 0) {
        return;
    }
    //Serial.print(F("Reading "));  Serial.print(count); Serial.println(F(" bytes from register."));
    byte address = 0x80 | (reg & 0x7E);     // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
    byte index = 0;                         // Index in values array.
    SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV4, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
    digitalWrite(_chipSelectPin, LOW);      // Select slave
    count--;                                // One read is performed outside of the loop
    SPI.transfer(address);                  // Tell MFRC522 which address we want to read
    while (index < count) {
        if (index == 0 && rxAlign) {        // Only update bit positions rxAlign..7 in values[0]
            // Create bit mask for bit positions rxAlign..7
            byte mask = 0;
            for (byte i = rxAlign; i <= 7; i++) {
                mask |= (1 << i);
            }
            // Read value and tell that we want to read the same address again.
            byte value = SPI.transfer(address);
            // Apply mask to both current value of values[0] and the new data in value.
            values[0] = (values[index] & ~mask) | (value & mask);
        }
        else { // Normal case
            values[index] = SPI.transfer(address);  // Read value and tell that we want to read the same address again.
        }
        index++;
    }
    values[index] = SPI.transfer(0);            // Read the final byte. Send 0 to stop reading.
    digitalWrite(_chipSelectPin, HIGH);         // Release slave again
    SPI.endTransaction(); // Stop using the SPI bus

} // End PCD_ReadRegister()

Я несколько раз прочитал таблицу данных и не могу понять, в чем функция этого параметра! На основе таблицы данных для считывания регистра из rc522:

, 👍0


1 ответ


0

Что касается изображения в вашем посте о "Данных для чтения SPI", в котором просто говорится, что первый байт, полученный через MISO, отбрасывается, что выполняется в PCD_ReadRegister() прямо перед циклом for, а затем считывается n байтов, при этом 0 передается в последний раз, чтобы остановить чтение.

Быстрый просмотр библиотеки и таблицы данных показывает, что аргумент rxAlign используется для определения первого допустимого бита в первом полученном байте. txLastBits служит аналогичной цели, только для передачи последнего байта. Оба они записаны в BitFramingReg MFRC522 и необходимы для битовых кадров между MFRC522 и картой/тегом.

Например, в приведенной выше функции, если rxAlign = 3, это означает, что в первом полученном байте допустимы только биты от 7 до 3, извлеченные с помощью битовой маски 11111000. Таким образом, первый допустимый "байт" содержит биты от 7 до 3 первого принятого байта, объединенного с битами 2-0 следующего принятого байта. Аналогично, при передаче txLastBits указывает количество битов последнего байта, которые должны быть переданы на карту/метку. В обоих случаях то, что передается или принимается по радиочастотному полю, может быть не кратно 8, следовательно, необходимы эти аргументы и BitFramingReg.

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


Обновление

Я постараюсь ответить на ваши вопросы:

  • В этом контексте 106 Кб / с относится к скорости передачи данных между RC522 и картой, а не между RC522 и MCU. Максимум, я думаю, составляет около 848 кб / с, я думаю. Проверьте таблицу данных для получения более подробной информации.
  • Битовые кадры необходимы для процесса предотвращения столкновений. Наложенные биты в манчестерском кодировании, когда несколько карт пытаются связаться с RC522 одновременно, требуют обработки отдельных битов в отличие от обычных единиц размером в байт. Посмотрите на методы защиты от столкновений.
  • Предотвращение столкновений необходимо, если один и тот же считыватель, возможно, будет иметь несколько тегов в пределах своего диапазона. Из статьи IEEE:

Столкновения меток могут привести к серьезной неэффективности RFID-систем, что приведет к низкой скорости идентификации, короткому диапазону считывания и неэффективному использованию ресурсов. Они более проблематичны в пассивных тегах из-за ограничений по мощности и функциональности.

Таким образом, если вы будете предъявлять только одну карту за раз, то вы должны быть в безопасности, не внедряя в свой код защиту от коллизий. В противном случае, боюсь, у вас нет выбора, если только вы не хотите сбить читателя с толку.

Если все, что вы хотите сделать, это прочитать UID и прочитать/записать в блоки на карте (по одному за раз), вы можете попробовать перенести эту простую библиотеку UART MFRC522, которая, кстати, не реализует anitcollision.

Если вы все еще хотите перенести библиотеку на основе SPI, тогда несколько предложений:

Вы хотите заменить интерфейс SPI на UART. Это низкоуровневые материалы, все они содержатся в нескольких функциях, таких как PCD_ReadRegister (), PCD_WriteRegister() и некоторых других. Эти функции служат функциям более высокого уровня, которые понятия не имеют об их внутренней реализации, но ожидают от них определенного поведения. Замените функции SPI на их эквиваленты UART, как только вы поймете, как разговаривать с читателем через UART. Как только ваши функции ARM UART будут вести себя точно так же, как функции SPI, ваша работа почти завершена; нет необходимости выяснять причину всего, что содержится в функциях более высокого уровня, поскольку они не связаны ни с чем, связанным с интерфейсом. Это включает в себя все, что касается rxAlign и еще много чего. Удачи :).

,

Дорогая Тисте,Огромное спасибо за ваше замечательное описание.Проблема в том, что я должен изменить библиотеки, используемые периферийным соединением с SPI на UART.3 новый вопрос:1-На основе таблицы 46-таблица 48:эти биты должны использоваться только для побитового антиколлизии при 106 кБд, для всех остальных режимов они установлены в 0.затем для скорости передачи данных по умолчанию 9600 бод в uart я могу избежать этого?2-второй вопрос: я понимаю,что делать, но я еще не знаю, почему мы это делаем?почему байты не формируются как обычно и не действительны с первого бита?3-это необходимо и в режиме UART?, @Mahmoud HD

@MahmoudHD Я отредактировал свой ответ., @SoreDakeNoKoto

@MahmoudHD Это помогает? Ты уже прошел через это?, @SoreDakeNoKoto

Уважаемый Тисте,Очень ценю вас за ваше отличное руководство,я изо всех сил стараюсь портировать официальную библиотеку SPI arduino этого чипа на мой целевой MCU,я буду иметь место для нового вопроса здесь,WBR., @Mahmoud HD

@MahmoudHD Ты больше не портируешься на UART?, @SoreDakeNoKoto

На самом деле я имею в виду,что пытаюсь портировать SPI-версию(https://github.com/miguelbalboa/rfid) до инициализации с помощью UART еще нет.Теперь мы находимся в новогодних каникулах,и после этого я продолжу портировать это для LPC ARM MCU, WBR., @Mahmoud HD