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

Работа с backup SRAM stm32f407

Приветствую всех, кто осиливает тяжкий труд по освоению чего-то от ST :wacko:

 

Вопрос - в stm32f407 якобы есть 4кило памяти с питанием от батарейки. Якобы, потому что в описаниях она есть, а вот как к ней добраться, по каким адресам и какими командами - ни в даташите, ни в референсах - неизвесно. Может есть какие примерчики или описание, а может у меня уже глаза запотели от этой доки - ткните пальцем, где это все написано.

 

ЗЫ. может нужно использовать специфические команды компилятора, пользуюсь ИАРом...

 

И еще одна "фишка" - подключил батарейку, убрав перемычку на дискавери, и включил часы, так вот ток потребления по этому пину, при выкл. питании - 15 мкА, хотя в доке - макс 4, в чем может быть дело?

Изменено пользователем mantech

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


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

Оно?

 

PWR_BackupAccessCmd(ENABLE);

 

ну и включить тактирование перед этим.

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


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

Оно?

 

PWR_BackupAccessCmd(ENABLE);

 

ну и включить тактирование перед этим.

 

Это понятно, а по каким адресам расположена эта память?? т.е. как туда писать и читать :rolleyes:

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


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

Это понятно, а по каким адресам расположена эта память?? т.е. как туда писать и читать :rolleyes:

В Memory map пишут, что от 0x4002 4000 до 0x4002 4FFF, не проверял :)

 

Память она и есть память, можно по указателю обращаться.

Можно описать как отдельную секцию, разместить в этой секции переменные и работать с ними.

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


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

В Memory map пишут, что от 0x4002 4000 до 0x4002 4FFF, не проверял :)

 

Отковырял какой-то исходник, там есть параметр - BKPSRAM_BASE. Поищу, где он задается...

 

 

/* Backup SRAM ***************************************************************/

/* Enable BKPRAM Clock */

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_BKPSRAM, ENABLE);

 

/* Write to Backup SRAM with 32-Bit Data */

for (uwIndex = 0x0; uwIndex < 0x1000; uwIndex += 4)

{

*(__IO uint32_t *) (BKPSRAM_BASE + uwIndex) = uwIndex;

}

/* Check the written Data */

for (uwIndex = 0x0; uwIndex < 0x1000; uwIndex += 4)

{

if ((*(__IO uint32_t *) (BKPSRAM_BASE + uwIndex)) != uwIndex)

{

uwErrorIndex++;

}

}

 

if(uwErrorIndex)

{

LCD_ErrLog ("BKP SRAM Number of errors = %d\n", uwErrorIndex);

}

else

{

LCD_UsrLog ("BKP SRAM write OK \n");

}

 

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


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

В Memory map пишут, что от 0x4002 4000 до 0x4002 4FFF, не проверял :)

 

Память она и есть память, можно по указателю обращаться.

Можно описать как отдельную секцию, разместить в этой секции переменные и работать с ними.

Так и есть. Проверено.

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


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

Так и есть. Проверено.

 

Вопрос еще один, как "сказать" ИАРу, что вот это -

 

union {Uint16 GlobalVar_w[VarCount];unsigned char GlobalVar_b[VarCount*2];} s_var;

#define GlobalVar s_var.GlobalVar_w

#define GlobalVarb s_var.GlobalVar_b

 

должно находиться c адреса 0x40024000 до ...?

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


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

Вопрос еще один, как "сказать" ИАРу, что вот это -

 

union {Uint16 GlobalVar_w[VarCount];unsigned char GlobalVar_b[VarCount*2];} s_var;

#define GlobalVar s_var.GlobalVar_w

#define GlobalVarb s_var.GlobalVar_b

 

должно находиться c адреса 0x40024000 до ...?

Как сказать ИАРу не знаю, но GCC я говорю так:

volatile sSTR_LINE    sstr __attribute__((section(".bkpsram")));

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


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

Как сказать ИАРу не знаю, но GCC я говорю так:

volatile sSTR_LINE    sstr __attribute__((section(".bkpsram")));

 

У долбанутого ИАра там

#pragma location = адрес

Правда для переменных прокатывает, а вот с юнионом никак не хочет...

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


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

У долбанутого ИАра там

#pragma location = адрес

Правда для переменных прокатывает, а вот с юнионом никак не хочет...

Думаю, этого мало. Вам зачем батареечная память нужна? Хранить данные, которые не уничтожаются после сброса?

Тогда нужно еще как-то сказать линкеру, чтоб не инициализировал эти данные.

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


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

В файле stm32f4xx.h должна быть строка (в Keil есть)

#define BKPSRAM_BASE ((uint32_t)0x40024000) /*!< Backup SRAM(4 KB) base address in the alias region */

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

 

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


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

Думаю, этого мало. Вам зачем батареечная память нужна? Хранить данные, которые не уничтожаются после сброса?

Тогда нужно еще как-то сказать линкеру, чтоб не инициализировал эти данные.

 

Как раз и нужна, чтоб при откл питания данные сохранялись.

"Тогда нужно еще как-то сказать линкеру, чтоб не инициализировал эти данные." - за это я как раз меньше всего волнуюсь - там есть защита от записи, которая не дает писать туда до тех пор, пока ее специально не отключишь...

 

В файле stm32f4xx.h должна быть строка (в Keil есть)

#define BKPSRAM_BASE ((uint32_t)0x40024000) /*!< Backup SRAM(4 KB) base address in the alias region */

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

 

Это я понял, только очень желательно разместить там эти массивы, которые я написал, а то придется больше 150 обращений к массиву править как через указатель, а это не айс :(

 

ЗЫ. А можно сделать так, что массив int разместить с адреса BKPSRAM_BASE и с того-же адреса массив char?

Это не будет эквивалентно union?

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


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

typedef union {u16 GlobalVar_w[128]; u8 GlobalVar_b[128*2];} s_var;
#pragma location = 0x40024000
s_var ss_var;

#define GlobalVar ss_var.GlobalVar_w
#define GlobalVarb ss_var.GlobalVar_b

 

может так

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


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

typedef union {u16 GlobalVar_w[128]; u8 GlobalVar_b[128*2];} s_var;
#pragma location = 0x40024000
s_var ss_var;

#define GlobalVar ss_var.GlobalVar_w
#define GlobalVarb ss_var.GlobalVar_b

 

может так

 

Надо попробовать B)

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

 

Вопрос - когда записываю в эту память, туда все пишется и читается, но при выкл. питания информация искажается. Там что-то еще нужно "включать" или что? сразу скажу - параллельно работают часы, которые не сбиваются, и батарейка хорошая 3в...

 

Все разобрался, там надо еще регулятор питания подключить было. Все работает, всем спасибо! :a14:

Изменено пользователем mantech

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


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

Все разобрался, там надо еще регулятор питания подключить было. Все работает, всем спасибо! :a14:

А как же часы работали?

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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