Hola a todos.
Llevo un tiempo utilizando el Pic16f877A y me gustaria saltar a la serie pic18F. Para ello elegi el Pic18f4520 y estoy intentando migrar algunos programas del 16f al 18f, todo en ensamblador (La verdad es que no entiendo c ni tengo oportunidad de aprenderlo) y la cosa no me iba mal del todo (Entradas y salidas sin problemas, Conversion AD sin problemas, LCD sin problemas...).
Ahora estaba empezando a utilizar la memoria EEPROM interna y aqui viene el problema.
El programa que estoy escribiendo, simplemente espera a una interrupcion por el PORTB:0. Cuando salta la interrupcion, el programa aumenta un registro y lo escribe en una direccion de eeprom. El caso es que para leer/escribir la eeprom utilize la rutina que viene en el datasheet de microchip y simulado en MPLAB (Ver 7.00, algo antigua) para leer la eeprom no hay problema, pero no veo manera de escribir en ella. Realmente, el problema puede que este en la interrupcion, pero no veo manera de simularla en MPLAB asi que, vamos a pensar que es problema de la memoria
Buscando en esta pagina y tambien en la red, la mayoria de lo relacionado con los pif18 viene en C y, sinceramente, no entiendo nada.
No pido que me escriban el programa, pero si alguien puede darle un vistazo (sobre todo a la rutina de la eeprom) se lo agradeceria. Aqui lo adjunto.
;****************************************************************************************************************************************************
LIST P=18F4520
INCLUDE <P18F4520.INC>
__CONFIG _CONFIG1H, _FCMEN_OFF_1H & _IESO_OFF_1H & _OSC_HS_1H
__CONFIG _CONFIG2L, _BOREN_OFF_2L ;& _PWRTE_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H
__CONFIG _CONFIG4L, _DEBUG_OFF_4L & _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L;DEBUG cambio ON=>OFF
__CONFIG _CONFIG5L, _CP3_OFF_5L & _CP2_OFF_5L & _CP1_OFF_5L & _CP0_OFF_5L
__CONFIG _CONFIG5H, _CPD_ON_5H & _CPB_ON_5H
__CONFIG _CONFIG6L, _WRT3_OFF_6L & _WRT2_OFF_6L & _WRT1_OFF_6L & _WRT0_OFF_6L
__CONFIG _CONFIG6H, _WRTD_ON_6H & _WRTC_ON_6H & _WRTB_ON_6H
ERRORLEVEL -202
ERRORLEVEL -302
ERRORLEVEL -305
#DEFINE COUNTER PORTB, 0 ;counter (por interrupcion)
REGISTRO_1 equ 0x04A
Guarda_W equ 0x04C
Guarda_STATUS equ 0x04D
Guarda_RESUL equ 0x04E
Guarda_R_ContA equ 0x04F
Guarda_R_ContB equ 0x050
org 0xf00002
DE 0x09
V_RESET org 0000h
nop
nop
goto main
org 0008h
goto count ;interrupcion del counter
; retfie
main
clrf PORTA
clrf PORTB
clrf PORTC
clrf PORTD
clrf PORTE
clrf TRISA
movlw b'00000001'
movwf TRISB
clrf TRISC
clrf TRISD
clrf TRISE
bcf INTCON2 ,INTEDG0
movlw b'10010000' ;Habilita la interrupci RBI y la general.
movwf INTCON
;********************INICIO (ESPERA A LA INTERRUPCION)****************************
Inicio
nop
goto $-1 ;el programa espera hasta que salta la interucpcion
;**********************************INTERRUCIOPN**********************************
count
call Retardo_10ms
movwf Guarda_W ; Guarda W y STATUS.
swapf STATUS,W ; Ya que "movf STATUS,W" corrompe el bit Z.
movwf Guarda_STATUS
movf R_ContA,W ; Guarda los registros utilizados en esta
movwf Guarda_R_ContA ; subrutina y tambi駭 en la principal.
movf R_ContB,W
movwf Guarda_R_ContB
call Retardo_20ms
INCR_REGISTRO
incf REGISTRO_1
movlw b'00000000' ;Posicion de rom para mi registro
movwf EEADR
movf REGISTRO_1, w
call EEPROM_EscribeDato
goto FinInterrupcion
FinInterrupcion
swapf Guarda_STATUS,W ; Restaura el STATUS.
movwf STATUS
swapf Guarda_W,F ; Restaura W como estaba antes de producirse
swapf Guarda_W,W ; interrupci.
movf Guarda_R_ContA,W ; Restaura los registros utilizados en esta
movwf R_ContA ; subrutina y tambi駭 en la principal.
movf Guarda_R_ContB,W
movwf R_ContB
; bcf INTCON, INTF ; Limpia flag de reconocimiento de la interrupci.PIC16
bcf INTCON, INT0IF ; Limpia flag de reconocimiento de la interrupci.PIC18
bcf INTCON, RBIF
bsf INTCON, INT0IE
; bcf INTCON, T0IF
retfie ; Retorna y rehabilita las interrupciones.
#INCLUDE <18_AMC_RETARDOS.INC>
#INCLUDE <18_AMC_EEPROM.INC>
END
;************************************************************************************************************************************************
y aqui esta la rutina de la eeprom
;************************************************************************************************************************************************
; Entrada: En (W) la direcci de la memoria EEPROM a leer.
; Salida : En (W) el byte le冝o.
EEPROM_LeeDato
movwf EEADR ; Direcci a leer.
bcf EECON1,EEPGD
bcf EECON1, CFGS ;7/1 anadido
bsf EECON1,RD ; Orden de lectura.
EEPROM_SigueLeyendo
btfsc EECON1,RD ; El PIC indica que ha terminado la lectura
goto EEPROM_SigueLeyendo ; poniendo en bajo este bit.
movf EEDATA,W ; El byte le冝o al registro W.
return
; Entradas: En el registro EEADR la direcci de la memoria EEPROM a escribir.
; En el registro W el byte a escribir.
;
CBLOCK
EEPROM_GuardaINTCON
ENDC
EEPROM_EscribeDato
movwf EEDATA ; El byte a escribir.
bcf EECON1, EEPGD
bcf EECON1, CFGS ;7/1 anadido
bsf EECON1,WREN ; Habilita escritura.
bcf INTCON, GIE ;7/1 anadido
movlw 0x55
movwf EECON2
movlw 0xAA
movwf EECON2
bsf EECON1,WR ; Inicia la escritura.
DES btfsc EECON1,WR ; Comprueba que termina de escribir en la EEPROM.
goto DES
goto EEPROM_TerminaEscribir
EEPROM_TerminaEscribir
bsf INTCON, GIE ;7/1 anadido
bcf EECON1,WREN ; Desautoriza la escritura en EEPROM.
return
:**********************************************************************************************************************************************
Utilizo un rutina de retardos pero no hay problema con ella asi que no la adjunto de momento.
Gracias por adelantado por su atencion.