Задача: Запись и чтение из внутренней энергонезависимой памяти EEPROM
Исходный материал: PIC16f628a и простенькая devboard.
Микроконтроллер PIC16f628a имеет на борту 128 байт EEPROM, не шибко много, но что есть то есть. Обычно в компиляторах уже есть встроенные функции записи/чтения из памяти, Hi-tech PICC не исключение, но здесь я приведу разработку своих функций с нуля. Начнем с регистра EECON1:
EEPGD — В микроконтроллере PIC16f628a не используется WRERR — флаг ошибки • 1 — операция записи прервана • 0 — операция записи прошла успешно WREN — Разрешение записи в EEPROM • 1 — Операция записи разрешена • 0 — Операция записи запрещена WR — Контрольный бит записи • 1 — Инициализация записи • 0 — Запись завершена RD — Контрольный бит чтения • 1 — Инициализация чтения • 0 — Чтение завершено
*Биты WR и WD нужно устанавливать только в «1″, сброс в низкое логическое состояние происходит автоматически, после завершения операции
Кроме этого есть еще вспомогательные регистры: Регистр EEDATA — 8 битный регистр, служит буфером, куда помещаются данные при чтении/записи. Регистр EEADR — 7 битный регистр, указывающий адрес куда будет производится запись или адрес, откуда нужно прочитать данные. Программный регистр EECON2 — регистр использующийся исключительно для операции запись в EEPROM, для успешной операции записи необходимо последовательно записывать в этот регистр следующее выражение:
EECON2=0x55;
EECON2=0xAA;
Да, еще, для EEPROM также может генерироваться прерывание — флаг EEIF устанавливается при успешной операции записи.
Порядок чтения из EEPROM: Запись нужного адреса в регистр EEADR. Установка бита RD в «1″. Данные сохранены в регистре EEDAT и готовы для использования.
Порядок записи в EEPROM: Запись нужного адреса в регистр EEADR. Запись данных в регистр EEDAT. Установка WREN в «1″. Запись в регистр EECON2 0×55 и 0хАА. Установка бита WR в «1″.
Также в даташите сильно просят отключать на время записи прерывания, вот в принципе и все. Уже можно работать с EEPROM.
Код -пример работы:
#include <htc.h> #define _XTAL_FREQ 4000000
__CONFIG(MCLRDIS & UNPROTECT & WDTDIS & LVPDIS & HS); unsigned char eeprom_read_my(unsigned char adres); // инициализация операции чтения unsigned char eeprom_write_my(unsigned char data, unsigned char adres); // инициализцация операции записи
for (;;) { PORTB = temp; // Присваиваем порту Б значение из EEPROM if (!RA1) { __delay_ms(100); if (!RA1) { if (temp < 240) { // Пишем в память значения от 16 до 240, с шагом 16 temp = temp + 16; eeprom_write_my(temp, 0x07); } else { temp = 16; eeprom_write_my(temp, 0x07); } } }