Запись/чтение EEPROM микроконтроллера

Здесь приведён несложный скетч, демонстрирующий функции чтения и записи памяти EEPROM микроконтроллера Arduino с помощью библиотеки VEduino.

Скетч Arduino чтения/записи EEPROM

К аналоговому входу Analog In 0 микроконтроллера Arduino подключен потенциометр (см. Как подключить к Arduino...). Вращением потенциометра изменяется время задержки мигания светодиода на выводе Digital 13. Через монитор порта Serial Monitor Arduino IDE можно подавать команды:

  • R -- считать значение задержки из EEPROM

  • W -- записать текущее значение потенциометра в EEPROM

После сброса микроконтроллера из EEPROM считывается значение, которое используется как время задержки мигания светодиода, но если начать поворачивать потенциометр, то как время задержки мигания светодиода используется уже текущее значение, задаваемое потенциометром. Чтобы светодиод мигал не с текущим, а с сохранённым временем задержки, нужно прочитать значение задержки из EEPROM (команда R).

Скетч использует библиотеку VEduino (скачать), после установки библиотеки его можно найти в меню Файл / Примеры / VEduino / VEduino_EEPROM.

Ниже приведён код скетча (скачать):

/**

* Данный скетч - из примеров библиотеки VEduino.

* Он демонстрирует, как читать и записывать EEPROM.

*

* Подключите потенциометр к входу A0 платы Adruino UNO.

* Вращением потенциометра регулируется частота мигания светодиода D13.

* Используйте Монитор порта Arduino IDE для чтения и записи текущего значения

* потенциометра в памяти EEPROM микроконтроллера:

* Введите W - чтобы записать текущее значение.

* Введите R - чтобы прочитать сохранённое значение.

*

* http://sites.google.com/site/vanyambauseslinux/biblioteka-ve_avr

*/

#include <ve_avr.h> // Данный скетч использует библиотеку VEduino.


#define LED_PIN 13 // Светодиод, который будет мигать.


// Эта переменная объявлена как volatile, поскольку её значение изменяется в обработчике прерывания.

volatile bool bLedOn = false; // Флаг состояния светодиода (включен/выключен)


uint16_t potValue; // Предыдущее значение потенциометра.

uint16_t ledBlinkDelay; // Задержка между импульсами светодиода LED.

bool usePotValue;


void setup()

{

pinMode(LED_PIN, OUTPUT); // Настройка вывода LED_PIN в режим вывода.

DEV_EEPROM[0] >> ledBlinkDelay; // Читаем задержку между импульсами, сохранённую в EEPROM по адресу 0

potValue = analogRead(0) << 6; // Значение потенциометра, умноженное на 2 шесть раз (на 64).

usePotValue = false; // Использовать значение из EEPROM, а не текущее значение потенциометра.

DEV_TIMER1.setClockSelect(TimerW::Prescaler_64); // 16 МГц / 64 = 250 кГц. Timer1 будет

// увеличивать значение регистра TCNT1 каждые 4 мс.

DEV_TIMER1.setWaveGenMode(TimerW::FastPWM_OCRA); // Timer1 будет сравнивать значение регистра TCNT1

// со значением в регистре OCR1A и

// каждый раз, когда TCNT1 == OCR1A

DEV_TICTRL1.outCompIntEnableA(); // обработчик вектора прерывания TIMER1_COMPA_vect

// вызываться будет.

Serial.begin(19200); // Будет использоваться Монитор порта.

// Введите W - чтобы сохранить текущее значение потенциометра.

// Введите R - чтобы прочитать сохранённое значение.

interrupts(); // Разрешить прерывания.

Serial.println("VEduino EEPROM example");

Serial.println("Type R or W");

}


void loop()

{

uint16_t newPotValue = analogRead(0) << 6; // Прочитать значение потенциометра и умножить его на 64.

if (! usePotValue) {

if ((newPotValue & 0xF800) != (potValue & 0xF800)) {

usePotValue = true; // Использовать текущее значение потенциометра.

ledBlinkDelay = newPotValue;

}

}

else

ledBlinkDelay = newPotValue;

potValue = newPotValue;

if (bLedOn) // Если светодиод нужно включить

digitalWrite(LED_PIN, HIGH); // выставляем высокий уровень на выводе LED_PIN.

else

digitalWrite(LED_PIN, LOW); // в противном случае - низкий уровень.

if (Serial.available()) { // Прочитать команду из последовательного порта.

char ch = Serial.read();

switch (ch) {

case 'R': // Команда чтения READ

case 'r':

Serial.print("Reading value... ");

DEV_EEPROM[0] >> ledBlinkDelay; // Читаем EEPROM адрес 0

Serial.print(ledBlinkDelay);

Serial.println(" OK");

usePotValue = false;

break;

case 'W': // Команда записи WRITE

case 'w':

Serial.print("Writing value... ");

DEV_EEPROM[0] = newPotValue; // Записываем в EEPROM по адресу 0

DEV_EEPROM[0] >> ledBlinkDelay; // Читаем записанное значение

Serial.print(ledBlinkDelay);

Serial.println(" OK");

usePotValue = false;

break;

default:

break;

}

}

}


// Обработчик прерывания DEV_TIMER1 Output Compare A

ISR(TIMER1_COMPA_vect)

{

DEV_TIMER1.setOutputCompareA(ledBlinkDelay); // Установить интервал для следующего прерывания.

bLedOn = ! bLedOn; // Изменить флаг состояния светодиода.

}

/***** (c) Vanyamba Electronics, 2012 *****/

Автор: Андрей Шаройко <vanyamboe@gmail.com>