Manejar EEPROM interna

Iniciado por Meta, 7 Marzo 2013, 15:51 PM

0 Miembros y 1 Visitante están viendo este tema.

Meta

Hola:

Uso el PIC12F629 puedo leer un valor en la EEPROM interna pero no soy capaz  de almacenarlo en la misma dirección.

Este es el código.
;No olvidar que si GP2 detecta un un 0 en la entreda menor de 5 segundos,
;el PIC no actua, vuelve a lo suyo como si no pasara nada.
;
; Cuando detecte
;GP2|GP0 GP1 GP4 GP5
;---+----------------
;1) | 0   1   0   0
;2) | 1   0   1   0
;3) | 0   1   1   0
;4) | 1   0   0   1
;
;ZONA DE DATOS*****************************************************************

    LIST P=12F629                          ; Procesador usado.
    INCLUDE <P12F629.INC>                  ; Fichero que definen las etiquetas.

    __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_OFF & _FOSC_INTRCIO
    ERRORLEVEL -302

#DEFINE     Pulsador    GPIO,2      ; Pulsador.
#DEFINE     Leds        GPIO        ; Leds está conectado al GPIO.

VARIABLES UDATA_SHR
ContadorEstado RES 1
RAM_ret RES 1
RAM_ret_1 RES 1
Contador RES 1

;ContadorEstado     equ  20h
;RAM_ret         equ 21h
;RAM_ret_1       equ 22h
;Contador        equ 23h

; ORG 0x2100 ; Corresponde a la dirección 0 de la zona EEPROM de datos.
; DE 0x00 ; El contador en principio a cero.

;ZONA DE CÓDIGOS***************************************************************
    ORG     0     
                  ; El programa comienza en la dirección 0.
    goto    Inicio

Inicio
    bsf     STATUS,RP0                  ; Selecciona banco 1.
    call    0x3FF                    ; Lo el valor de la calibración que sera almacenada en W.
    movwf   OSCCAL                    ; Paso el valor de W a OSCCAL para calibrar el oscilador.
    movlw   b'00000100'
    movwf   TRISIO
    movlw   b'00001111'
    movwf   OPTION_REG              ; Activa Pull Up.
    movlw   b'0000100'
    movwf   WPU                     ; Activada Pull Up del GP0.
    bcf     STATUS,RP0                      ; Selecciona banco 0.
    movlw   b'00000111'             ; Desactivar comparadores.
    movwf   CMCON
movlw .3
    movwf Contador
clrf GPIO
;***************************************************************************

Principal
    btfsc   Pulsador                ; ¿Pulsador presionado?, ¿(Pulsador)=0?
    goto    Principal               ; No. Vuelve a leerlo.
;    call    Retardo_20ms            ; Espera que se estabilicen los niveles de tensión.
    btfsc   Pulsador                ; Comprueba si es un rebote.
    goto    Principal               ; Era un rebote y sale fuera.
    call    IncrementaVisualiza             ; Incrementa el contador y lo visualiza.
EsperaDejePulsar
    btfss    Pulsador                ; ¿Dejó de pulsar?. ¿(Pulsador)=1?
    goto    EsperaDejePulsar         ; No. Espera que deje de pulsar.
Fin    goto    Principal

;***************************************************************************   
; Subrutina "IncrementaVisualiza" ---------------------------------------------------------

IncrementaVisualiza
call Lee_Dato_EEPROM
incf Contador,F ; Incrementa el contador y comprueba si ha
call Escribe_Dato_EERPOM
movlw d'4' ; llegado a su valor máximo mediante una
subwf Contador,W ; resta. (W)=(Contador)-4.
btfsc STATUS,C ; ¿C=0?, ¿(W) negativo?, ¿(Contador)<4?
InicializaContador
clrf Contador ; No, era igual o mayor. Por tanto, resetea.
Visualiza
movf Contador,W
call Tabla ; Lo pasa a siete segmento para poder ser
movwf GPIO ; visualizado en el display.
return


Tabla
    addwf PCL,F                      ; Sumo W al contador de programa. ;
    retlw b'00000010'  ;1
    retlw b'00010001'  ;2         
    retlw b'00010010'  ;3               ; Retorno con el valor correspondiente. 
    retlw b'00100001'  ;4
;Subrutina EEPROM ******************************************************************

Lee_Dato_EEPROM
    bsf     STATUS,RP0              ; Banco 1
    movlw   0x00              ; Primera posición de la tabla
    movwf   EEADR                  ; Apunta ahí
;    movf    Contador,W       ; Coge el contador
;    addwf   EEADR                  ; Suma el contador para apuntar al dato que nos interesa
    bsf     EECON1,RD              ; Lee el valor de la tabla
    movf    EEDATA,W              ; Pasa el valor a W para trabajar con él.
bcf STATUS,RP0
    return



;Guarda en la EEPROM el valor del contador
Escribe_Dato_EERPOM
    bsf      STATUS,RP0             ; Banco 1.
    movlw    0x00                 ; Elijo esta dirección de la EEPROM y
    movwf    EEADR                  ; lo cargo en EEADR con el dato a escribir.
    movlw    Contador
    movwf    EEDAT                  ; Cargo el registro EEDAT con el dato a escribir.
    bsf      EECON1,WREN            ; Habilitar
    bcf     INTCON,GIE              ; Deshabilitar intercepciones.
    movlw     0x55                  ; Desbloquear escritura.
    movwf     EECON2
    movlw     0xAA
    movwf     EECON2
    bsf     EECON1,WR               ; Inicie la escritura.
    bsf     INTCON,GIE              ; Habilitar INTS.
bcf STATUS,RP0
    return
   
;Subrutina Retardo_20ms ************************************************************
; Retardo = 0.02 segundos.
; Frecuencia Reloj = 4 MHz.
; Retardo actual = 0.02 segundos = 20000 ciclos.

Retardo_20ms
            ;19993 ciclos.
    movlw    0x9E
    movwf    RAM_ret
    movlw    0x10
    movwf    RAM_ret_1
Retardo_20ms_0
    decfsz    RAM_ret, f
    goto    $+2
    decfsz    RAM_ret_1, f
    goto    Retardo_20ms_0
            ;3 ciclos.
    goto    $+1
    nop
            ;4 ciclos (incluyendo call).
    return

END


Salu2.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Firos

He encontrado esto por ahí:

http://www.ucontrol.com.ar/forosmf/tutoriales-guias-y-cursos-en-ucontrol/datasheet-en-espanol-pic12f629675/msg7676/#msg7676


Es el datasheet en español de ese PIC que estas usando.



Pues a simple vista parece que estas cumpliendo con lo que pide el datasheet. ¿Has probado a debuggear paso a paso y revisando el codigo de el programa con el MPLAB o con Proteus para ver en que paso se queda enganchado?

Es posible que el código de escritura en la EEPROM esté bien y esté fallándote otra cosa.


Por otro lado. ¿No era necesario esperar a que la operación de escritura en la EEPROM se realizase con éxito? Aunque en el datasheet ponga habilitar la interrupción inmediatamente después de mandar la escritura, la escritura requiere un tiempo para que no de fallos y como bien dice, hay que deshabilitar interrupciones para evitar fallos, puesto que no debe interrumpirse.


¿Habías probado alguna vez a escribir la EEPROM de esa manera? ¿Te ha funcionado?


Prueba a darle las ordenes de escritura pero no habilites las interrupciones hasta que el FLAG de escritura en la EEPROM se active. Métele un búcle que compruebe el FLAG.

En tu caso creo que es el bit 7 (EEIF) de el registro PIR1. Asi que ya sabes:

Bucle        btfss  PIR1,EEIF
                goto  Bucle

... Habilita interrupciones y sigue con tu programa





Si te funciona pónnoslo aquí para corroborarlo. Gracias.



Un saludo.
El final del camino no está determinado, lo determinamos nosotros mismos paso a paso, día a día, y se puede cambiar.