Главная » Статьи » Уроки по программированию stm32fxxx » Уроки по программированию stm32f4xx

Урок 4: Работа с Flash для stm32f4

Общие положения.

Зачастую возникает необходимость сохранять ряд данных в энергонезависимую память. Такими данныхми например могут быть настройки программы для МК. Если нет внешней памяти, то приходится использовать внутренние ресурсы МК. К сожалению stm32f4 не имеет в своём составе памяти EEPROM, позволяющей писать побайтно, как в ОЗУ. Потому приходится использовать Flash. Тот самый, в который пишется и сама программа. Потому работа с этой памятью требует особой осторожности. Если её не соблюдать, то вы можете легко затереть часть (а то и всю) вашей программы и устройство перестанет работать.
Чтобы этого не произошло, в микроконтроллере stm32f4 предусмотрена защита. Для доступа к записи в эту память необходимо ввести 8-мибайтный код. Если код введён не верно, доступ к flash можно будет открыть только после сброса питания с МК. Рассмотрим основные функции flash.

Структура Flash.

Flash память МК делится на сектора. Каждый сектор отвечает за заданную область памяти. Всего секторов 12. Какой сектор за какую область памяти отвечает можно узнать из приведённого ниже списка:

0. 0x08000000-0x08003FFF (16 кБ)
1. 0x08004000-0x08007FFF (16 кБ)
2. 0x08008000-0x0800BFFF (16 кБ)
3. 0x0800C000-0x0800FFFF (16 кБ)
4. 0x08010000-0x0801FFFF (64 кБ)
5. 0x08020000-0x0803FFFF (128 кБ)
6. 0x08040000-0x0805FFFF (128 кБ)
7. 0x08060000-0x0807FFFF (128 кБ)
8. 0x08080000-0x0809FFFF (128 кБ)
9. 0x080A0000-0x080BFFFF (128 кБ)
10. 0x080C0000-0x080DFFFF (128 кБ)
11. 0x080E0000-0x080FFFFF (128 кБ)

Стирать память можно только по секторам, т.е., если вам требуется записать 1 байт, вам надо куда-то скопировать ВЕСЬ сектор, стереть его и записать в него старые данные, заменив в них нужный байт. Записать же данные поверх текущих невозможно потому, что запись производится побитовым AND. Т.е. фактически это выглядит так:

ПАМЯТЬ=ПАМЯТЬ AND data, где data - ваши данные.

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

Чтение из Flash.

Тут всё просто. У нас есть адрес из которого нам надо считать. Что мы и делаем функцией:

uint32_t flash_read(uint32_t address)
{
return (*(__IO uint32_t*) address);
}

Эта функция возвращает данные из 4-х байт, начиная с заданного.

Разблокирование Flash.

Прежде чем что-то делать с памятью, как уже было написано выше, её надо сначала разблокировать. Для этого надо в регистр KEYR сначала записать число 0x45670123, а затем 0xCDEF89AB. при использовании StdPeriph это сводится к вызову функции:

FLASH_Unlock();

Если вы закончили писать в память, то вызовите функцию:

FLASH_Lock();

Стирание Flash.

Перед стиранием узнайте по приведённому выше списку в каком секторе находятся данные, подлежащие стиранию. Затем вызовите функцию:

FLASH_EraseSector(FLASH_Sector_5, VoltageRange_3);

FLASH_Sector_5 - Вместо 5 вставьте номер своего сектора.
VoltageRange_3 - это диапазон питания. Есть 4 диапазона:

VoltageRange_1 - питание от 1.8 до 2.1 В
VoltageRange_2 - питание от 2.1 до 2.7 В
VoltageRange_3 - питание от 2.7 до 3.6 В
VoltageRange_4 - питание от 2.7 до 3.6 В с внешним Vpp.

У вас скорее всего 3.3В без батарейки.

Запись в Flash.

Запись также происходит по адресу одной из команд:

FLASH_ProgramDoubleWord() - запись 8-х байт.
FLASH_ProgramWord() - запись 4-х байт.
FLASH_ProgramHalfWord() - запись 2-х байт.
FLASH_ProgramByte() - запись 1-х байт.

Первым пишется адрес куда писать, вторым данные которые писать. Функции используются в зависимости от типа записываемых данных. Пример:

FLASH_ProgramWord(0x08007F00, 0x89ABCDEF);

Пример чтения и записи.

Фунция которая записывает 12 символов в память:

#define DEVICE_ADDRESS 0x08007F00
#define DEVICE_SECTOR FLASH_Sector_1

void WriteDeviceAddress(char* data)
{
uint8_t i;

FLASH_Unlock();
FLASH_EraseSector(DEVICE_SECTOR, VoltageRange_3);

for (i=0;i<12;i++)
{
FLASH_ProgramByte(DEVICE_ADDRESS+i, data[i]);
}

FLASH_Lock();
}


Пример чтения записанных 12-ти символов:

void ReadDeviceAddress(char* Dout)
{
uint32_t temp , i, j, k=0;

for (i=0;i<3;i++)
{
temp = flash_read(DEVICE_ADDRESS+(i*4));
for (j=0;j<4;j++)
{
Dout[k] = (char)((temp>>(j*8))&0xFF);
k++;
}
}
Dout[12]=0;
}

Использование в программе:

char TempStr[20], TempStr2[20];

sprintf(TempStr2, "0001951337B1");
WriteDeviceAddress(TempStr2);
ReadDeviceAddress(TempStr);

На этом всё. Удачного использования Flash.
Категория: Уроки по программированию stm32f4xx | Добавил: Korvin (03.10.2013)
Просмотров: 21646 | Комментарии: 3 | Рейтинг: 5.0/1
Всего комментариев: 3
1 zauberer  
0
Компилятор ругается на
temp = flash_read(DEVICE_ADDRESS+(i*4));

2 Korvin  
0
Ошибку в студию, пожалуйста.

3 ШСА  
0
Спасибо за такое доступное разъяснение принципов работы с Flash. Однако, для эмуляции EEPROM в STM32F4xx надо разместить в выбранном секторе Flash-памяти изменяемые данные. А как задать для этих данных адреса размещения? Да ещё, чтобы этот сектор "обтекал" код программы?
Поделитесь знаниями - буду очень признателен.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]