Странная проблема с ардуино

Я написал код ниже, и результат оказался совсем не таким, как я ожидал! Я не понимаю, почему это происходит!

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

const uint8_t pat[] PROGMEM = {
  0xff,
  0x00,
  0xff,
  0x00,
  0xff,
  0x00,
  0xff,
  0x66
};

void loop() {
  delay(100);
  Serial.println(sizeof(pat));
  for (int i=0; i<8; i++){
    Serial.print(pat[int(i)],HEX);
  }
  Serial.println("");
  Serial.print(pat[0],HEX);
  Serial.print(pat[1],HEX);
  Serial.print(pat[2],HEX);
  Serial.print(pat[3],HEX);
  Serial.print(pat[4],HEX);
  Serial.print(pat[5],HEX);
  Serial.print(pat[6],HEX);
  Serial.print(pat[7],HEX);
  Serial.println("");
  while(true);
}

Выход на удивление такой:

8

008000010

FF0FF0FF0FF66

Что делает компилятор в фоновом режиме, но, похоже, он действительно все портит! Цикл должен делать то же самое, что и писать этот код вручную снова и снова, но это не так! Как исправить петлю?

, 👍0

Обсуждение

представляет ли результат одну итерацию цикла()? ..... вам действительно нужно напечатать разделитель, используя что-то вроде Serial.println("--------------");, @jsotola


1 ответ


Лучший ответ:

1

Если вы хотите получить значение из PROGMEM, вы должны прочитать его с помощью функций pgm_read. Прочтите справку по PROGMEM.

for (int i = 0; i < 8; i++) {
  Serial.print(pgm_read_byte_near(pat + i),HEX);
}

pat[0] в Serial.print(pat[0],HEX); — это элемент в массиве констант const uint8_t pat[]. оно не может измениться во время выполнения, поэтому компилятор использует значение 0xFF. вот почему он печатается нормально без pgm_read_byte_near

,

это бы объяснило это, но почему, когда я вручную пишу pat[6] в операторе печати, он не возвращает то же значение? каким-то образом во время компиляции заменяются только значения цикла?, @OM222O

@ OM222O OM222O, как я пишу в ответе, константы использования заменяются при компиляции, @Juraj

Мой вопрос все еще остается: почему код в цикле СПЕЦИАЛЬНО заменяется во время компиляции? если я что-то сделаю, я = 0; печать (пат [я]); оно не должно отличаться от print(pat[0]); ! это почти как если бы компилятор обрабатывал целые числа по-другому!, @OM222O

потому что для использования значения из позиции массива требуется меньше инструкций, чем для получения значения из массива каждый раз. компилятор оптимизирует малый размер двоичного файла, @Juraj

это не имело бы большого смысла! они оба целые! Я даже обязательно использовал int(i)! Создается int и увеличивается цикл выполнения программы!, @OM222O

@OM222O, pat[0] в Serial.print(pat[0],HEX); — это элемент в массиве констант const uint8_t pat[]. оно не может измениться во время выполнения, поэтому компилятор использует значение 0xFF. вот почему он печатается нормально без pgm_read_byte_near, @Juraj