|
|
View previous topic :: View next topic |
Author |
Message |
diegostreetbob
Joined: 05 Sep 2009 Posts: 11
|
eeprom accidental data change when cold powerup |
Posted: Mon Dec 13, 2010 3:02 pm |
|
|
Hello,
In the first place thanks for your help, I've apreciated your help.
**************************
This software is a modification of original 433mhz receiver card, based in tda5200 and pic12f629. It's adapted at original hardware, work fine but when start cold (2 to 3 hours) then data in eeprom is different than the previous memorized data, and the program is unstable.
It's the first important project in C for me. The code is very low optimized, I think. But I don't think it's the problem.
Regards
Code: |
#include <12F629.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOCPD //No EE protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES MCLR //Master Clear pin enabled
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Brownout reset
#FUSES BANDGAP_HIGH
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(internal=4000000)
//#use rs232(baud=300,parity=N,xmit=PIN_A1,bits=8)//usado para debud en pruebas anteriores
#byte porta=0x05
#byte trisa=0x85
#use fast_io(a)
#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5
#zero_ram
int botondetectado=0;// en la comparacion sera asignado un valor a boton detectado
int flagalarma=1; //estara a 0 cuando se haya pulsado el boton de parada
int botonant=3;//inicializado a 3 como si fuese a partir de puerta cerrada, boton 3.
void open(void);//función abierto
void close(void);//funcion cerrado
void automatic(void);
void modoalarma(void);//función a realizar en modo alarma
#int_ext
void ext_isr(void)//funcion de interrupción, cada flaco de subida del clock se hara esta función
{
if(flagalarma==0)
{
output_low(pin_a1);
delay_us(16400);
output_high(pin_a1);
delay_us(4100);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(4100);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(8200);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(12200);
output_low(pin_a1);
delay_us(10300);
output_high(pin_a1);
}
else
{
botonant=botondetectado;
switch(botondetectado)
{
case 1:
automatic();
break;
case 2:
open();
break;
case 3:
close();
break;
}
}
}
int lectura();//funcion lectura
int1 detecta(void);//funcion detectar pulso bajo
void memo(int v);//funcion memo, en v se almacenara el valor de leido una vez pulsado memo
void compara(int w);//función compara lectura con datos de eprom para identificar boton
int boton;//inicializamos boton
int boton1,boton2,boton3; //variable numero boton y boton pulsado anterior
int modo=0;//detección de modo, a 255 modo simple, a 0 modo combinado el boton auto es pulsacion si viene de puertas
//cerradas
int1 flagmodo=0;//cuando este a 1 es que se ha pulsado la combinacion auto despues de pce
int leido;
void main()
{
set_tris_a(0b110100);
int1 detectado;//recibira el valor del flagdetecta mediante el return de la funcion detecta()
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(0);
output_high(pin_a0);
//write_eeprom(0x04,0);//grabamos 0 en la eeprom, modo combinado
boton1=read_eeprom(0x00);
delay_ms(6);
boton2=read_eeprom(0x01);
delay_ms(6);
boton3=read_eeprom(0x02);
delay_ms(6);
flagalarma=read_eeprom(0x03);//pasamos la lectura del flag de alarma a la variable flag
delay_ms(6);
//modo=read_eeprom(0x04);//si no se ha tocado nada la eeprom devolvera 255 que es su estado normal virgen.
if(bit_test(porta,4)==0) delay_ms(20);//si se ha pulsado el boton antirebote
if(bit_test(porta,4)==0)
{
write_eeprom(0x03,255);//desactivamos alarma
write_eeprom(0x04,255);//grabamos 255 en la eeprom, modo simple
output_low(pin_a0);
delay_ms(2500);
output_high(pin_a0);
}
/*if(bit_test(porta,4)==0)//cambiamos a modo combinado
{
write_eeprom(0x04,0);//grabamos 0 en la eeprom, modo combinado
output_low(pin_a0);
delay_ms(5000);
output_high(pin_a0);
}*/
while(true)
{
disable_interrupts(int_ext);
disable_interrupts(global);
flagalarma=read_eeprom(0x03);//pasamos la lectura del flag de alarma a la variable flag
if(flagalarma==0) modoalarma();
detectado=detecta();
leido=lectura();//llamamos funcion lectura y cargamos leido con valor y de lectura Return(y)
compara(leido);//llamamos a compara y le enviamos el valor de leido
}
}
int1 detecta(void)
{
int1 flagdetecta; //variable que se pondrá a 1 cuando haya sido detectado
if(flagmodo==1) //como esta a 1 hacemos pausa de 5seg y se va a la funcion leido donde sin leer nada devolvera como
{ //si se hubiese pulsado el boton de pce nº3.
delay_ms(6000);
return(flagdetecta);
}
star:
if(bit_test(porta,4)==0) delay_ms(20);
if(bit_test(porta,4)==0) memo(leido);//va a memorizar si pulsamos memo
set_timer1(0);
while(bit_test(porta,5)==0) //cuando el pulso es bajo, leemos el timer1 para medir el ancho de pulso
{
if(get_timer1()>16300)//retardo para detectar primer pulso largo bajo del mando
{
return(flagdetecta);//devolvemos el 1 de flagdetecta
}
}
goto star;
}
int lectura()
{
if(flagmodo==1)
{
flagmodo=0;
return(boton3);//se devuelve el valor del boton puerta cerrada como si se hubiese pulsado pero sin llegar a leer
}
int codigo[3]={0}; // Array de [3]Bytes, 24bits para la lectura del código boton1, inicializado a 0, importante
int x; //para el for-next y lectura del array
int y;//almacenaremos codigo0+codigo1+codigo2
for(x=0;x<19;x++)//leemos 18bits,
{
delay_us(2900);//retardo para conincidir con el flanco tren de impulsos
shift_left(codigo,3,bit_test(porta,5));//registra lo que entra por portc,0 en los 3 bytes del array código
}
y=codigo[0]+codigo[1]+codigo[2];
set_timer1(0);
output_low(pin_a0);//para encender el led hay que sacar 0
delay_ms(450);
output_high(pin_a0);
return(y);
}
void memo(int v)
{
boton++;//aunmenta una vez cada vez que entra en la funcion
if(boton>3) boton=1;
switch(boton)//depende las veces que se haya pulsado el boton de grabar se graba en una posición distinta
{
case 1:
write_eeprom(0x00,v);//grabamos leido(asignado a V) en la eeprom
boton1=v;
break;
case 2:
write_eeprom(0x01,v);
boton2=v;
break;
case 3:
write_eeprom(0x02,v);
boton3=v;
break;
}
{
output_low(pin_a0);//parpadeo de led para verificar que se ha memorizado.
delay_ms(450);
output_high(pin_a0);
}
}
void compara(int w)
{
if(modo==255)//modo normal
{
if(w==boton1) botondetectado=1;
else if(w==boton2) botondetectado=2;
if(w==boton3) botondetectado=3;
if((w==98)&&(flagalarma==255)) flagalarma=0;//estas 2 lineas cambian el flagalarma de 0 a 255 si se ha pulsado
else if(w==98)flagalarma=255; //el boton de puerta abierta con la combinacion de parada de puerta
write_eeprom(0x03,flagalarma);//memorizamos eeprom el flag de alarma
enable_interrupts(int_ext);//habilitamos interrupcion exterior deteccion flanco de subida
ext_int_edge(l_to_h);
enable_interrupts(global);
}
else if(modo==0)//modo combinado
{
if((w==boton1)&&(botonant==3))
{
flagmodo=1;//activamos el flag que usaremos en deteccion y lectura
botondetectado=1;
}
else if((w==boton1)&&(botonant==2)) botondetectado=1;
else if(w==boton2) botondetectado=2;
if(w==boton3) botondetectado=3;
if((w==98)&&(flagalarma==255)) flagalarma=0;
else if(w==98)flagalarma=255;
write_eeprom(0x03,flagalarma);//memorizamos eeprom el flag de alarma
enable_interrupts(int_ext);//habilitamos interrupcion exterior deteccion flanco de subida
ext_int_edge(l_to_h);
enable_interrupts(global);
}
}
void automatic(void)
{
output_low(pin_a1);
delay_us(16400);
output_high(pin_a1);
delay_us(4100);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(4100);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(8200);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(8200);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
}
void open(void)
{
output_low(pin_a1);
delay_us(16400);
output_high(pin_a1);
delay_us(4100);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(4100);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(8200);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(12200);
output_low(pin_a1);
delay_us(10300);
output_high(pin_a1);
}
void close(void)
{
output_low(pin_a1);
delay_us(16400);
output_high(pin_a1);
delay_us(4100);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(4100);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(8200);
output_low(pin_a1);
delay_us(4100);
output_high(pin_a1);
delay_us(8200);
output_low(pin_a1);
delay_us(8200);
output_high(pin_a1);
}
void modoalarma(void)
{
enable_interrupts(int_ext);//habilitamos interrupcion exterior deteccion flanco de subida
ext_int_edge(l_to_h);
enable_interrupts(global);
} |
|
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Mon Dec 13, 2010 5:05 pm |
|
|
Hi,
What is your compiler version?
EEPROM operations are generally very robust. You've got a lot of (poorly formatted) code there, and I don't think anyone is going to try to fully understand it. I would recommend that you make a very simple test program to test the EEPROM on your PIC. Do something like check if a pin is being held low on start up, and if so, write several values to consecutive EEPROM locations. If the pin is high on startup (it's got a pullup on it!) read the EEPROM locations, and print them to a terminal program on your PC.
I just looked at your code again, and I'm wondering how you know that the EEPROM values are changing? You don't appear to have any way to see whats happening with your code?
This short test program will tell you whats going on. If it fails, post your test program and let us look at it. If it succeeds, start to rebuild your code until the problem re-appears.
I'm guessing this is not an EEPROM issue!
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 14, 2010 12:10 am |
|
|
You have posted too much code for us to look at. A short test program
that gets rid of 90% of your posted code would be better.
But anyway, here is a thread with some links on data eeprom corruption:
http://www.ccsinfo.com/forum/viewtopic.php?t=37757 |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|