Перейти к содержанию
    

Чтение EEPROM в STM32L152

Добрый день!

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

uint8_t                *Addr = 0x8080000;

Компилятор не позволяет. NULL позволяет присваивать, &.. тоже,  а конкретное число нет.

Не подскажет ли кто как считать байт по конкретному адресу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

по аналогии (память в общем адресном пространстве) в МК от Renesas делаю так 

uint8_t data;

data = *((uint8_t*)0x"АДРЕС");

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, JohnKorsh сказал:

Пытаюсь так:

uint8_t                *Addr = 0x8080000;

В языке C, к счастью, нет неявного приведения типа из целого в указатель. Вам нужно сделать явное приведение типа:

uint8_t const * const Addr = (uint8_t const *)0x8080000;

const я добавил от себя, чтобы компилятор не дал вам совершить глупые ошибки.

 

Но гораздо более наглядно объединить все ваши данные в const volatile структуру и эту структуру разместить в соответствующей секции, расположение которой задать компоновщику. const даст вам по рукам при попытке прямой записи в эту структуру, а volatile не позволит компилятору повыдергивать из нее известные на этапе компиляции значения и вставить константами прямо в код. И не нужны будут указатели.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, JohnKorsh said:

 

Добрый вечер!
Продолжаю работать с EEPROM.
В моём исполнении работает нестабильно.
Работаю через HAL. Да, пытался найти примеры - в HAL есть примеры EEPROM, но это EEPROM внешняя с SPI иди I2C.
Вот код тестовой программы:

  HAL_FLASHEx_DATAEEPROM_Unlock ();   // Обеспечиваю доступ к EEPROM
  for (Test = 0; Test < 100; Test++)
   {
     IWDG->KR = 0xAAAA;                                // Watchdog reset
//
    HAL_FLASHEx_DATAEEPROM_Erase(FLASH_TYPEERASEDATA_BYTE, FLASH_EEPROM_BASE + Test); // <- 1
    HAL_FLASHEx_DATAEEPROM_Program(FLASH_TYPEPROGRAMDATA_FASTBYTE, FLASH_EEPROM_BASE + Test, Test); // <- 2
         
    Min = Rd_Byte_EEPR (FLASH_EEPROM_BASE + RSSI_Level); 
   }    
 HAL_FLASHEx_DATAEEPROM_Lock ();

В EEPROM в результате предыдущих тестов записались, начиная с адреса FLASH_EEPROM_BASE, следующие данные 
0x55, 0x00, 0x00, 0x00, 0x37, ....
Эти данные не стираются функцией, помеченной 1- при запуске под отладчиком в переменной Min они читаются, вместо 00, 01, 02,... как ожидалось.
В некоторых сессиях отладки программа зависает в точках 1 или 2. Приходится делать стирание программной Flash.
Не подскажет ли кто причину?
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 5/8/2019 at 5:42 PM, JohnKorsh said:

Добрый день!
Не получается грамотно обращаться с EEPROM.
Конкретно - не могу стереть - для данной EEPROM это записать 0x00.
В Reference Manual написано, что при записи значение данных для записи не должно быть 0x00.
(Data EEPROM Byte Write
This operation is used to write a NON NULL(1) byte to the data EEPROM - p. 69) 
Поясните, пожалуйста, как стереть байт в EEPROM.

Вот мой код:
//----------------------------------------------------------------
void Wr_Byte_EEPR (uint32_t   Addr, uint8_t    Data)
 {
    IWDG->KR = 0xAAAA;                // Watchdog reset.
//     
   if ((Addr < FLASH_EEPROM_BASE) | (Addr > FLASH_EEPROM_END))
    {
     return; 
    }         
//    
  if (Data != 0)
  {        
    *(__IO uint8_t *)Addr = Data;
    FLASH_WaitForLastOperation(MY_FLASH_TIMEOUT_VALUE);     
  }     
 else
 {
    HAL_FLASHEx_DATAEEPROM_Erase (FLASH_TYPEERASEDATA_BYTE, Addr);  // <- !!!
    FLASH_WaitForLastOperation(MY_FLASH_TIMEOUT_VALUE);     
 }     

...

  HAL_FLASHEx_DATAEEPROM_Unlock ();                                     // Unlock of the EEPROM                                
  HAL_FLASHEx_DATAEEPROM_EnableFixedTimeProgram    ();       // Set of the regime erase before write
  FLASH_WaitForLastOperation(MY_FLASH_TIMEOUT_VALUE);       // For to be on the safe side.

// В функциях HAL     задано FLASH_TIMEOUT_VALUE 50 Секунд. Наверное, в расчёте на Program memory.
// Я посмотрел в DataSheet - там максимальное время стирания/записи для EEPROM 3,94 ms., задал
// MY_FLASH_TIMEOUT_VALUE = 50 ms (пишу в EEPROM побайтно) 

  Wr_Byte_EEPR (FLASH_EEPROM_BASE, 0x1);       // Пишет нормально. 
  Wr_Byte_EEPR (FLASH_EEPROM_BASE, 0x0);       // Зависает в точке, помеченной !!! 
...
//----------------------------------------------------------------

В функции HAL HAL_FLASHEx_DATAEEPROM_Erase после проверок правильности данных всё сводится к 
    if(TypeErase == FLASH_TYPEERASEDATA_BYTE)
    {
      /* Write 00h to valid address in the data memory */
      *(__IO uint8_t *) Address = (uint8_t)0x00;       // Здесь и виснет.
    }

То есть, я не могу записать 0x00, всё остальное пишется нормально.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нашёл. Может, кому пригодится. Оказывается STM32 умеет стирать EEPROM только словами, хотя в HAL есть функция стирания по байтам. Перед записью стираю рабочую область EEPROM.

Вот мой код - помещаю перед записью, может, есть решение поизящнее.

 
// Erase of the EEPROM work area  
     
    HAL_FLASHEx_DATAEEPROM_Erase (FLASH_TYPEERASEDATA_WORD, FLASH_EEPROM_BASE);  
    HAL_FLASHEx_DATAEEPROM_Erase (FLASH_TYPEERASEDATA_WORD, FLASH_EEPROM_BASE + 4);  
    HAL_FLASHEx_DATAEEPROM_Erase (FLASH_TYPEERASEDATA_WORD, FLASH_EEPROM_BASE + 8);  

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, JohnKorsh сказал:

Нашёл. Может, кому пригодится. Оказывается STM32 умеет стирать EEPROM только словами, хотя в HAL есть функция стирания по байтам. Перед записью стираю рабочую область EEPROM.

Ну, то что стирается только словами (4х) или двойными словами (8х) это описано у них понятно. Там суммарно непонятно описан их весь зоопарк команд. Я тоже с этим разбирался, почитайте, может не видели:

EEPROM в STM32L151

Стирание в явном виде нужно только для Cat.1 devices. Для всех других нет ограничений команд записи. Можно в ненулевой байт/полуслово/слово писать хоть нули, хоть другой код, все работает. Поэтому я применяю только команды записи.

Причем для МК и HAL все равно, вызовите вы функцию "быстрой записи" или "обычной". Там все равно все одинаково.
Я применяю быструю, т.к. она в явном виде очищает бит быстрой записи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...