Деление массива байтов: какой функцией?
- Войдите на сайт для отправки комментариев
Ср, 01/05/2019 - 23:17
То есть например из 16-ти байтного массива:
byte mainBuffer[] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F
};
получить такие 4 массива по 4 байта
byte buffer_0[] = {0x00, 0x01, 0x02, 0x03};
byte buffer_1[] = {0x04, 0x05, 0x06, 0x07};
byte buffer_2[] = {0x08, 0x09, 0x0A, 0x0B};
byte buffer_3[] = {0x0C, 0x0D, 0x0E, 0x0F};Есть ли готовая функция для этого? Подскажите пожалуйста, кто разбирается!
Оно?
Вариант 1 - очевидный - два вложенных цикла for
Вариант 2 - для эстетов - описать 16 байтовый массив как унион для четырех переменных типа лонг
Оно?
шикарно
https://ru.wikipedia.org/wiki/Memcpy
Тфу, вот так всмысле
Только это будет не копия а ссылки на элементы, соответственно границы надо контролировать самому.
Полагаю, что тут приведён способ того, как получить четыре указателя на разные части массива, а не получить четыре массива из одного. А это слегка разные вещи.
Вы имеете в виду что-то вроде этого
for (int i = 0; i < 4; i++) // количество массивов { ????? for (int j = 0; j < 4; j++) // количество байт { ????? } }Но названия у массивов ведь разные! Как их запихнуть в цикл for?
Вариант № 1
union uMassConv { uint8_t raw[16]; uint8_t fofo[4][4]; }; uMassConv myMass; void setup() { for(uint8_t i=0;i<16;i++){ myMass.raw[i]=i+1; } for(uint8_t i=0;i<4;i++){ for (uint8_t j=0;i<4;j++){ Serial.print(myMass.fofo[i][j]); Serial.print(' '); } Serial.println(); } } void loop() { }Вариант № 2
uint8_t fofo[4][4]; uint8_t* raw=(uint8_t*)fofo; void setup() { for(uint8_t i=0;i<16;i++){ raw[i]=i+1; } for(uint8_t i=0;i<4;i++){ for (uint8_t j=0;i<4;j++){ Serial.print(fofo[i][j]); Serial.print(' '); } Serial.println(); } } void loop() { }Думаю, что пока ТС не соблаговолит уточнить - что, по его мнению, означает "получить 4 массива", особого смысла в упражнениях нет.
Тфу, вот так всмысле
Только это будет не копия а ссылки на элементы, соответственно границы надо контролировать самому.
Кстати, ничто не мешает работать с этими массивами так:
buffer_1[1]=20;
А вот buffer_0 излишен, ибо он mainBuffer и есть :)
Например, есть функция, которая принимает 4 байта и записывает их в память. И чтобы использовать её с буфером, в который считывается дамп памяти, нужно разделить данные по 4 байта. Чтобы эту функцию можно было запихнуть в цикл for.
То есть алгоритм вроде бы простой:
-взять первые четыре байта из массива;
-запихнуть их в функцию для записи;
- взять следующие четыре байта из массива;
-запихнуть их в функцию для записи;
и т.д.
Объявление функции покажи, пж - как она принимает 4 байта? Это 4 разных параметра, или четырехбайтовая переменная, или просто - указатель на массив? Если последнее, то с точки зрения С++ нет разницы, что передавать - можешь передать указатель на первый элемент массива, а можешь - на пятый, и ничего делить не надо. Например:
void function(byte* bArray) { ..... } byte b[16] = {0}; function(b); function(b+4); function(b+8);Например, есть функция, которая принимает 4 байта и записывает их в память. И чтобы использовать её с буфером, в который считывается дамп памяти, нужно разделить данные по 4 байта. Чтобы эту функцию можно было запихнуть в цикл for.
То есть алгоритм вроде бы простой:
-взять первые четыре байта из массива;
-запихнуть их в функцию для записи;
- взять следующие четыре байта из массива;
-запихнуть их в функцию для записи;
и т.д.
junior_developer, давайте разделять понятия "есть" и "можно написать".
По поводу "есть", длина массива даже для Уно, Нано, Мини может быть от 2 до примерно 2000. Длина каждой из частей тоже может быть примерно от 1 до 2000. Итого, на все случаи жизни требуется около 4 миллионов разных функций (это еще если не учитывать Micro, Due, stm32duino и пр.), как Вы думаете, они уже где-то есть готовые?
Ну а по поводу "можно написать" - да, можно. Причем, это совсем не сложно.
А вот функция целиком:
MFRC522::StatusCode MFRC522::MIFARE_Ultralight_Write( byte page, ///< The page (2-15) to write to. byte *buffer, ///< The 4 bytes to write to the PICC byte bufferSize ///< Buffer size, must be at least 4 bytes. Exactly 4 bytes are written. ) { MFRC522::StatusCode result; // Sanity check if (buffer == nullptr || bufferSize < 4) { return STATUS_INVALID; } // Build commmand buffer byte cmdBuffer[6]; cmdBuffer[0] = PICC_CMD_UL_WRITE; cmdBuffer[1] = page; memcpy(&cmdBuffer[2], buffer, 4); // Perform the write result = PCD_MIFARE_Transceive(cmdBuffer, 6); // Adds CRC_A and checks that the response is MF_ACK. if (result != STATUS_OK) { return result; } return STATUS_OK; } // End MIFARE_Ultralight_Write()Она из библиотеки https://github.com/miguelbalboa/rfid
Ну и зачем делить массив? Пример - я писал - просто скармливаешь функции указатель на нужный элемент массива:
byte b[16] = {0}; mifare.MIFARE_Ultralight_Write(0,b,4); mifare.MIFARE_Ultralight_Write(0,b+4,4); mifare.MIFARE_Ultralight_Write(0,b+8,4); mifare.MIFARE_Ultralight_Write(0,b+12,4);Большое спасибо всем, кто помог!
Для ясности добавлю ещё образец вызова этой функции
for (int i=0; i < 4; i++) { //data is writen in blocks of 4 bytes (4 bytes per page) status = (MFRC522::StatusCode) mfrc522.MIFARE_Ultralight_Write(pageAddr+i, &buffer[i*4], 4); if (status != MFRC522::STATUS_OK) { Serial.print(F("MIFARE_Read() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } }В таком варианте она работает правильно! Пишутся 4 страницы по 4 байта! Кстати под буффер выделено не 16 байтов, а 18!
И код целиком
/* mifare ultralight example (25-02-2018) * * RFID-RC522 (SPI connexion) * * CARD RC522 Arduino (UNO) * SDA ----------- 10 (Configurable, see SS_PIN constant) * SCK ----------- 13 * MOSI ----------- 11 * MISO ----------- 12 * IRQ ----------- * GND ----------- GND * RST ----------- 9 (onfigurable, see RST_PIN constant) * 3.3V ----------- 3.3V * */ #include <SPI.h> #include <MFRC522.h> #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance MFRC522::StatusCode status; //variable to get card status byte buffer[18]; //data transfer buffer (16+2 bytes data+CRC) byte size = sizeof(buffer); uint8_t pageAddr = 0x06; //In this example we will write/read 16 bytes (page 6,7,8 and 9). //Ultraligth mem = 16 pages. 4 bytes per page. //Pages 0 to 4 are for special functions. void setup() { Serial.begin(9600); // Initialize serial communications with the PC SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 card Serial.println(F("Sketch has been started!")); memcpy(buffer,"HELLO WORLD! ;-)",16); } void loop() { // Look for new cards if ( ! mfrc522.PICC_IsNewCardPresent()) return; // Select one of the cards if ( ! mfrc522.PICC_ReadCardSerial()) return; // Write data *********************************************** for (int i=0; i < 4; i++) { //data is writen in blocks of 4 bytes (4 bytes per page) status = (MFRC522::StatusCode) mfrc522.MIFARE_Ultralight_Write(pageAddr+i, &buffer[i*4], 4); if (status != MFRC522::STATUS_OK) { Serial.print(F("MIFARE_Read() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } } Serial.println(F("MIFARE_Ultralight_Write() OK ")); Serial.println(); // Read data *************************************************** Serial.println(F("Reading data ... ")); //data in 4 block is readed at once. status = (MFRC522::StatusCode) mfrc522.MIFARE_Read(pageAddr, buffer, &size); if (status != MFRC522::STATUS_OK) { Serial.print(F("MIFARE_Read() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return; } Serial.print(F("Readed data: ")); //Dump a byte array to Serial for (byte i = 0; i < 16; i++) { Serial.write(buffer[i]); } Serial.println(); mfrc522.PICC_HaltA(); }Нашел его в ответе на вопрос в этом топике
Да, в таком виде код рабочий, но если попробовать записывать не 16 байт, а например 64 - не работает!!!
У меня уже возникло предположение, что тут не обойтись без ещё одного цикла for!
То есть, чтобы получить 64, нужно просто запихнуть этот вызов функции в цикл for и повторить его 4 раза, просто меняя значение указателя!
А под буфер тогда нужно выделить 18*4=72 байта! 16*4=64(под данные) 2*4=8 (для контрольных сумм). Правильно ли я рассудаю?
И ещё обратил внимание на такую деталь: в функции записи есть вот такая закорючка "&", а в функции чтения - нет!
То есть вот так:
Нужна ли она?
И ещё обратил внимание на такую деталь: в функции записи есть вот такая закорючка "&", а в функции чтения - нет!
То есть вот так:
Нужна ли она?
Вам нужно срочно что нибудь почитать ! Пока вас отсюда ссаными тряпками в песочницу не загнали !
[buffer_0 излишен, ибо он mainBuffer и есть :)
Согласен. Ну как бы для наглядности примера
Ну, а в чем наглядность то ? Вот даже не понимаю, это поток мысли, так сказать, или поток желчи ? Или это смесь "мысли так сказать" с желчью ? Не понимаю как вам отвечать. Но в принципе, если сумеете сформулировать мысль, то я вам обязательно отвечу :)
Это мне? Где в моём посте "желчь"??
А она там есть ? Я же и спрашиваю, что это ?