# Pic Lab, PIC16, Experiment #23: Saving data to EEPROM before the power off event

I guess, that sooner or later any developer has a question in his head – how do I save the data if the supply shut down?

There are some solutions listed:

• The reserve battery (the RTC clock, the motherboard);
• The constant saving to the memory – not nice, the EEPROM has limited cycles;
• Saving to the external memory – the complication of the PCB and the code;
• Saving when the lowering of the vdd level is detected – that what I need!

So, the goal is to detect some low supply level, for this purpose I’m going to use the internal comparator of pic16f628a microcontroller. On one of the inputs we will connect the diode (assume the voltage drop is 0.6V), the other input is connect to the voltage divider. The divider will have the level higher than 0.6V during normal operation and, obviously, when supply goes down the divider output also lowered. I just took the first diode I found in my stashes and here what do we have during normal conditions:

OK, this is done, now we need to make sure that the uC will have enough time to save the data. To do so we need to make at least two things:

1. To add to the supply voltage the capacitor of large enough nominal (before actual regulation line) and a diode to prevent discharge to the external power supply (maybe it has ground potential, who knows):

I would actually do the same at the 5V output as well.

2. To make sure that a discharge time happens as long as possible – switch off all what is glowing, sounding and doing some other stuff which consumes the power.

Refreshing the memory, how to use the comparator in the pic microcontroller, adding on top of this experiment interruptions and getting something like that:

#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