Эксперимент #23: Сохранение настроек в EEPROM при сбросе питания

Рано или поздно перед разработчиком встает вопрос о сохранении настроек. Встречаются разные способы:

  • Резервный источник питания (как например в часах реального времени или многих магнитолах);
  • Постоянная запись сейвов в память – ага, но EEPROM то не резиновая;
  • Постоянная запись сейвов во внешнюю память, например во флеш – надо покупать и ждать и делать отдельную разводку;
  • Запись сейва при понижении напряжения питания до определенного уровня – то что нужно, о нем и пойдет речь дальше.

Итак нам нужно детектить низкий уровень напряжения, для этого будем юзать встроенный компаратор в pic16f628a. На один из его входов подцепим диод (падение на котором будем считать постоянным и равным примерно 0.6 В), на вторую делитель напряжения, который при нормальном питании выдает напряжение больше этих 0.6 В, а при нужном для нас уровне срабатывания падает ниже. Я взял первый попавшийся диод из закромов и на нем падение оказалось равным 0.77 В. Ну собственно вот нормальные условия:

Так это сделано, теперь надо позаботиться о том, чтобы нашему мк хватило времени на сохранение настроек. Для этого необходимо сделать как минимум две вещи:

1. Добавить на линию питания емкость достаточного номинала, причем добавить не в произвольное место, а после диода перед стабилизатором – диод предотвратит разряд емкости в неправильном направлении:

После стабилизатора ставить не стоит или придется добавлять еще один диод. Я себе поставил с запасом 2.2 мкФ.

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

Ну собственно вспоминаем, как использовать компаратор в pic16f628a, дочитываем каким образом он юзается с прерываниями и получаем что-то вот такое:

#include <htc.h>
#define _XTAL_FREQ 4000000
__CONFIG(WDTDIS & UNPROTECT & MCLREN & LVPDIS & HS & BOREN);
volatile unsigned char temp;

void main(void) {

__delay_ms(200);
__delay_ms(200);
__delay_ms(200);
__delay_ms(200);
__delay_ms(200);                  //секундная задержка после старта
temp = 0;

CMCON = 0b00000101;              //настраиваем наш компаратор

TRISA = 0xFF;
TRISB = 0x00;
TRISB0 = 1;
VRCON = 0x00;
PORTB = 0;

CMIE = 1;                       //включаем прерывания компаратора
PEIE = 1;
GIE = 1;
for (;;) {
  if (!RB0)
     {
      __delay_ms(200);
      temp++;
      PORTB = temp<<4;                     //это для проверки числа
}//if
}//for(;;)

}//main

void interrupt isr()
{
 if (CMIF)
 {
  __delay_ms(20);
    if (!C2OUT)
    {
    PORTB = 0x00;                        //выключаем все свистелки
    SLEEP();                             //и входим в стенд бай
    eeprom_write(0x04, temp);             //сейвимся
    eeprom_write(0x05, temp);
    eeprom_write(0x06, temp);
    eeprom_write(0x07, temp);
}//if c2out
CMIF = 0;
}//if
}//isr

По хорошему надо еще и организовать POR, BOR, но у нас пока что эксперимент и суть и так ясна. Видео эксперимента:

Как видно из записи, емкости вполне достаточно, чтобы записать 4 байта данных, да думаю там еще 4 спокойно запишется, но дальше тесты уже буду делать на pic16f877a когда они придут и внедрять опцию в свой усилок.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">