
Микроконтроллер 80C51F120 от Silicon Labs оснащён 128 КБ встроенной флеш-памяти, разделённой на 512 страниц по 256 байт. Для записи данных в энергонезависимую память требуется соблюдать специфический протокол: разблокировка доступа, стирание страницы, запись байтов и верификация. Ошибки на любом этапе приводят к повреждению данных или отказу записи. В этом примере рассмотрим запись 16-битной переменной в заданный адрес флеш с использованием регистров FLSCL, PSCTL и FLKEY.
Перед началом работы убедитесь, что тактовая частота не превышает 25 МГц – превышение этого значения вызывает сбои при записи. Страница флеш стирается только целиком, поэтому предварительно сохраните критичные данные в ОЗУ или другой странице. Для записи используйте команду MOVX с косвенной адресацией через регистр DPTR. Пример кода ниже демонстрирует запись значения 0xABCD по адресу 0x1000, расположенному на странице 4 (адреса 0x1000–0x10FF).
После записи обязательно выполните верификацию: считайте данные и сравните с исходным значением. Если результат не совпадает, повторите процедуру с увеличенной задержкой между операциями (рекомендуется 10–50 мкс). Избегайте частых перезаписей одной страницы – ресурс флеш ограничен 20 000 циклов стирания/записи. Для продления срока службы используйте алгоритмы выравнивания износа или резервные страницы.
Запись переменной во флеш 80c51f120: пример кода

Микроконтроллер 80C51F120 (Silicon Labs) поддерживает запись во флеш-память через регистры FLSCL и PSCTL. Перед записью необходимо разрешить доступ к флешу, установив бит FLWE в регистре FLSCL и активировать режим записи через PSWE в PSCTL. Пример кода для записи байта по адресу 0x1000:
- Настройка тактовой частоты:
OSCICN = 0x83;(внутренний генератор 24.5 МГц). - Разрешение записи:
FLSCL = 0x01;(битFLWE). - Активация режима записи:
PSCTL = 0x01;(битPSWE). - Запись данных:
*(unsigned char xdata *)0x1000 = 0xAA;. - Отключение режима записи:
PSCTL = 0x00;.
Для записи массива данных используйте цикл с проверкой границ флеш-сектора (512 байт для 80C51F120). Перед записью очищайте сектор командой FLKEY = 0xA5; FLKEY = 0xF1; и устанавливайте бит PSEE в PSCTL. Пример записи 16 байт с адреса 0x1000:
- Разрешите стирание:
PSCTL = 0x03;(битыPSWEиPSEE). - Сотрите сектор:
*(unsigned char xdata *)0x1000 = 0;. - Отключите стирание:
PSCTL = 0x01;. - Запишите данные в цикле:
for (i = 0; i < 16; i++) { *(unsigned char xdata *)(0x1000 + i) = data[i]; } - Завершите запись:
PSCTL = 0x00;.
Выбор регистров и адресов для записи во флеш-память микроконтроллера

Для записи данных во флеш-память микроконтроллера 80C51F120 критически важен выбор регистров и адресного пространства. Основные регистры, участвующие в процессе: FLSCL (Flash Scale Register) – определяет тактовую частоту записи/стирания, PSCTL (Program Store Control) – управляет режимами записи и стирания, и FLKEY (Flash Lock and Key) – обеспечивает защиту от случайной модификации. Адресное пространство флеш-памяти разделено на страницы по 512 байт (0x0000–0xFBFF для кода, 0xFC00–0xFFFF – загрузочный сектор). Для записи используйте только адреса в диапазоне 0x0000–0xFBFF, избегая загрузочного сектора, если не требуется его модификация. Перед записью проверяйте бит BUSY в регистре PSCTL – операция возможна только при его сбросе (0).
- Регистр
FLSCL: установите значение0x86для тактовой частоты 24.5 МГц (максимальная скорость записи). При других частотах используйте формулу:FLSCL = (SYSCLK / 1000000) - 1, гдеSYSCLK– частота в Гц. - Регистр
PSCTL: битPSEE(1) разрешает стирание страницы, битPSWE(1) – запись байта. После установки битов выполните запись по целевому адресу, затем сбросьте их для защиты от случайных операций. - Регистр
FLKEY: перед любой операцией с флеш требуется записать последовательность0xA5, затем0xF1. Игнорирование этого шага блокирует доступ. - Адресация: для записи массива данных используйте инкрементальные адреса в пределах одной страницы (512 байт). При переходе на следующую страницу предварительно стирайте её командой
MOVX @DPTR, Aс установленным битомPSEE.
Инициализация тактового сигнала и настройка режима программирования

Для микроконтроллера 80C51F120 тактовый сигнал задаётся через регистр CKCON (Clock Control Register). По умолчанию используется внутренний генератор на 12 МГц, но для стабильной работы в режиме программирования флеш-памяти рекомендуется переключиться на внешний кварцевый резонатор с частотой 24 МГц. Это снижает вероятность ошибок записи из-за нестабильности тактового сигнала. Пример инициализации:
CKCON = 0x01; // Включение внешнего генератора
Если используется внутренний генератор, его частоту можно скорректировать через регистр OSCICN, но для программирования флеш это нежелательно из-за возможных джиттеров.
Режим программирования флеш-памяти активируется установкой бита FPD (Flash Programming Disable) в регистре FLSCL (Flash Scale Register). Перед записью необходимо убедиться, что тактовая частота не превышает 25 МГц – превышение этого порога приводит к сбоям. Пример настройки:
FLSCL = 0x80; // Разрешение программирования, частота ≤ 25 МГц
После установки FPD микроконтроллер переходит в режим, где доступ к флеш-памяти осуществляется через специальные регистры FLKEY и PSCTL. Без корректной инициализации этих регистров запись будет заблокирована аппаратно.
Регистр PSCTL (Program Store Control) управляет режимами доступа к флеш. Для записи необходимо установить бит PSEE (Program Store Erase Enable) и PSWE (Program Store Write Enable). Пример:
PSCTL = 0x03; // Разрешение стирания и записи
Перед каждой операцией записи или стирания требуется разблокировка через регистр FLKEY. Последовательность команд должна строго соблюдаться: сначала записывается 0xA5, затем 0xF1. Нарушение порядка приведёт к игнорированию операции.
Для стабильной работы в режиме программирования рекомендуется отключать прерывания на время записи. Это предотвращает конфликты доступа к флеш-памяти. Пример:
EA = 0; // Глобальное отключение прерываний
После завершения записи прерывания можно включить обратно. Если программирование выполняется в реальном времени, используйте таймеры для периодического сохранения состояния, но избегайте записи во флеш во время активных прерываний.
При использовании внешнего тактового сигнала проверьте стабильность источника. Нестабильность частоты более ±1% может вызвать ошибки верификации после записи. Для тестирования тактового сигнала используйте осциллограф или логический анализатор. Если частота плавает, замените кварцевый резонатор или конденсаторы обвязки.
После настройки режима программирования выполните тестовую запись в неиспользуемую область флеш-памяти. Проверьте корректность данных с помощью чтения и сравнения. Если возникают ошибки, снизьте тактовую частоту или увеличьте задержки между операциями. Для 80C51F120 минимальная задержка между записью и стиранием составляет 10 мкс.
Подготовка данных и буфера перед записью в сектор флеш

Проверьте целостность данных перед записью с помощью контрольной суммы или CRC. Для 80C51F120 эффективен алгоритм CRC-8 с полиномом 0x07, который легко реализуется на ассемблере или C. Рассчитайте контрольную сумму для всего буфера и сохраните её в последних двух байтах сектора. Это позволит быстро верифицировать данные после чтения без необходимости повторного расчёта. Пример кода на C для CRC-8:
unsigned char crc8(unsigned char *data, unsigned int len) {
unsigned char crc = 0;
while (len--) {
crc ^= *data++;
for (unsigned char i = 0; i < 8; i++)
crc = (crc << 1) ^ ((crc & 0x80) ? 0x07 : 0);
}
return crc;
}
Убедитесь, что целевой сектор флеш-памяти предварительно стёрт. Для 80C51F120 стирание выполняется командой 0x20 через интерфейс программирования, но перед этим проверьте статус сектора с помощью команды 0x05. Если сектор не стёрт, запись завершится ошибкой или приведёт к повреждению данных. Используйте таймаут не менее 10 мс для операции стирания – это гарантирует завершение процесса даже при нестабильном питании.
Для минимизации износа флеш-памяти применяйте стратегию wear leveling на уровне приложения. Храните в ОЗУ карту использования секторов и выбирайте наименее изношенный сектор для записи. В 80C51F120 доступно 128 КБ флеш-памяти, разделённой на 256 секторов по 512 байт. При частых перезаписях ограничьте количество циклов стирания/записи для одного сектора до 10 000 – это предел для большинства флеш-ячеек на базе технологии 0.35 мкм.
Перед началом записи отключите все прерывания, которые могут повлиять на стабильность процесса. В 80C51F120 используйте инструкцию EA = 0 для глобального запрета прерываний. После завершения записи восстановите их состояние. Для буфера в ОЗУ выделите область с выравниванием по границе 4 байта – это ускоряет доступ к данным при использовании DMA или оптимизированных инструкций процессора. Если данные критически важны, дублируйте их в двух разных секторах и добавляйте метку времени для восстановления последней корректной версии при сбоях.
Использование команд стирания сектора перед новой записью
Микроконтроллеры семейства 80C51F120 требуют предварительного стирания флеш-сектора перед записью новых данных. Каждый сектор имеет размер 512 байт, и попытка записи без стирания приведёт к искажению данных. Команда стирания активируется через регистр FMCON (Flash Memory Control Register), где необходимо установить бит ERASE (бит 0) и указать адрес сектора в регистре FMADRH:FMADRL. После записи команды в FMCON микроконтроллер выполняет стирание за ~2 мс, что требует ожидания завершения операции через проверку бита BUSY (бит 1) в том же регистре.
Для надёжной работы рекомендуется использовать проверку успешности стирания. После завершения операции бит BUSY сбрасывается, но дополнительно стоит убедиться в отсутствии ошибок через бит ERROR (бит 2) в FMCON. Если бит установлен, операция не выполнена, и её следует повторить. Пример кода: перед записью данных в сектор 0x1000 необходимо выполнить стирание, дождаться завершения и проверить ERROR. Игнорирование этой проверки может привести к записи в повреждённый сектор.
Секторы флеш-памяти в 80C51F120 имеют ограниченный ресурс перезаписи – около 10 000 циклов. Частое стирание одного и того же сектора ускоряет его деградацию. Чтобы продлить срок службы, используйте алгоритмы распределения нагрузки, например, запись данных в разные секторы поочерёдно. Также избегайте стирания сектора, если новые данные идентичны уже записанным, – это сокращает количество ненужных операций.
При работе с критически важными данными добавьте контрольную сумму или CRC для проверки целостности после записи. Например, после стирания и записи данных в сектор 0x1800 вычислите CRC записанных байтов и сохраните его в отдельной области флеш. При чтении данных повторно вычислите CRC и сравните с сохранённым значением. Это позволит обнаружить ошибки, вызванные неполным стиранием или сбоями во время записи.
Реализация цикла записи байтов с проверкой статуса операции
Для микроконтроллера 80C51F120 запись во флеш-память требует строгого контроля статуса операции через регистр FLSCL и бит BUSY в регистре PSCTL. Цикл записи должен включать проверку готовности флеш-контроллера перед каждой операцией, так как время записи одного байта составляет 20–40 мкс. Пример структуры цикла:
FLASH_WriteByte: mov FLADDR, #LOW(target_address) ; Установка адреса mov FLADDRH, #HIGH(target_address) mov FLDATA, A ; Байт для записи orl PSCTL, #0x01 ; Разрешение записи mov FLSCL, #0x82 ; Разрешение флеш-операций (2 такта на цикл) nop ; Обязательная задержка nop anl PSCTL, #0xFE ; Запрет записи ret
Проверка статуса выполняется через бит BUSY (бит 0 в PSCTL). Если он установлен, флеш-контроллер занят. Цикл ожидания готовности реализуется так:
WaitFlashReady: jb PSCTL.0, WaitFlashReady ; Проверка BUSY ret
Для записи массива байтов используйте цикл с инкрементом адреса и проверкой каждого байта. Пример для 16 байт:
mov R0, #0x00 ; Счетчик байтов mov DPTR, #source_data ; Адрес исходных данных WriteLoop: mov A, R0 movc A, @A+DPTR ; Чтение байта из памяти программ lcall FLASH_WriteByte ; Запись байта lcall WaitFlashReady ; Ожидание готовности inc R0 cjne R0, #0x10, WriteLoop ; Повтор для 16 байт
Ошибки записи возникают при нарушении временных характеристик или попытке записи в защищенные сектора. Для диагностики используйте регистр FLSTAT (бит PVIOL – нарушение защиты, бит ACCERR – ошибка доступа). При обнаружении ошибки сбросьте биты через запись 1 в соответствующие поля FLSTAT перед повторной попыткой.