Hola:
Por lo que cuentas, falta vovler en Escribir_EEPROM volver al banco 00, justo antes del return.
Por ahora lo he hecho así. Creo, solo creo, que no hace falta usar dos direcciones, solo uno, el del contador.
Lo que no me guarda nada.
Por lo que cuentas, falta vovler en Escribir_EEPROM volver al banco 00, justo antes del return.
Por ahora lo he hecho así. Creo, solo creo, que no hace falta usar dos direcciones, solo uno, el del contador.
Código (asm) [Seleccionar]
;
; Un pulsador en RA4 va incrementando un contador, entre [1-4].
; La salida se envía a un display de 7 seg. en PORTB, y hacia salidas en PORTA.
;
; (Contador) |RB 76543210 |RA 76543210
; ------------|------------------------
; 1 | 00000011 | 00000010
; 2 | 00100100 | 00000101
; 3 | 00001100 | 00000110
; 4 | 00111100 | 00001001
;
; PORTA:
; RA0 : OE1
; RA1 : OE2
; RA2 : A21
; RA3 : AUX
; RA4 : Pulsador
; PORTB : display de 7 segmentos. a = RB0
;
; ZONA DE DATOS ****************************************************************
;*******************************************************************************
; Listado y condiciones de ensamblado
LIST P=16F88 ; 4 Mhz
radix dec
errorlevel -302 ; Turn off banking message
;*******************************************************************************
; Bibliotecas
INCLUDE <P16f88.INC>
;*******************************************************************************
; Fusibles
__CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
;_XT_OSC
; _CP_OFF: Protección de código DESACTIVADO.
; _DEBUG_OFF: Debug en circuito DESACTIVADO.
; _WRT_PROTECT_OFF: Protección a escritura en memoria de programa DESACTIVADO.
; _CPD_OFF: Protección de código de datos DESACTIVADO.
; _LVP_OFF: Programación en baja tensión DESACTIVADO.
; _BODEN_OFF: Reset por Brown-out DESACTIVADO.
; _MCLRE_ON: Reset por pin externo ACTIVADO.
; _PWRTE_ON: Retraso al reset ACTIVADO.
; _WDT_OFF: Watchdog DESACTIVADO.
; _XT_OSC: Oscilador externo del tipo XT.
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
; _IESO_OFF: Modo de intercambio de externo a interno DESACTIVADO.
; _FCMEN_OFF: Monitor de CLK DESACTIVADO.
;*******************************************************************************
; Definiciones
; Máscaras de E/S de los puertos
; 0 = salida, 1 = entrada
; |76543210|
#define PORTA_ES b'00010000'
#define PORTB_ES b'00000000'
;*******************************************************************************
; Variables
area_compartida: udata_shr
contador res 1 ; Contador [1-4]
; ZONA DE CÓDIGOS **************************************************************
programa: code
ORG 000h
Inicio:
banksel ANSEL ; bank 1
clrf ANSEL ; Puerto analógico a digital.
movlw PORTA_ES ; definir E/S puerto A
movwf TRISA
movlw PORTB_ES ; definir E/S puerto B
movwf TRISB
;
movlw 0 ; inicializamos contador
movwf contador
call Leer_EEPROM ; Lectura de la EEPROM.
; Bucle principal
BANKSEL OSCCON
movlw b'01100000' ; 4 MHz
movwf OSCCON
banksel PORTA ; bank 0, siempre
goto Inicializado
Principal:
movf PORTA, w ; leer puerto A
andlw PORTA_ES ; nos quedamos sólo con lo interesante
btfss STATUS, Z ; ¿Se ha pulsado? Lo está si RA4 == 0
goto Principal ; No, esperar
;
; Aquí llegamos con el botón pulsado
Inicializado:
call incrementa_contador
call visualiza_contador
call salida_hacia_A
; Esperamos que levante el botón
Espera_levantar:
call Retardo_100ms ; Esperar la suelta del pulsador
movf PORTA, w ; leer puerto A
andlw PORTA_ES ; nos quedamos sólo con lo interesante
btfsc STATUS, Z ; ¿Sigue pulsado? Lo está si RA4 == 0
goto Espera_levantar ; No, esperar
;
goto Principal
; ******************************************************************************
;; salida_hacia_A
;
; Según el valor del contador ([1-4]), lo transforma en otro, basado en una
; tabla y lo saca por el puerto A
;
salida_hacia_A: call transforma_contador
movwf PORTA ; visualiza en puerto A
return
transforma_contador:
decf contador,w ; leemos el contador y le restamos 1
addwf PCL, f ; saltamos dentro de la tabla
; |76543210|
retlw b'00000010'
retlw b'00000101'
retlw b'00000110'
retlw b'00001001'
; ******************************************************************************
;; incrementa_contador
;
; Incrementa el valor de la variable contador, entre 1 y 4, inclusives.
;
incrementa_contador:
bcf contador,2
incf contador
call Escribir_EEPROM ; Escribir dato en la EEPROM.
return
; ******************************************************************************
;; visualiza_contador
;
; Muestra el valor del contador en el display de 7 segmentos
;
visualiza_contador:
movfw contador ; leemos contador
call w_a_digito ; transformación a dígito 7 segmentos
movwf PORTB ; visualiza en puerto B
return
w_a_digito: addwf PCL, f ; salta al dígito indexado por w
; |76543210|
retlw b'00111111' ; 0
retlw b'00000110' ; 1
retlw b'01011011' ; 2
retlw b'01001111' ; 3
retlw b'01100110' ; 4
retlw b'01101101' ; 5
retlw b'01111101' ; 6
retlw b'00000111' ; 7
retlw b'01111111' ; 8
retlw b'01101111' ; 9
; ----------------------------------------------------------------------------------------------------
; Espera = 100ms
; Frecuencia de reloj = 4Mhz
;
; Espera real = 0.1 segundos = 100000 ciclos
; Error = 0.00 %
Retardo_par: udata_shr
Retardo_100ms_d1 res 1
Retardo_100ms_d2 res 1
Retardo_code: code
Retardo_100ms:
;99993 ciclos
movlw 0x1E
movwf Retardo_100ms_d1
movlw 0x4F
movwf Retardo_100ms_d2
Retardo_100ms_loop:
decfsz Retardo_100ms_d1, f
goto $+2
decfsz Retardo_100ms_d2, f
goto Retardo_100ms_loop
;3 ciclos
goto $+1
nop
;4 ciclos (incluyendo la llamada)
return
; Generado por delay_pic.pl (Joaquín Ferrero. 2014.07.22)
; ./delay_pic.pl -s Retardo_100ms 4Mhz 100ms
; mar 22 jul 2014 19:22:23 CEST
; http://perlenespanol.com/foro/generador-de-codigos-de-retardo-para-microcontroladores-pic-t8602.html
; ----------------------------------------------------------------------------------------------------
; ******************************************************************************
;Subrutinas EEPROM -----------------------------------------------------------
Leer_EEPROM
BANKSEL EEADR ; Selecciona el registro EEADR.
movf contador, W
movwf EEADR ; Dato dirección de momoria a leer.
BANKSEL EECON1 ; Selecciona el banco EECON1.
bcf EECON1, EEPGD ; Punto a memoria de datos
bsf EECON1, RD ; a Leer.
BANKSEL EEDATA ; Seleccionar banco de EEDATA.
movf EEDATA, W ; W = EEDATA.
BANKSEL PORTA
return
Escribir_EEPROM
BANKSEL EECON1 ; Selecciona banco de EECON1.
btfsc EECON1, WR ; Espera para escribir
goto $-1 ; a completar.
BANKSEL EEADR ; Selecciona el banco EEADR.
movf contador, W
movwf EEADR ; Dirección dato de memoria a escribir.
BANKSEL EECON1 ; Selecciona el banco EECOn1.
bcf EECON1, EEPGD ; Punto a dato de memoria.
bsf EECON1, WREN ; Activar escritura.
bcf INTCON, GIE ; Desactiva interrupciones.
; El fabricante especifica que hay que seguir esta secuencia para escritura en EEPROm.
movlw 0x55
movwf EECON2 ; Escribe 55h.
movlw 0xAA
movwf EECON2 ; Escribe AAh.
bsf EECON1, WR
bsf INTCON, GIE ; Activa interrupciones.
bcf EECON1, WREN ; Desactiva escrituras.
BANKSEL PORTA
return
END
Lo que no me guarda nada.