В контроллерах STM32 для этого есть специальная операция. Надо в специальный регистр записать не менее специальное значение. И ещё -- номер сектора для стирания. Секторов штук 10-15 (в разных моделях по разному).
Я стирал два сектора -- номер 10 и номер 11. По очереди.
Управляющий регистр 32-битный, там ещё куча других настроек. Трогать я их не хотел. Поэтому я воспользовался побитовым "или":
FLASH->CR|=sector<<3;//установить номер сектора: биты 3-6.
И тут я заметил, что когда я стираю сектор 10, всё хорошо. Сектор 11 -- всё хорошо. Но когда я после этого опять стираю 10 -- происходит ошибка стирания. Нет, все статусные регистры хороши, но когда я де-факто смотрю в содержимое памяти, оказывается, что она не стирается! Долго прохожу с отладчиком, грешу на недостаточное напряжение питания, на закончившиеся циклы перезаписи (хотя 10000 израсходовать не так просто).
Потом начинаю уже параноидально проверять содержимое всех управляющих и статусных регистров флеш-модуля после каждой строчки. И обнаруживаю, что стирание происходит у сектора 11, а не 10! То есть, я всё время стирал не тот сектор?!
Т.е. я передаю в регистр сектор 10, а в регистре указано:
ХХХХХХХХ ХХХХХХХ ХХХХХХХХ Х0011ХХХ
(как вы догадались, номера секторов выше были в двоичной системе счисления)
Тут я понял, что виной всему было побитовое логическое или. 1|0 будет 1. То есть после записи сектора 11 (3) в регистр, запись 10 (2) поверх него давала опять 11 (3).
Т.е. мне надо было не просто НАБИТЬ ЕДИНИЦАМИ нужные поля, а набить конкретными значениями, включая нули. Побитовое "или" тут уже не подходит. В итоге я решил проблему так:
FLASH->CR=(FLASH->CR&0xFFFFFF00)|(sector<<3);//ценные биты были только в старших трёх байтах
А ведь в ассемблере для этого есть специальная команда -- BFI.