Como programar una primera clave con eeprom

#1
Saludos miembros de la comunidad, tengo una pequeña duda. Estoy programando en MPLAB con un pic16f876a un mundano programa que al ingresar una clave de 4 digitos por medio de una lcd me permita acceder a una opción de modificar la clave (si la clave fue correcta) sino pues un mensaje de contraseña invalida. El programa esta casi listo pero no logro programar una forma de ingresar una contraseña para la primera corrida . Esto es lo que tengo:

C++:
#include <xc.h>
#define _XTAL_FREQ 8000000

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#define RS RA0
#define EN RA1

#define F1 RB0
#define F2 RB1
#define F3 RB2
#define F4 RB3
#define C1 RB4
#define C2 RB5
#define C3 RB6


void CONFIGURACION_LCDP(void);
void LCDP(unsigned char INFO, unsigned char TIPO);
void LCDP_TEXTOS (const char *CAD, unsigned char POSIC);
unsigned char TECLADO(void);
unsigned int LEER_TECLADO(unsigned char DIG, unsigned char POSIC);
unsigned int ESCRIBIR_TECLADO(unsigned char DIG, unsigned char POSIC);
unsigned char LEER_EEPROM(unsigned char DIRECCION);
void ESCRIBIR_EEPROM(unsigned char DIRECCION, unsigned char DATO);
void CONDICION_EEPROM1(unsigned char EEPRM3);
void CONDICION_EEPROM2(unsigned char EEPRM4);

unsigned int CLAVE, CODIGO, SUMA, UNIDAD_DE_MIL, CENTENA;
unsigned char DECENA, UNIDAD;

void main (void)
{
    TRISA=0b00000000;
    PORTA=0b00000000;
    TRISB=0b01110000;
    PORTB=0b00000000;
    TRISC=0b00000000;
    PORTC=0b00000000;
    ADCON1=0b00000110;
    
    CONFIGURACION_LCDP();
 
    LCDP_TEXTOS("BIENVENIDO",0x83);
    __delay_ms(500);
    LCDP(0b0000001,0);
    
        
    
    while(1)
    {
      
        LCDP_TEXTOS("Ingrese Clave:",0x80);
        LEER_TECLADO(4,0xC6);
        CODIGO=CLAVE;
        LCDP(0b00000001,0);
        LEER_EEPROM(3);
        UNIDAD_DE_MIL=EEDATA*1000;
        LEER_EEPROM(2);
        CENTENA=EEDATA*100;
        LEER_EEPROM(1);
        DECENA=EEDATA*10;
        LEER_EEPROM(0);
        UNIDAD=EEDATA;
        SUMA=UNIDAD_DE_MIL + CENTENA + DECENA + UNIDAD;
        
        
        if(CODIGO==SUMA)
        {
            LCDP_TEXTOS("CLAVE CORRECTA",0x80);
            __delay_ms(1000);
            LCDP(0b00000001,0);
            LCDP_TEXTOS("Ingrese nueva",0x80);
            LCDP_TEXTOS("Clave:",0xC0);
            ESCRIBIR_TECLADO(4,0xC6);
            LCDP(0b00000001,0);
            LCDP_TEXTOS("Clave Guardada",0x80);
            __delay_ms(500);
        }
        else
        {
            LCDP_TEXTOS("CLAVE INCORRECTA",0x80);
            LCDP_TEXTOS("Deje la droga",0xC0);
            __delay_ms(1000);
            LCDP(0b00000001,0);
        }
    }
}

void CONFIGURACION_LCDP(void)
{
    LCDP(0b00111100,0);
    LCDP(0b00010100,0);
    LCDP(0b00001100,0);
    LCDP(0b00000110,0);
    LCDP(0b00000001,0);
}

void LCDP(unsigned char INFO, unsigned char TIPO)
{
RS    = TIPO;
PORTC = INFO;
EN    =1;   
__delay_ms(2);
EN    =0;   
__delay_ms(2);
}

void LCDP_TEXTOS (const char *CAD, unsigned char POSIC)
{
unsigned char CARACTER;
LCDP(POSIC,0);
while(*CAD!=0x00)
  {
CARACTER=*CAD;   
LCDP(CARACTER,1);   
*CAD++;   
  }
}

unsigned char TECLADO(void)
{
    unsigned char TECLA=12;
    while (TECLA==12)
    {
       F1=1;
       {
       if((F1==1)&(C1==1)){__delay_ms(250); TECLA=1; } 
       if((F1==1)&(C2==1)){__delay_ms(250); TECLA=2; }
       if((F1==1)&(C3==1)){__delay_ms(250); TECLA=3; }
       }
       F1=0;
       F2=1;
       {       
       if((F2=1)&(C1==1)){__delay_ms(250);TECLA=4; }
       if((F2=1)&(C2==1)){__delay_ms(250);TECLA=5; }
       if((F2=1)&(C3==1)){__delay_ms(250);TECLA=6; }
       }
       F2=0;
       F3=1;
       {
       if((F3=1)&(C1==1)){__delay_ms(250);TECLA=7; }
       if((F3=1)&(C2==1)){__delay_ms(250);TECLA=8; }
       if((F3=1)&(C3==1)){__delay_ms(250);TECLA=9; }
       }
       F3=0;
       F4=1;
       {
       if((F4=1)&(C1==1)){__delay_ms(250);TECLA=10; }
       if((F4=1)&(C2==1)){__delay_ms(250);TECLA=0;  }
       if((F4=1)&(C3==1)){__delay_ms(250);TECLA=11; }
       }
       F4=0;
    }
    return(TECLA);
}

unsigned int LEER_TECLADO(unsigned char DIG, unsigned char POSIC)
{
    CLAVE=0;
    unsigned char CONT=0,VALOR;
    LCDP(POSIC,0);
    while(CONT<DIG)
    {
        VALOR=10;
        while(VALOR==10||VALOR==11)
        {
            VALOR = TECLADO();
        }
            LCDP(VALOR+48,1);
            CLAVE=CLAVE*10+VALOR;
            CONT++;
    }
    return(CLAVE);
}

unsigned int ESCRIBIR_TECLADO(unsigned char DIG, unsigned char POSIC)
{
    
    CLAVE=0;
    unsigned char CONT=0,VALOR;
    LCDP(POSIC,0);
    while(CONT<DIG)
    {
        VALOR=10;
        while(VALOR==10||VALOR==11)
        {
            VALOR = TECLADO();
        }
            LCDP(VALOR+48,1);
            CLAVE=CLAVE*10+VALOR;
            ESCRIBIR_EEPROM(CONT,VALOR);
            CONT++;
    }
    return(CLAVE);
}

unsigned char LEER_EEPROM(unsigned char DIRECCION)
{
    EEADR=DIRECCION;
    EECON1bits.EEPGD=0;
    EECON1bits.RD=1;
    return (EEDATA);
}

void ESCRIBIR_EEPROM(unsigned char DIRECCION, unsigned char DATO)
{
    while(EECON1bits.WR==1);
    EEADR=DIRECCION;
    EEDATA=DATO;
    EECON1bits.EEPGD=0;
    EECON1bits.WREN=1;
    INTCONbits.GIE=0;
    EECON2=0x55;
    EECON2=0xaa;
    EECON1bits.WR=1;
    INTCONbits.GIE=1;
    EECON1bits.WREN=0;
    while(EECON1bits.WR==1);
}
 
#2
Hola, por un lado veo que en varios if, utilizas un sólo =, siendo que deben ser dos ==, sino en lugar de comparar estás asignando.
Respecto a grabar datos en EEPROM por primera vez. Lo que suelo hacer es, comparar una dirección EEPROM, con un valor de referencia, sino cumple la condición, grabo en esa dirección el dato que deseo, de lo contrario lo leo para comparar donde sea necesario.
 
#3
Gracias por tu respuesta, me han dicho que el PIC16f876a guarda por defecto un valor en la memoria cuando no se le ha asignado nada, pero he leído el datasheet y una guía proporcionada por el docente y no me hablan del tema. si supiera como citar ese valor en esa dirección podría implementar una comparación para asignar una clave nueva
 
#4
A veces se le pueden poner valores a manos en el programador.
Y si no, haz un checksum, Cómo no coincidirá entras a una rutina que pide los valores por primera vez y los programa en la EEPROM junto con el checksum a la siguiente vez ya no lo pregunta porque en checksum está bien.
 
#6
El valor por defecto de la EEPROM de todos los PIC que conozco es de $FF(dec 255).
Verifica cuando arranca el programa si esta en esos valores, entonces es por que nunca se grabo una calve por lo que procedes a almacenar una que tu quieras.
La próxima vez que arranques tendrá cargado los valores que almacenaste y por ende obviara el almacenar uno.

Saludos.


Ric.
 
#7
listo colega problema resuelto, gracias por ese dato y a todos por sus consejos, espero que el código le sea de provecho a alguno, funciona 10/10 en el proteus
 
Arriba