Autor Tema: se modifica el valor de mi registro al retornar de una interrupción  (Leído 8728 veces)

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

Desconectado cristhiamjara

  • PIC10
  • *
  • Mensajes: 15
Hola a toda la comunidad, me llamo Cristhiam, estoy aprendiendo a programar pics con assembly
Estuve practicando las interrupciones con los pines rb4-rb7 del portb, es muy extraño lo que sucede pero trataré de hacerles entender lo mas claro posible.

Org0x04 ;aqui viene cuando hay un cambio de estado en los pines rb4-rb7
-hago operaciones logicas y matematicas
-guardo el resultado en un registro, digamos VALOR
-paso VALOR a portA : VALOR --> portA (digamos que VALOR esta cargado con b'1010') y muestro el resultado en un arreglo de leds, que me sirve para verificar su contenido en binario
-hasta el paso anterior todo ok
-luego quiero salir de la interrupcion, hago bcf intcon,0 y luego retfie
-inmediatamente se cambia el valor binario en mis leds a un valor aleatorio que no se de donde aparece
-luego hago un testo y llamo a VALOR y muestro su contenido en portA a través del arreglo de leds, y me doy con la sorpresa que su valor se ha modificado.
-ese es mi gran problema, ya revisé mi código muchas veces y no escribí nada que modifique el contenido de VALOR.
Apreciaría mucho que me ayuden a entender que está sucediendo
gracias de antemano a todos  :-/ :-/

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #1 en: 18 de Mayo de 2020, 22:17:35 »
- Cuando entrás en la interrupción ¿Salvás estado?
- Al volver ¿Lo recuperás?

Desconectado cristhiamjara

  • PIC10
  • *
  • Mensajes: 15
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #2 en: 18 de Mayo de 2020, 23:17:47 »
- Cuando entrás en la interrupción ¿Salvás estado?
- Al volver ¿Lo recuperás?
hola eduardo, gracias por contestar.
Mira cuando inicia el programa
haga clrf VALOR
-hago mis rutinas normales y ninguna incluye modificar el contenido de VALOR
-cuando ocurre una interrupcion hago las operaciones y al final cargo el resultado en VALOR, y todo correcto
hasta una linea antes del retfie e podido verificar q VALOR esta con el contenido debido, cuando retorno de la interrupcion se modifica el contenido de VALOR
y eso es lo que no comprendo.

Desconectado cristhiamjara

  • PIC10
  • *
  • Mensajes: 15
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #3 en: 18 de Mayo de 2020, 23:25:13 »
Código: [Seleccionar]
            org    0x04
            operaciones
            guardo el resultado en valor_real
            movfw   valor_real
    movwf   portb  ;test para comprobar que se tiene el contenido esperado
            retfie     ;para regresar de la interrupcion

el problema ocurre de regreso a la rutina
los leds que deje con el contenido de valor_real se modifican, luego ya en la rutina, osea no en la interrupcion, llamo el contenido de valor_real y los mando a los leds, pero ya no tiene
el contenido debido, sino que se modifico. Espero que me entiendan

Desconectado Eduardo2

  • PIC24H
  • ******
  • Mensajes: 1004
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #4 en: 18 de Mayo de 2020, 23:35:11 »
A esto me refería, es la secuencia que Microchip pone en todos los datasheets.
Código: [Seleccionar]
        MOVWF W_TEMP        ;Copy W to TEMP register
        SWAPF STATUS,W      ;Swap status to be saved into W
        CLRF STATUS         ;bank 0, regardless of current bank, Clears IRP,RP1,R
        MOVWF STATUS_TEMP   ;Save status to bank zero STATUS_TEMP register
        MOVF PCLATH, W      ;Only required if using pages 1, 2 and/or 3
        MOVWF PCLATH_TEMP   ;Save PCLATH into W
        CLRF PCLATH         ;Page zero, regardless of current page
        :
        :(ISR)              ;(Insert user code here)
        :
        MOVF PCLATH_TEMP, W ;Restore PCLATH
        MOVWF PCLATH        ;Move W into PCLATH
        SWAPF STATUS_TEMP,W ;Swap STATUS_TEMP register into W
        ;(sets bank to original state)
        MOVWF STATUS        ;Move W into STATUS register
        SWAPF W_TEMP,F      ;Swap W_TEMP
        SWAPF W_TEMP,W      ;Swap W_TEMP into W 
       

Si no salvás y recuperás el estado el retorno es impredecible salvo que se esté en un bucle ocioso.

Desconectado cristhiamjara

  • PIC10
  • *
  • Mensajes: 15
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #5 en: 19 de Mayo de 2020, 01:42:33 »
A esto me refería, es la secuencia que Microchip pone en todos los datasheets.
Código: [Seleccionar]
        MOVWF W_TEMP        ;Copy W to TEMP register
        SWAPF STATUS,W      ;Swap status to be saved into W
        CLRF STATUS         ;bank 0, regardless of current bank, Clears IRP,RP1,R
        MOVWF STATUS_TEMP   ;Save status to bank zero STATUS_TEMP register
        MOVF PCLATH, W      ;Only required if using pages 1, 2 and/or 3
        MOVWF PCLATH_TEMP   ;Save PCLATH into W
        CLRF PCLATH         ;Page zero, regardless of current page
        :
        :(ISR)              ;(Insert user code here)
        :
        MOVF PCLATH_TEMP, W ;Restore PCLATH
        MOVWF PCLATH        ;Move W into PCLATH
        SWAPF STATUS_TEMP,W ;Swap STATUS_TEMP register into W
        ;(sets bank to original state)
        MOVWF STATUS        ;Move W into STATUS register
        SWAPF W_TEMP,F      ;Swap W_TEMP
        SWAPF W_TEMP,W      ;Swap W_TEMP into W 
       

Si no salvás y recuperás el estado el retorno es impredecible salvo que se esté en un bucle ocioso.
tengo entendido que esto se hace para guardar los datos que se tienen antes de una interrupcion, ya que estos suelen cambiar durante las interrupciones. Pero en mi caso
los datos los genero dentro de la interrupcion y los guardo en un registro, y al volver de la interrupcion el valor de este registro tambien se modifica.
comparto mi código:
Código: [Seleccionar]
List p=16f84a
    #include <p16f84a.inc>
    __config _XT_OSC & _PWRTE_ON & _CP_OFF & _WDT_OFF
    org     0x00
;declaracion de variables
tmr0     equ     0x01
pcl     equ     0x02
status     equ     0x03
porta     equ     0x05
portb     equ     0x06
intcon     equ     0x0b
option_reg  equ     0x81
trisa     equ     0x85
trisb     equ     0x86
    cblock  0x0c
    conta
    filas
    columnas
    contaf
    f
    c
    valor_real
    temp
    d1
    d2
    flag
    endc
    goto    principal ;####################################
    org     0x04 ;######INTERRUPCIONES################    
    movfw   portb ;estoy leyendo 'abcdxxxx'
    movwf   columnas
    clrf    porta ;limpio porta para que no se queden colgados valores
    swapf   columnas,1 ;    ahora tengo 'xxxxabcd'
    call    delaym;
    bsf     flag,0
    nop
    movfw   contaf  ;carga w con el valor de contaf , conta
    xorlw   .1     ;comprueba si contaf vale 1
    btfsc   status,2 ;revisa : si Z=1 caso1, si Z=0 , volver a preguntar
    goto    casof1     ;;; aqui va si son iguales , caso1
    movfw   contaf     ;aqui va si no es caso 1
    xorlw   .2
    btfsc   status,2
    goto    casof2     ;;aqui va si es caso2
    movfw   contaf
    xorlw   .3
    btfsc   status,2
    goto    casof3     ;caso3
casof4     movlw   .12     ;de lo contrario pasa a casof4
    movwf   f    
    goto    chkcol;return    
casof3     movlw   .8
    movwf   f
    goto    chkcol;return
casof2     movlw   .4
    movwf   f
    goto    chkcol;return
casof1     movlw   .0
    movwf   f
chkcol     ;movfw   columnas;carga w con el valor capturado de portb en columnas
    btfss   columnas,0
    goto    $+2
    goto    casoc1     ;aqui va caso1    
    btfss   columnas,1
    goto    $+2    
    goto    casoc2
    btfss   columnas,2
    goto    $+2
    goto    casoc3
    btfss   columnas,3
    goto    $+2
casoc4     movlw   .3
    movwf   c
    goto    sumar;retfie
casoc3     movlw   .2    
    movwf   c
    goto    sumar;retfie
casoc2     movlw   .1
    movwf   c
    goto    sumar;retfie
casoc1     movlw   .0
    movwf   c
    goto    sumar;retfie
sumar     movf    c,0 ;cargamos w con el valor de c
    addwf   f,0 ;sumamos w con f y lo guardamos en w
    movwf   valor_real ;cargamos valor_real con el valor de la suma
    ;ya tengo mi valor real################################!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ;ya tengo mi valor real################################!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
verificar   movfw   contaf ;verifica sin contaf=4 para reiniciarlo, casos contrarios <4 se incrementa su valor en 1
    xorlw   .1
    btfss   status,2 ;1 si son iguales,  0 si son diferentes
    goto    $+2
    goto    increment
    movfw   contaf
    xorlw   .2
    btfss   status,2 ;1 si son iguales, 0 si son diferentes
    goto    $+2
    goto    increment
    movwf   contaf
    xorlw   .3
    btfss   status,2
    goto    $+2
    goto    increment ; si esq si es el caso 3
re     movlw   .1    ;
    movwf   contaf  ;reinicia conta=1
    movwf   filas   ;filas=0001
    movfw   valor_real ;cargamos w con valor_real para pruebas
    movwf   portb
    call    delay500ms
    ;call    delay500ms
    ;call    delay500ms
    ;call    delay500ms
    movfw   filas   ;reinicia filas=0001
    goto    salir
increment   incf    contaf,1
    rlf     filas,1
    movfw   valor_real
    movwf   portb
    call    delay500ms
    ;call    delay500ms
    ;call    delay500ms
    ;call    delay500ms
    movfw   filas  ; 0002,3,4    
salir     bcf     intcon,0
    retfie 
principal   ;##############################################
    ;IOs
    bsf     status,5
    movlw   b'10000'   ;porta como salidas
    movwf   trisa
    movlw   b'11110000'
    movwf   trisb
    movlw   b'11010111' ;rbpullup no, intedge=subida, t0cs=f/4 ,t0ie:bajada, psa->tmr0 ratio 1:256
    movwf   option_reg
    bcf     status,5;de vuelta al banco0
    movlw   b'10001000'
    movwf   intcon
    clrf    porta
    clrf    portb
    movlw   .1 ;cargar 1
    movwf   contaf  ;se inicia con 1
    movwf   filas   ;se inicia con 0001
    clrf    valor_real
    clrf    columnas
    goto    inicio
delay50ms
    movwf   temp
    movlw   .60
    movwf   tmr0
    btfss   intcon,2
    goto    $-1
    bcf     intcon,2
    movfw   temp
    return
delaym
    movwf   temp
    movlw   .220
    movwf   tmr0
    btfss   intcon,2
    goto    $-1
    bcf     intcon,2
    movfw   temp
    return
delay500ms
    movwf   temp
    movlw   .10
    movwf   d1
    call    delay50ms
    decfsz  d1
    goto    $-2
    movfw   temp
    return
notecla    
    movfw   contaf  ;verificar si contaf es 4
    xorlw   .4     ;verificar si contaf es 4
    btfsc   status,2;verificar si contaf es 4
    goto    si4
    incf    contaf,1  ;si son diferentes
    rlf     filas,1
    movfw   filas
    return
si4     movlw   .1
    movwf   contaf
    movwf   filas
    movfw   filas
    return    
inicio    
    btfss   flag,0
    goto    aqui
    bcf     flag,0
    clrf    porta
    nop
aqui     ;bsf     intcon,7
    movfw   filas   ;w se carga con el valor de filas *******
    movwf   porta
    nop
    call    delaym    
    call    notecla
    nop
    nop;aqui va lo que se hará si no se presiono una tecla
    goto    inicio
    end
es un programa para leer un teclado matricial y mostrar la tecla presionada en un diplay a traves de un codificador bcd 74ls48

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #6 en: 19 de Mayo de 2020, 08:23:45 »
Citar
tengo entendido que esto se hace para guardar los datos que se tienen antes de una interrupcion


Ese codigo que te pasaron se DEBE realizar SIEMPRE, te doy un ejemplo:

Tu programa principal esta corriendo y antes de un BTFSS STATUS,Z salta a la interrupcion, vamos as decir que las banderas estaban en Z=1 C=0 (es decir no ejecuta el BTFSS)
En la interrupcion entras y operas, el registro STATUS cambia por las instrucciones que usas, llegas al final y tu registro status quedo Z=0 C=0
Vuelve al programa y ejecuta el BTFSS... Sorpresa, el BTFSS no salta porque Z=0...

Lo mismo puede ocurrir con W, si tenes cualquier instruccion que tome de W para operar y tenes una interrupcion antes, vas a tener problemas. Entonces ese código ES OBLIGATORIO en es PIC (hay otros PIC que tiene un auto-guardado)

Y como ves en tu programa estas modificando W y STATUS (con otras instrucciones) en todo momento.

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #7 en: 19 de Mayo de 2020, 09:34:48 »
Me parece, que el problema te lo da el call delaym dentro de la interrupción.
Por un tema del contador de programa, es preferible que todas las subrutinas estén por encima del programa, así cuando el CP tiene que volver, lo puede hacer sin problemas.
Entonces, en tu programa, el call tiene que ir más abajo y al subir, puede ser que lo esté haciendo en cualquier lado del programa; y no desde lo llamaste. Deberías simular esto con MPLAB; y asegurarte que retorne al lugar correcto.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado cristhiamjara

  • PIC10
  • *
  • Mensajes: 15
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #8 en: 19 de Mayo de 2020, 13:25:22 »
Me parece, que el problema te lo da el call delaym dentro de la interrupción.
Por un tema del contador de programa, es preferible que todas las subrutinas estén por encima del programa, así cuando el CP tiene que volver, lo puede hacer sin problemas.
Entonces, en tu programa, el call tiene que ir más abajo y al subir, puede ser que lo esté haciendo en cualquier lado del programa; y no desde lo llamaste. Deberías simular esto con MPLAB; y asegurarte que retorne al lugar correcto.

hola, en este caso todas las subrutinas estan por encima del programa pero debajo de la interrupción, debería colocar las subrutinas por arriba de org0x04?

Desconectado cristhiamjara

  • PIC10
  • *
  • Mensajes: 15
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #9 en: 19 de Mayo de 2020, 13:38:10 »
Citar
tengo entendido que esto se hace para guardar los datos que se tienen antes de una interrupcion


Ese codigo que te pasaron se DEBE realizar SIEMPRE, te doy un ejemplo:

Tu programa principal esta corriendo y antes de un BTFSS STATUS,Z salta a la interrupcion, vamos as decir que las banderas estaban en Z=1 C=0 (es decir no ejecuta el BTFSS)
En la interrupcion entras y operas, el registro STATUS cambia por las instrucciones que usas, llegas al final y tu registro status quedo Z=0 C=0
Vuelve al programa y ejecuta el BTFSS... Sorpresa, el BTFSS no salta porque Z=0...

Lo mismo puede ocurrir con W, si tenes cualquier instruccion que tome de W para operar y tenes una interrupcion antes, vas a tener problemas. Entonces ese código ES OBLIGATORIO en es PIC (hay otros PIC que tiene un auto-guardado)

Y como ves en tu programa estas modificando W y STATUS (con otras instrucciones) en todo momento.
buenas, ya implementé el codigo de salvar status y w y recuperarlos antes de volver a la interrupción pero sigue ocurriendo lo mismo,
durante la interrupcion mando un valor al display y al retornar de la interrupion el display cambia y muestra otro valor, osea las salidas del pic cambia de estado.
A pesar que en bluckle principal no tengo ninguna sentencia que mande valores de salida al puerto.
PD: Gracias a todos por su atención

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #10 en: 19 de Mayo de 2020, 18:42:25 »
Me parece, que el problema te lo da el call delaym dentro de la interrupción.
Por un tema del contador de programa, es preferible que todas las subrutinas estén por encima del programa, así cuando el CP tiene que volver, lo puede hacer sin problemas.
Entonces, en tu programa, el call tiene que ir más abajo y al subir, puede ser que lo esté haciendo en cualquier lado del programa; y no desde lo llamaste. Deberías simular esto con MPLAB; y asegurarte que retorne al lugar correcto.

hola, en este caso todas las subrutinas estan por encima del programa pero debajo de la interrupción, debería colocar las subrutinas por arriba de org0x04?

Para ser más preciso, en las interrupciones se trata de hacer lo menos posible; y por sobretodo evitar llamar con call. Si lo haces, tenes que asegurarte de no sobrepasar la pila. El pic que estás usando, tiene un tamaño de 8 posiciones la pila; por lo que podes llamar hasta 8 veces la pila en forma anidada. O sea, llamas con un call, dentro de ese; llamás a otro, y así hasta 8 veces. El problema que las interrupciones consumen una posición de pila.

Ahora bien. Cada llamado debe de estar por encima. El call de la interrupción, está en la posición 0x08, y la subrutina llamada está 0x74
Esto debe ser al revés; o sea, la subrutina tiene que estar en una posición más chica que la llamada (dije por encima, al principio, porque es por el orden en cascada que se escribe el programa). Te doy un ejemplo:


Código: ASM
  1. org 0x00
  2.         goto principal
  3. org 0x04
  4.         MOVWF W_TEMP        ;Copy W to TEMP register
  5.         SWAPF STATUS,W      ;Swap status to be saved into W
  6.         CLRF STATUS         ;bank 0, regardless of current bank, Clears IRP,RP1,R
  7.         MOVWF STATUS_TEMP   ;Save status to bank zero STATUS_TEMP register
  8.         MOVF PCLATH, W      ;Only required if using pages 1, 2 and/or 3
  9.         MOVWF PCLATH_TEMP   ;Save PCLATH into W
  10.         CLRF PCLATH         ;Page zero, regardless of current page
  11.         goto interrupcion
  12. ;
  13. delay50ms
  14.             movwf   temp
  15.             movlw   .60
  16.             movwf   tmr0
  17.             btfss   intcon,2
  18.             goto    $-1
  19.             bcf     intcon,2
  20.             movfw   temp
  21.             return
  22. delaym
  23.             movwf   temp
  24.             movlw   .220
  25.             movwf   tmr0
  26.             btfss   intcon,2
  27.             goto    $-1
  28.             bcf     intcon,2
  29.             movfw   temp
  30.             return
  31. delay500ms
  32.             movwf   temp
  33.             movlw   .10
  34.             movwf   d1
  35.             call    delay50ms
  36.             decfsz  d1
  37.             goto    $-2
  38.             movfw   temp
  39.             return
  40. ;
  41. notecla
  42.             movwf temp     
  43.             movfw   contaf  ;verificar si contaf es 4
  44.             xorlw   .4      ;verificar si contaf es 4
  45.             btfsc   status,2;verificar si contaf es 4
  46.             goto    si4
  47.             incf    contaf,1  ;si son diferentes
  48.             rlf     filas,1
  49.             movfw   filas
  50.             movfw temp
  51.             return
  52. si4         movlw   .1
  53.             movwf   contaf
  54.             movwf   filas
  55.             movfw   filas
  56.             return
  57. ;
  58. interrupcion
  59.             movfw   portb       ;estoy leyendo 'abcdxxxx'
  60.             movwf   columnas
  61.             clrf    porta ;limpio porta para que no se queden colgados valores
  62.             swapf   columnas,1 ;    ahora tengo 'xxxxabcd'
  63.             call    delaym;
  64.             bsf     flag,0
  65.             nop
  66.             movfw   contaf  ;carga w con el valor de contaf , conta
  67.             xorlw   .1      ;comprueba si contaf vale 1
  68.             btfsc   status,2    ;revisa : si Z=1 caso1, si Z=0 , volver a preguntar
  69.             goto    casof1          ;;; aqui va si son iguales , caso1
  70.             movfw   contaf          ;aqui va si no es caso 1
  71.             xorlw   .2
  72.             btfsc   status,2
  73.             goto    casof2          ;;aqui va si es caso2
  74.             movfw   contaf
  75.             xorlw   .3
  76.             btfsc   status,2
  77.             goto    casof3          ;caso3
  78. casof4      movlw   .12     ;de lo contrario pasa a casof4
  79.             movwf   f      
  80.             goto    chkcol;return          
  81. casof3      movlw   .8
  82.             movwf   f
  83.             goto    chkcol;return
  84. casof2      movlw   .4
  85.             movwf   f
  86.             goto    chkcol;return
  87. casof1      movlw   .0
  88.             movwf   f
  89. chkcol      ;movfw   columnas;carga w con el valor capturado de portb en columnas
  90.             btfss   columnas,0 
  91.             goto    $+2
  92.             goto    casoc1          ;aqui va caso1         
  93.             btfss   columnas,1
  94.             goto    $+2    
  95.             goto    casoc2
  96.             btfss   columnas,2
  97.             goto    $+2
  98.             goto    casoc3
  99.             btfss   columnas,3
  100.             goto    $+2
  101. casoc4      movlw   .3 
  102.             movwf   c
  103.             goto    sumar;retfie
  104. casoc3      movlw   .2     
  105.             movwf   c
  106.             goto    sumar;retfie
  107. casoc2      movlw   .1
  108.             movwf   c
  109.             goto    sumar;retfie
  110. casoc1      movlw   .0
  111.             movwf   c
  112.             goto    sumar;retfie
  113. sumar       movf    c,0 ;cargamos w con el valor de c
  114.             addwf   f,0 ;sumamos w con f y lo guardamos en w
  115.             movwf   valor_real  ;cargamos valor_real con el valor de la suma
  116.             ;ya tengo mi valor real################################!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  117.             ;ya tengo mi valor real################################!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  118. verificar   movfw   contaf      ;verifica sin contaf=4 para reiniciarlo, casos contrarios <4 se incrementa su valor en 1
  119.             xorlw   .1
  120.             btfss   status,2    ;1 si son iguales,  0 si son diferentes
  121.             goto    $+2
  122.             goto    increment
  123.             movfw   contaf
  124.             xorlw   .2
  125.             btfss   status,2    ;1 si son iguales, 0 si son diferentes
  126.             goto    $+2
  127.             goto    increment
  128.             movwf   contaf
  129.             xorlw   .3
  130.             btfss   status,2
  131.             goto    $+2
  132.             goto    increment   ; si esq si es el caso 3
  133. re          movlw   .1     ;
  134.             movwf   contaf  ;reinicia conta=1
  135.             movwf   filas   ;filas=0001
  136.             movfw   valor_real  ;cargamos w con valor_real para pruebas
  137.             movwf   portb
  138.             call    delay500ms
  139.             ;call    delay500ms
  140.             ;call    delay500ms
  141.             ;call    delay500ms
  142.             movfw   filas   ;reinicia filas=0001
  143.             goto    salir      
  144. increment   incf    contaf,1
  145.             rlf     filas,1
  146.             movfw   valor_real
  147.             movwf   portb
  148.             call    delay500ms
  149.             ;call    delay500ms
  150.             ;call    delay500ms
  151.             ;call    delay500ms
  152.             movfw   filas  ; 0002,3,4      
  153. salir       MOVF PCLATH_TEMP, W ;Restore PCLATH
  154.         MOVWF PCLATH        ;Move W into PCLATH
  155.         SWAPF STATUS_TEMP,W ;Swap STATUS_TEMP register into W
  156.         ;(sets bank to original state)
  157.         MOVWF STATUS        ;Move W into STATUS register
  158.         SWAPF W_TEMP,F      ;Swap W_TEMP
  159.         SWAPF W_TEMP,W      ;Swap W_TEMP into W
  160.         bcf         intcon,0
  161.         retfie  
  162.  ;
  163. principal   ;##############################################
  164.             ;IOs
  165.             bsf     status,5
  166.             movlw   b'10000'   ;porta como salidas
  167.             movwf   trisa
  168.             movlw   b'11110000'
  169.             movwf   trisb
  170.             movlw   b'11010111' ;rbpullup no, intedge=subida, t0cs=f/4 ,t0ie:bajada, psa->tmr0 ratio 1:256
  171.             movwf   option_reg
  172.             bcf     status,5;de vuelta al banco0
  173.             movlw   b'10001000'
  174.             movwf   intcon
  175.             clrf    porta
  176.             clrf    portb
  177.             movlw   .1 ;cargar 1
  178.             movwf   contaf  ;se inicia con 1
  179.             movwf   filas   ;se inicia con 0001
  180.             clrf    valor_real
  181.             clrf    columnas
  182.            ; goto    inicio
  183.  inicio  btfss   flag,0
  184.             goto    aqui
  185.             bcf     flag,0     
  186.             clrf    porta
  187.             nop
  188. aqui        ;bsf            intcon,7
  189.             movfw   filas   ;w se carga con el valor de filas *******
  190.             movwf   porta
  191.             nop
  192.             call    delaym         
  193.             call    notecla
  194.             nop
  195.             nop;aqui va lo que se hará si no se presiono una tecla
  196.             goto    inicio
  197.             end

Ahora, el la llamada del call dentro de la rutina de interrupción, está por debajo de las subrutinas (hablando de la escritura en cascada). Si ahora lo vemos por la posición de memoria, la subrutina llamada delay500ms está en la posición 0x14 y el call que llama a esta subrutina está en la posición 0x36 (no te guíes por las numeraciones de línea. Recuerda que las etiquetas no ocupan posición de memoria, y las intrucciones que están con ; no son cargadas al pic.
« Última modificación: 20 de Mayo de 2020, 17:52:09 por Leon Pic »
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado cristhiamjara

  • PIC10
  • *
  • Mensajes: 15
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #11 en: 20 de Mayo de 2020, 13:32:49 »
Gracias Leon, probé el código modificado que sugeriste, pero sigue con el mismo resultado inesperado, por algún motivo que aún no entiendo el valor en mi display se modifica
No sé si compilaste el código en el circuito que adjunté en la foto, espero que se animen a hacerlo y así podamos resolver este problema.
Gracias!

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #12 en: 20 de Mayo de 2020, 17:55:20 »
Me parece que ya encontré el error.
La subrutina notecla te estaba cambiando el valor de w. En la subrutina de delay, lo salvabas en una variable llamada temp para luego recuperar este dato antes de salir, pero en la otra no lo hiciste.

Volvé a carga mi programa de mi mensaje anterior, que ya lo actualicé.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.

Desconectado cristhiamjara

  • PIC10
  • *
  • Mensajes: 15
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #13 en: 20 de Mayo de 2020, 19:25:36 »
Me parece que ya encontré el error.
La subrutina notecla te estaba cambiando el valor de w. En la subrutina de delay, lo salvabas en una variable llamada temp para luego recuperar este dato antes de salir, pero en la otra no lo hiciste.

Volvé a carga mi programa de mi mensaje anterior, que ya lo actualicé.
Hola de nuevo, ya lo probé y sigue igual,
fijate que dentro de todo el programa la única linea donde hago un "movwf portb" está dentro de la interrupción, en ninguna otra parte mando valores al portb, por eso no entiendo porque se cambia mi display que va conectado al portb.

Desconectado Leon Pic

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3610
    • Impresiones en 3D
Re:se modifica el valor de mi registro al retornar de una interrupción
« Respuesta #14 en: 21 de Mayo de 2020, 09:49:13 »
Vamos a partir del principio, como debimos hacerlo.
Primero, explicá mejor como funciona, ya que no se bien que es lo que tiene que hacer.

Necesito saber que hace cada rutina o subrutina; excepto las de delay que son obvias; ya que me pierdo en el programa. Que obtenés en cada rutina y en donde se guarda y para qué.
Jesús dijo, yo soy el CAMINO, la VERDAD y la VIDA, nadie llega al PADRE si no es por mi.


 

anything