Jump to content

    
Sign in to follow this  
JohnKorsh

Чтение EEPROM в STM32L152

Recommended Posts

Добрый день!

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

uint8_t                *Addr = 0x8080000;

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

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

Share this post


Link to post
Share on other sites
1 час назад, JohnKorsh сказал:

Пытаюсь так:

uint8_t                *Addr = 0x8080000;

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

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

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

 

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

Share this post


Link to post
Share on other sites
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.
Не подскажет ли кто причину?
 

Share this post


Link to post
Share on other sites
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, всё остальное пишется нормально.

 

Share this post


Link to post
Share on other sites

Нашёл. Может, кому пригодится. Оказывается 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);  

 

Share this post


Link to post
Share on other sites
3 часа назад, JohnKorsh сказал:

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

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

EEPROM в STM32L151

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this