Mega2560 чтение одного байта из eeprom с адреса > 255

Тема в разделе "Arduino & Shields", создана пользователем Vovka, 8 ноя 2020.

Метки:
  1. Vovka

    Vovka Гик

    Если для компилятора ардуины uint8_t и uint32_t одно и то же, то может так понятнее было бы:
    Код (C++):

    uint8_t eeprom_read_byte (const uint8_t *__p) __ATTR_PURE__;
    uint16_t eeprom_read_word (const uint8_t *__p) __ATTR_PURE__;
    uint32_t eeprom_read_dword (const uint8_t *__p) __ATTR_PURE__;
     
  2. Nekto_nikto

    Nekto_nikto Гик

    Вам до этого УЖЕ написали, что это не одно и то же и компилятор сам выберет нужную функцию в зависимости от входных данных и прочих задаваемых параметрам, к которым в вашем случае также относится поддерживаемая контроллером адресация. ГУГЛИТЕ,
     
  3. a1000

    a1000 Гуру

    До чего всё запутанно в Си. Как всё просто и наглядно в ASM
    Код (C++):
    LDI R16,0 ; Загружаем адрес нулевой ячейки
    LDI R17,0 ; EEPROM из которой хотим прочитать байт
    RCALL EERead ; вызываем процедуру чтения. После которой
                 ; в R21 будет считанный байт.

    EERead:
           SBIC EECR,EEWE ; Ждем пока будет завершена прошлая запись.
           RJMP EERead ; также крутимся в цикле.
           OUT EEARL, R16 ; загружаем адрес нужной ячейки
           OUT EEARH, R17 ; его старшие и младшие байты
           SBI EECR,EERE ; Выставляем бит чтения
           IN R21, EEDR ; Забираем из регистра данных результат
    RET
    Никаких типов переменных. Глянул что получается - выделил нужное число байт в памяти. Сам себе хозяин, а тут надо компилятор уговаривать.
     
  4. SergeiL

    SergeiL Оракул Модератор

    А если подумать?
    Взять например ATtiny13 - 1К Flash и 64 байта SRAM.
    Или Intel 8086, где есть сегментация, различные модели памяти у приложения и, естественно короткие и длинные указатели.
     
  5. Vovka

    Vovka Гик

    А почему мой выше код не является перегруженными функциями??? Что за новый стандарт в ардуине?
    Сейчас вопрос о том, что в данном случае для компилятора одно и тоже в адресе uint8_t или uint32_t
     
  6. Unixon

    Unixon Оракул Модератор

    Во-первых, перегруженная функция всегда называется одинаково.
    Во-вторых в C/C++ функции по типу возвращаемого значения не перегружаются.
     
    SergeiL и ZAZ-965 нравится это.
  7. parovoZZ

    parovoZZ Гуру

    ты вообще понимаешь разницу между ПЕРЕМЕННОЙ и УКАЗАТЕЛЕМ на эту ПЕРЕМЕННУЮ? Указатель на байт говорит компилятору, что необходимо извлечь ДАННЫЕ из ПЕРЕМЕННОЙ размером ОДИН БАЙТ. Адрес этой переменной компилятор ПОДСТАВИТ САМ! Адрес вообще может быть 32 бита!
     
  8. Vovka

    Vovka Гик

    Что-то я вообще запутался! Т.е. по адресу 300 компитятор извлечет данные и передаст в функцию?
    Код (C++):
    uint8_t eeprom_read_byte (const uint8_t *__p) __ATTR_PURE__;
    uint8_t x;
    x = eeprom_read_byte ( 300 );
     
     
  9. parovoZZ

    parovoZZ Гуру

    только не компилятор, а код, который этот компилятор создаст. А если бы вместо сидения на форумах ты бы изучил МК AVR серии AtMega (например, книга Евстифеева), то знал бы, что у этих МК абсолютно вся память адресуется 2-мя байтами.
     
  10. parovoZZ

    parovoZZ Гуру

    Я для себя написал такие функции для работы с EEPROM AVR:
    Код (C++):
    //... Запись в EEPROM
    void EEPROM_write(uint16_t ucAddress, uint8_t ucData)
    {  
        while(EECR & (1<<EEPE));            //.. Ждем завершения предыдущей операции с памятью

        cli();
       
        EECR = (0<<EEPM1)|(0<<EEPM0);            //.. Установим режим работы - стирание и запись за одну операцию длительностью 3.4 мс (Atomic Operation)
       
        EEAR = ucAddress;                //.. Запишем адрес ячейки и данные в регистры
        EEDR = ucData;  

        EECR |= (1<<EEMPE);                //.. Установим мастер бит EEMPE
       
        EECR |= (1<<EEPE);                //.. и произведём запись в EEPROM

        sei();
    }


        //... Чтение из EEPROM
    uint8_t EEPROM_read(uint16_t ucAddress)
    {    
         while(EECR & (1<<EEPE));            //.. Ждем завершения предыдущей операции с памятью
         cli();
       
         EEAR = ucAddress;                //.. Запишем адрес ячейки
       
         EECR |= (1<<EERE);                //.. Старт чтения EEPROM
         sei();
       
         return EEDR;                //.. Возвращаем полученные данные
    }
     
    Здесь всё просто и понятно)))
     
  11. Vovka

    Vovka Гик

    parovoZZ, что такое указатель и как его готовить я в курсе. Скольки байтовая адресация не принципиально - разговор шел о том, как написали функции, вводящие в некоторое заблуждение! (портирую на Visual c++, эмулируя работой через файл)
    По три вида для чтения и записи, но при этом используют три вида указателя для двухбайтовой адресации!
    Гораздо проще было бы написать:
    Код (C++):

    void writeEEPROM( uint16_t ucAddress, uint8_t ucData);
    void writeEEPROM( uint16_t ucAddress, uint16_t ucData);
    void writeEEPROM( uint16_t ucAddress, uint32_t ucData);

    void readEEPROM( uint16_t ucAddress, uint8_t &ucData);
    void readEEPROM( uint16_t ucAddress, uint16_t &ucData);
    void readEEPROM( uint16_t ucAddress, uint32_t &ucData);
     
    Код с ошибкой!
     
  12. parovoZZ

    parovoZZ Гуру

    где там ошибка? Возможно, в 2560 по-другому названы регистры или биты. Даташит открой да подправь.

    В большинстве случаев проще передать именно указатель на данные, а не копировать их туда-сюда.
     
  13. parovoZZ

    parovoZZ Гуру

    ну...напиши свои функции. В даташите вся информация есть. Можешь даже на ассемблере. @a1000 заготовкой поделился.
     
  14. Vovka

    Vovka Гик

    Не в регистрах ошибка, а в логике!
    Не согласен: проще передать адрес в EEPROM и адрес переменной. Спорить не буду - каждый готовит на свой вкус...
     
  15. parovoZZ

    parovoZZ Гуру

    где же?
     
  16. Vovka

    Vovka Гик

    что такое прерывания и как их готовить...
     
    Последнее редактирование: 8 ноя 2020
  17. Asper Daffy

    Asper Daffy Иксперд

    Жаль только, что неправильно :-(
     
    SergeiL и Vovka нравится это.
  18. parovoZZ

    parovoZZ Гуру

    где неправильно?
     
  19. Asper Daffy

    Asper Daffy Иксперд

    Так вроде в #36 коллега уже начал объяснять, дал намёк. Не буду ему мешать, сам объяснит, раз уж начал.

    (я уж не говорю про всякую мелочёвку типа наглого "sei" безо всякой проверки, а что там было до вызова, и прочих мелочей, которые на скорость не влияют, но глаза режут)
     
  20. SergeiL

    SergeiL Оракул Модератор

    Детально не вникал, но сразу бросаются в глаза две ошибки в одной строке.