Autor Tema: TecladoMatricial  (Leído 3456 veces)

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

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
TecladoMatricial
« en: 12 de Mayo de 2015, 11:43:56 »
Buenas tardes, Tengo que hacer el siguiente programa :

En vez de usar el puerto A para prender y apagar los diferentes dysplay, use el puerto C, no se porque con el puerto A no me anda.
Mi problema es el siguiente: creo que en el Mplab esta todo bien, y segun tengo entendido no voy a poder probar si anda o no desde el debuug, por el tema de las interrupciones externas. Asi que lo programe y lo estoy intentando Simularlo en Proteus, el problema es que no prende nada, cuando activo las resistencia pull UP, no hace nada, si desactivo las resistencias pull Up, me muestra los 3 ceros que me deberian mostrar cuando arrancas el programa, Pero la cosa es hacerlo con las resistecias pull UP.
Este es el codigo en cuestion:
Código: [Seleccionar]
list P=16F877A ;Comando que indica el Pic usado
#include "p16F877A.inc" ;Etiquetas genéricas para el Pic16F887

; CONFIG
; __config 0xFFFD
 __CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF


W_TEMP EQU 0X21
STATUS_TEMP EQU 0X22
Cont1 EQU 0x23
Cont2 EQU 0x24
Cont3 EQU 0x25
Cont4 EQU 0x26
Cont1A EQU 0x27
Cont2A EQU 0x28
Cont3A EQU 0x29
Cont4A EQU 0x30
ContLED EQU 0x31
ContTMR EQU 0x32

; -------
    ORG 0x00
    GOTO EMPEZAR
    ORG 0x04
    GOTO INTERRUPCION
    ORG 0x05

; ------------- Configuracion ---------------
EMPEZAR
    MOVLW 0x07
    MOVWF CMCON
    BSF STATUS, RP0 ; Banco 1
    BCF STATUS, RP1



    CLRF TRISC ; Puerto C como salida
    CLRF TRISD ; Puerto D como salida

    MOVLW B'00000111' ; ------ Configuramos el option REG con disivor 1:64 y R PULL up
    MOVWF OPTION_REG

    MOVLW b'11110000'
    MOVWF TRISB ; Puerto B como entrada



    MOVLW B'00101000' ; ------ Habilito Interrupcione por EXT
    MOVWF INTCON

    BCF STATUS, RP0 ; Banco 0

 
    MOVLW B'11110000'
    MOVWF PORTB
    CLRF PORTC
    CLRF PORTD


    MOVLW D'16'
    MOVWF Cont1A
    MOVWF Cont2A
    MOVWF Cont3A


    MOVLW D'3'
    MOVWF ContLED

    MOVLW D'3'
    MOVWF ContTMR


    MOVLW D'99'
    MOVWF TMR0
    BCF INTCON, RBIF
    ;BCF INTCON, T0IF
    BSF INTCON, GIE

;--------------------------------------

INICIO

    nop
    GOTO INICIO

TABLA
    ADDWF PCL,F
    RETLW B'00000000'
    RETLW B'01011100' ; F
    RETLW B'01111110' ; E
    RETLW B'01001111' ;D
    RETLW B'00110110' ;c
    RETLW B'00011111'
    RETLW B'01101111'
    RETLW B'01101111'
    RETLW B'01111111'
    RETLW B'01100001' ;7
    RETLW B'00111111'
    RETLW B'00111011';5
    RETLW B'01011001'
    RETLW B'01101011';3
    RETLW B'01101110'
    RETLW B'01000001'
    RETLW B'01110111'





INTERRUPCION
    MOVWF W_TEMP
    SWAPF STATUS,W
    MOVWF STATUS_TEMP

    MOVLW D'99'
    MOVWF TMR0

    BTFSC INTCON,RBIF
            GOTO INTERRUPCIONEXT
    BTFSC INTCON,T0IF
            GOTO INTERRUPCIONINT



RETORNA

    BCF INTCON,T0IF


    SWAPF STATUS_TEMP,W
    MOVWF STATUS
    SWAPF W_TEMP,F
    SWAPF W_TEMP,W

    RETFIE

LED0

    MOVF Cont1A,W
    CALL TABLA
    MOVWF PORTD
    BCF PORTC,3
    BSF PORTC,1
    BCF PORTC,2

    RETURN
LED1
    MOVF Cont2A,W
    CALL TABLA
    MOVWF PORTD
    BCF PORTC,1
    BSF PORTC,2
    BCF PORTC,3

    RETURN
LED2
    MOVF Cont3A,W
    CALL TABLA
    MOVWF PORTD
    BCF PORTC,1
    BCF PORTC,2
    BSF PORTC,3
    RETURN




TABLALED
    ADDWF PCL,F
    GOTO LED0
    GOTO LED2
    GOTO LED1
    GOTO LED0

    ;Rel_ContLED
    ;MOVLW D'4'
    ;MOVWF ContLED
    ;GOTO RETORNA

INTERRUPCIONEXT
    BCF INTCON, GIE
;------Rotacion de display
    MOVF Cont2A,W
    MOVWF Cont1A
    MOVF Cont3A,W
    MOVWF Cont2A
;-------------------------

    CALL Ver_Teclado
    MOVWF Cont3A

    MOVLW B'00000000'
    MOVWF PORTB

    BCF INTCON, RBIF
    BSF INTCON, GIE
    GOTO RETORNA

INTERRUPCIONINT

;--------------IMPRIME lo que hay en los contadores
    DECFSZ ContTMR,F
           GOTO SEGUIR
           GOTO SEGUIR1
SEGUIR1
    MOVLW D'3'
    MOVWF ContTMR

    MOVF ContLED,W
    CALL TABLALED
    DECFSZ ContLED,F
            GOTO SEGUIR
            MOVLW D'3'
            MOVWF ContLED
SEGUIR
    GOTO RETORNA



;-------------- NO LO USAMOS
   ; DECFSZ Cont1,F
        ;GOTO RETORNA
        ;GOTO Rei0


;------------- Identifica la tecla

Ver_Teclado
    BTFSS PORTB, 4 ; Fila 0
        GOTO Fila0
    BTFSS PORTB, 5 ; Fila 1
        GOTO Fila1
    BTFSS PORTB, 6 ; Fila 2
        GOTO Fila2
    BTFSS PORTB, 7 ; Fila 3
        GOTO Fila3

Fila0
    MOVLW B'00001110'
    MOVWF PORTB
    BTFSS PORTB, 4 ; Columna 3
          GOTO $+3
          CALL ANTIR
          RETLW D'15'
    MOVLW B'00001101'
    BTFSS PORTB, 4 ; Columna 2
          GOTO $+3
          CALL ANTIR
          RETLW D'12'
    MOVLW B'00001011'
    BTFSS PORTB, 4 ; Columna 1
          GOTO $+3
          CALL ANTIR
          RETLW D'9'
    MOVLW B'00000111'
    BTFSS PORTB,4  ; Columna 0
          GOTO $+3
          CALL ANTIR
          RETLW D'1'


Fila1
    MOVLW B'00001110'
    MOVWF PORTB
    BTFSS PORTB, 5 ; Columna 3
          GOTO $+3
          CALL ANTIR
          RETLW D'14'
    MOVLW B'00001101'
    BTFSS PORTB, 5 ; Columna 2
          GOTO $+3
          CALL ANTIR
          RETLW D'11'
    MOVLW B'00001011'
    BTFSS PORTB, 5 ; Columna 1
          GOTO $+3
          CALL ANTIR
          RETLW D'8'
     MOVLW B'00000111'
    BTFSS PORTB, 5 ; Columna 0
          GOTO $+3
          CALL ANTIR
          RETLW D'16'

Fila2
    MOVLW B'00001110'
    MOVWF PORTB
    BTFSS PORTB, 6 ; Columna 3
          GOTO $+3
          CALL ANTIR
          RETLW D'13'
    MOVLW B'00001101'
    BTFSS PORTB, 6 ; Columna 2
          GOTO $+3
          CALL ANTIR
          RETLW D'10'
    MOVLW B'00001011'
    BTFSS PORTB, 6 ; Columna 1
          GOTO $+3
          CALL ANTIR
          RETLW D'7'
    MOVLW B'00000111'
    BTFSS PORTB, 6 ; Columna 0
          GOTO $+3
          CALL ANTIR
          RETLW D'2'

Fila3
    MOVLW B'00001110'
    MOVWF PORTB
    BTFSS PORTB, 7 ; Columna 3
          GOTO $+3
          CALL ANTIR
          RETLW D'6'
    MOVLW B'00001101'
    BTFSS PORTB, 7 ; Columna 2
          GOTO $+3
          CALL ANTIR
          RETLW D'5'
    MOVLW B'00001011'
    BTFSS PORTB, 7 ; Columna 1
          GOTO $+3
          CALL ANTIR
          RETLW D'4'
    MOVLW B'00000111'
    BTFSS PORTB, 7 ; Columna 0
          GOTO $+3
          CALL ANTIR
          RETLW D'3'

;-------------------------

ANTIR
     BTFSC PORTB, 4
            GOTO ANTIR
     BTFSC PORTB, 5
            GOTO ANTIR
     BTFSC PORTB, 6
            GOTO ANTIR
     BTFSC PORTB, 7
            GOTO ANTIR
     RETURN



    END




Es probable que tenga algun numero mal mapeado para mostrar en los display, pero no importa eso, después corrijo esos errores.

Dejo una captura del Proteus, capaz puse algo mal:


Que podre tener mal?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: TecladoMatricial
« Respuesta #1 en: 12 de Mayo de 2015, 13:27:17 »
Bastante cosas a ver:

- El PORTA seguro que no te anda por que en el reset se configuran como analogicos, observaras que el PORTA tambien tiene la funcion del ADC ( ANx ), para ponerlos como digitales debes modificar el registro ADCON1, los bits PCFG3:PCFG1

- Hay algunas cosas del Hardware que me causan dudas. Como normalmente se hace el teclado matricial, se deberian activar una por 1 las columnas o las filas, y observar si se produce un cambio en su contraparte ( si activo columnas observo filas ) , si queres usar las interrupciones esto quiere decir que lo que leo, deberia estar conectado al RB4:RB7. Por otra parte como decia el hardware, supongamos que en diagrama activamos las filas y leemos las columnas, mientras no se presione nada las columnas van a estar en un valor incierto.. ya que no hay nada que los tenga en 0 o en 1. Asi que deberian tener una resistencia de pull-down o pull-up segun como utilizes tu logica. Esto tal ves en la simulacion si afecte

- No creo que la simulacion afecte que los displays no tienen resistencia, pero si pensas hacerlo fisico deberias tenerlo en cuenta.

Tu rutina de interrupcion:

- Estas recargando el timer cuando todavia no preguntas por que entraste a la interrupciones, esa recarga del timer deberia ir en lo que llamas INTERRUPCIONINT.
- Existe una posibilidad de que mientras estas haciendo el tratamiento del teclado ocurra una interrupcion del timer, pero no creo que exista ningun problema por que solo se retraso un poco un disparo.
- Te das cuenta que jamas va a dispararse la interrupcion del PORTB ya que nunca estas activando las filas ?
- Estas activando GIE cuando eso lo hace el RETFIE
- Y pare de mirarlo xD

Con lo que mi pregunta va.. es necesario usar las interrupciones para eso ? Yo lo haria solo con una interrupcion que seria el del timer, el timer me activa un flag y ese flag permite la ejecucion de todo (o solo la actualizacion de los displays) el programa. La decision de hacerlo asi fue por que ya que si activo O desactivo una fila O se suelta el boton ,cualquiera de esas va a entrar a la interrupcion ya que es por nivel. Y de hacerlo asi tendrias que hacer un programa que discrimine todo eso. Pero aun asi deberias de activar las filas para saber si se presiono algo o no. El activar una y desactivar otra va a hacer que se dispare sola la interrupcion y tambien deberias de preveer eso.

En fin como dije yo haria algo asi:
La rutina de leer el teclado puede o no estar dentro de la declaracion del FLAG, y que se ejecute siempre.

INTERRUPCION
     ;Salvo contexto (W,STATUS)
     MOVLW D'99'
     MOVWF TMR0
     BSF  FLAG,0
     BCF  INTCON,T0IF
      ;Limpio flag timer
      ; Devuelvo contexto
      RETFIE

MAIN
     BTFSC FLAG,0
     GOTO MAIN
     CALL LEER_TECLADO
     CALL DISPLAYS
     BCF FLAG,0
     GOTO MAIN

LEER_TECLADO
     ; Rutina de leer el teclado, comprobacion de que no sea el mismo boton, cambio en los registros
    
DISPLAYS
     ;Rutina de actualizacion de displays.
    
« Última modificación: 12 de Mayo de 2015, 13:32:27 por KILLERJC »

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Re: TecladoMatricial
« Respuesta #2 en: 12 de Mayo de 2015, 16:38:56 »
Gracias por la respuesta.

Bastante cosas a ver:

- El PORTA seguro que no te anda por que en el reset se configuran como analogicos, observaras que el PORTA tambien tiene la funcion del ADC ( ANx ), para ponerlos como digitales debes modificar el registro ADCON1, los bits PCFG3:PCFG1

Tenes razon, me falto configurar eso.


- Hay algunas cosas del Hardware que me causan dudas. Como normalmente se hace el teclado matricial, se deberian activar una por 1 las columnas o las filas, y observar si se produce un cambio en su contraparte ( si activo columnas observo filas ) , si queres usar las interrupciones esto quiere decir que lo que leo, deberia estar conectado al RB4:RB7. Por otra parte como decia el hardware, supongamos que en diagrama activamos las filas y leemos las columnas, mientras no se presione nada las columnas van a estar en un valor incierto.. ya que no hay nada que los tenga en 0 o en 1. Asi que deberian tener una resistencia de pull-down o pull-up segun como utilizes tu logica. Esto tal ves en la simulacion si afecte
Lo hice al reves, pero calculo que deberia andar igual, no se porque se me dio por hacerlo al reves, debí poner las filas como entradas (RB4-RB7) y las otras como salidas.

- No creo que la simulacion afecte que los displays no tienen resistencia, pero si pensas hacerlo fisico deberias tenerlo en cuenta.
En la simulacion no afecta, pero en fisico si lo pongo, pasa que como no hace falta en la simulacion lo salteo.

Tu rutina de interrupcion:

- Estas recargando el timer cuando todavia no preguntas por que entraste a la interrupciones, esa recarga del timer deberia ir en lo que llamas INTERRUPCIONINT.
- Existe una posibilidad de que mientras estas haciendo el tratamiento del teclado ocurra una interrupcion del timer, pero no creo que exista ningun problema por que solo se retraso un poco un disparo.
- Te das cuenta que jamas va a dispararse la interrupcion del PORTB ya que nunca estas activando las filas ?
- Estas activando GIE cuando eso lo hace el RETFIE
- Y pare de mirarlo xD
- Tenes razon, eso me olvide corregir.
-Si tambien pense eso, pero es poco probable, en todo caso podria apagar la habilitacion de la interrupcion por TMR0 cuanto este dentro de la rutina INTERRUPCIONEXT y listo.
-Esto no lo entendi, como no va a saltar la interrupcion nunca? como no activo las filas?. En teoria deberia saltar cuando toco cualquier tecla, que me pasa el "0" a la entrada en rb4-rb4, y ahi deberia saltar la interrupcion.
-Ah no sabia, yo siempre activaba el GIE una vez que salia de la interrupcion.

Con lo que mi pregunta va.. es necesario usar las interrupciones para eso ? Yo lo haria solo con una interrupcion que seria el del timer, el timer me activa un flag y ese flag permite la ejecucion de todo (o solo la actualizacion de los displays) el programa. La decision de hacerlo asi fue por que ya que si activo O desactivo una fila O se suelta el boton ,cualquiera de esas va a entrar a la interrupcion ya que es por nivel. Y de hacerlo asi tendrias que hacer un programa que discrimine todo eso. Pero aun asi deberias de activar las filas para saber si se presiono algo o no. El activar una y desactivar otra va a hacer que se dispare sola la interrupcion y tambien deberias de preveer eso.

Es necesario hacerlo con interrupciones si o si, porque en teoria tengo que dejar libre el micro para hacer otras cosas.

Tambien tengo un problema que no me salta ni la interrupcion del TMR0 si no toco nada, si desactivo los pullup, anda, si lo activo no me muestran el triple 0
« Última modificación: 12 de Mayo de 2015, 16:43:13 por rosalva40 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: TecladoMatricial
« Respuesta #3 en: 12 de Mayo de 2015, 18:06:42 »
Citar
Lo hice al reves, pero calculo que deberia andar igual, no se porque se me dio por hacerlo al reves, debí poner las filas como entradas (RB4-RB7) y las otras como salidas.
Los unicos que tienen capacidad de interrupcion son RB4 a RB7, y su interrupcion es si cambio o no la señal de entrada. Si pasa de 0 a 1 o como si pasa de 1 a 0

Asi que si queres hacerlo con interrupciones no te va a quedar otra que hacerlo con eso. En tu programa si no me equivoco lo tenes bien, pero ese no era mi punto, sino el que sigue:

Citar
-Esto no lo entendi, como no va a saltar la interrupcion nunca? como no activo las filas?. En teoria deberia saltar cuando toco cualquier tecla, que me pasa el "0" a la entrada en rb4-rb4, y ahi deberia saltar la interrupcion.

Crei que no tenias activado las pull-up, lo cual si o si vas a tener que activarlo

Citar
Tambien tengo un problema que no me salta ni la interrupcion del TMR0 si no toco nada, si desactivo los pullup, anda, si lo activo no me muestran el triple 0

Hay algunas cosas malas en el codigo, por ejemplo no podes estar esperando que se deje de presionar todo dentro de una interrupcion, la idea o concepto de una interrupcion es que se atienda lo mas rapido posible y salga. Por eso normalmente activo una flag que luego en mi programa principal actuo dependiendo de lo que se activo. Ademas solamente se activarian en los flancos esa interrupcion.
En simulacion no tenes rebotes, asi que si vas a implementar algun anti-rebote podes hacerlo por hw, o pensarlo de otra forma.
Tambien veo que en la rutina del teclado haces un MOVLW pero luego te falto ponerlo en PORTB, Tambien podria haberlo simplificado poniendo todo a 1 y el carry tambien a 1 y solo rotarlo

Tu codigo, un poco reformado:

Código: ASM
  1. ; __config 0xFFFD
  2.  __CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
  3.  
  4.  
  5. W_TEMP EQU 0X21
  6. STATUS_TEMP EQU 0X22
  7. Cont1 EQU 0x23
  8. Cont2 EQU 0x24
  9. Cont3 EQU 0x25
  10. Cont4 EQU 0x26
  11. Cont1A EQU 0x27
  12. Cont2A EQU 0x28
  13. Cont3A EQU 0x29
  14. Cont4A EQU 0x30
  15. ContLED EQU 0x31
  16. ContTMR EQU 0x32
  17.  
  18. ; -------
  19.     ORG 0x00
  20.     GOTO EMPEZAR
  21.     ORG 0x04
  22.     GOTO INTERRUPCION
  23.  
  24. ;-------------------------------------------------
  25. ;
  26. ; Configuracion
  27. ;
  28. ;-------------------------------------------------
  29.  
  30. EMPEZAR
  31.     MOVLW 0x07
  32.     MOVWF CMCON
  33.     BSF STATUS, RP0 ; Banco 1
  34.     BCF STATUS, RP1
  35.  
  36.  
  37.  
  38.     CLRF TRISC ; Puerto C como salida
  39.     CLRF TRISD ; Puerto D como salida
  40.  
  41.     MOVLW B'00000111' ; ------ Configuramos el option REG con disivor 1:64 y R PULL up
  42.     MOVWF OPTION_REG
  43.  
  44.     MOVLW b'11110000'
  45.     MOVWF TRISB ; Puerto B como entrada
  46.  
  47.  
  48.  
  49.     MOVLW B'00101000' ; ------ Habilito Interrupcione por EXT
  50.     MOVWF INTCON
  51.  
  52.     BCF STATUS, RP0 ; Banco 0
  53.  
  54.  
  55.     MOVLW B'11110000'
  56.     MOVWF PORTB
  57.     CLRF PORTC
  58.     CLRF PORTD
  59.  
  60.  
  61.     MOVLW D'16'
  62.     MOVWF Cont1A
  63.     MOVWF Cont2A
  64.     MOVWF Cont3A
  65.  
  66.  
  67.     MOVLW D'3'
  68.     MOVWF ContLED
  69.  
  70.     MOVLW D'3'
  71.     MOVWF ContTMR
  72.  
  73.  
  74.     MOVLW D'99'
  75.     MOVWF TMR0
  76.  
  77.     MOVF PORTB,W      ;Leo el PORTB y limpio flags antes de activar las interrupciones.
  78.     BCF INTCON, RBIF
  79.     BCF INTCON, T0IF
  80.     BSF INTCON, GIE
  81.  
  82. ;-------------------------------------------------
  83. ;
  84. ; Programa Principal
  85. ;
  86. ;-------------------------------------------------
  87.  
  88. INICIO
  89.  
  90.     nop
  91.     GOTO INICIO
  92.  
  93. ;-------------------------------------------------
  94. ;
  95. ; Tabla Hex - 7 segmentos
  96. ;
  97. ;-------------------------------------------------
  98.  
  99. TABLA
  100.     ADDWF PCL,F
  101.     RETLW B'00000000'
  102.     RETLW B'01011100' ; F
  103.     RETLW B'01111110' ; E
  104.     RETLW B'01001111' ;D
  105.     RETLW B'00110110' ;c
  106.     RETLW B'00011111'
  107.     RETLW B'01101111'
  108.     RETLW B'01101111'
  109.     RETLW B'01111111'
  110.     RETLW B'01100001' ;7
  111.     RETLW B'00111111'
  112.     RETLW B'00111011';5
  113.     RETLW B'01011001'
  114.     RETLW B'01101011';3
  115.     RETLW B'01101110'
  116.     RETLW B'01000001'
  117.     RETLW B'01110111'
  118.  
  119.  
  120. ;-------------------------------------------------
  121. ;
  122. ; Rutina de Interrupcion
  123. ;
  124. ;-------------------------------------------------
  125.  
  126.  
  127. INTERRUPCION
  128.     MOVWF W_TEMP
  129.     SWAPF STATUS,W
  130.     MOVWF STATUS_TEMP
  131.  
  132.     BTFSC INTCON,RBIF
  133.     GOTO INTERRUPCIONEXT
  134.     BTFSC INTCON,T0IF
  135.     GOTO INTERRUPCIONINT
  136.  
  137. RETORNA
  138.  
  139.     SWAPF STATUS_TEMP,W
  140.     MOVWF STATUS
  141.     SWAPF W_TEMP,F
  142.     SWAPF W_TEMP,W
  143.     RETFIE
  144.  
  145. ;-------------------------------------------------
  146. ;
  147. ; Rutina de interrupcion del PORTB
  148. ;
  149. ;-------------------------------------------------
  150.  
  151.  
  152. INTERRUPCIONEXT
  153.  
  154.     COMF PORTB,W       ; Complemento , para saber si es que se solto el boton. Esto hace que si todas las entradas estan a 1 (1111 sin nada presionado) sean 0 y poder ver el flag Z
  155.     ANDLW 0xF0         ; Separo unicamente entradas
  156.     BTFSC STATUS,Z
  157.     GOTO INT_PORTB_SALIR  ; Se solto el boton, no hay nada presionado, todas las entradas en 1111, asi que salgo
  158.  
  159.     MOVF Cont2A,W      ; En caso de que realmente se haya presionado un boton
  160.     MOVWF Cont1A       ; Rotacion del display
  161.     MOVF Cont3A,W
  162.     MOVWF Cont2A
  163.  
  164.     CALL Ver_Teclado   ; Veo que tecla se presiono
  165.     MOVWF Cont3A
  166.  
  167.     MOVLW B'00000000'  ; Pone a 0 el PORTB, esto implica que puede llegar a dispararse de nuevo la interrupcion o activarse el flag
  168.     MOVWF PORTB
  169.  
  170. INT_PORTB_SALIR
  171.     MOVF PORTB,W       ; Leo asi me permite la limpieza del flag
  172.     BCF INTCON, RBIF   ; Limpieza del flag
  173.     GOTO RETORNA
  174.  
  175.  
  176. ;-------------------------------------------------
  177. ;
  178. ; Rutina de interrupcion del TMR0
  179. ;
  180. ;-------------------------------------------------
  181.  
  182. INTERRUPCIONINT
  183.  
  184.     BCF INTCON,T0IF
  185.     MOVLW D'99'
  186.     MOVWF TMR0
  187.     DECFSZ ContTMR,F  ; Loop contador de interrupciones de timer
  188.     GOTO RETORNA
  189.  
  190.     MOVLW D'3'
  191.     MOVWF ContTMR     ;  Si se cumplio lo recargo
  192.  
  193.     MOVF ContLED,W    ;  Que display tengo que encender?
  194.     CALL TABLALED
  195.     DECFSZ ContLED,F  ;  Llego a 0? Lo recargo y vuelvo
  196.     GOTO RETORNA
  197.     MOVLW D'3'
  198.     MOVWF ContLED
  199.     GOTO RETORNA
  200.  
  201. ;-------------------------------------------------
  202. ;
  203. ; Funciones auxiliares de la interrupcion del TMR0
  204. ;
  205. ;-------------------------------------------------
  206.  
  207. TABLALED
  208.     ADDWF PCL,F
  209.     GOTO LED0
  210.     GOTO LED2
  211.     GOTO LED1
  212.     GOTO LED0
  213.  
  214. LED0
  215.     MOVF Cont1A,W
  216.     CALL TABLA
  217.     MOVWF PORTD
  218.     BCF PORTC,3         ; Acomode para que siempre desactive todo y luego active.
  219.     BCF PORTC,2
  220.     BSF PORTC,1
  221.     RETURN
  222.  
  223. LED1
  224.     MOVF Cont2A,W
  225.     CALL TABLA
  226.     MOVWF PORTD
  227.     BCF PORTC,1
  228.     BCF PORTC,3
  229.     BSF PORTC,2
  230.     RETURN
  231.  
  232. LED2
  233.     MOVF Cont3A,W
  234.     CALL TABLA
  235.     MOVWF PORTD
  236.     BCF PORTC,1
  237.     BCF PORTC,2
  238.     BSF PORTC,3
  239.     RETURN
  240.  
  241. ;-------------------------------------------------
  242. ;
  243. ; Funciones auxiliares de la interrupcion del PORTB
  244. ;
  245. ;-------------------------------------------------
  246.  
  247. Ver_Teclado
  248.     BTFSS PORTB, 4 ; Fila 0
  249.         GOTO Fila0
  250.     BTFSS PORTB, 5 ; Fila 1
  251.         GOTO Fila1
  252.     BTFSS PORTB, 6 ; Fila 2
  253.         GOTO Fila2
  254.         GOTO Fila3    ; Fila 3 - No queda otra
  255.  
  256. Fila0
  257.     MOVLW B'00001110'
  258.     MOVWF PORTB
  259.     BTFSS PORTB, 4 ; Columna 3
  260.     RETLW D'15'
  261.     MOVLW B'00001101'
  262.     MOVWF PORTB
  263.     BTFSS PORTB, 4 ; Columna 2
  264.     RETLW D'12'
  265.     MOVLW B'00001011'
  266.     MOVWF PORTB
  267.     BTFSS PORTB, 4 ; Columna 1
  268.     RETLW D'9'
  269.     RETLW D'1'
  270.          
  271.  
  272.  
  273. Fila1
  274.     MOVLW B'00001110'
  275.     MOVWF PORTB
  276.     BTFSS PORTB, 5 ; Columna 3
  277.     RETLW D'14'
  278.     MOVLW B'00001101'
  279.     MOVWF PORTB
  280.     BTFSS PORTB, 5 ; Columna 2
  281.     RETLW D'11'
  282.     MOVLW B'00001011'
  283.     MOVWF PORTB
  284.     BTFSS PORTB, 5 ; Columna 1
  285.     RETLW D'8'
  286.     RETLW D'16'
  287.  
  288. Fila2
  289.     MOVLW B'00001110'
  290.     MOVWF PORTB
  291.     BTFSS PORTB, 6 ; Columna 3
  292.     RETLW D'13'
  293.     MOVLW B'00001101'
  294.     MOVWF PORTB
  295.     BTFSS PORTB, 6 ; Columna 2
  296.     RETLW D'10'
  297.     MOVLW B'00001011'
  298.     MOVWF PORTB
  299.     BTFSS PORTB, 6 ; Columna 1
  300.     RETLW D'7'
  301.     RETLW D'2'
  302.  
  303. Fila3
  304.     MOVLW B'00001110'
  305.     MOVWF PORTB
  306.     BTFSS PORTB, 7 ; Columna 3
  307.     RETLW D'6'
  308.     MOVLW B'00001101'
  309.     MOVWF PORTB
  310.     BTFSS PORTB, 7 ; Columna 2
  311.     RETLW D'5'
  312.     MOVLW B'00001011'
  313.     MOVWF PORTB
  314.     BTFSS PORTB, 7 ; Columna 1
  315.     RETLW D'4'
  316.     RETLW D'3'
  317.  
  318.     END

Con respecto al antirebote, si lo queres hacer por soft, no podes hacerlo como estas haciendolo, seguro que existen algunas formas, pero la unica que se me ocurre es:
- Implementar que cada X tiempo se lean las entradas, es decir el timer active la lectura de las entradas, con lo cual tenes esa ventana entre interrupciones del timer que vas a tener tu antirebote. Con lo cual no te serviria de nada tener la interrupcion por PORTB. Y es parecido al ejemplo que di antes.
- Para hacerlo en la interrupcion, deberias desabilitar la interrupcion del PORTB, y activarla nuevamente con el timer (limpiando flags, etc) asi de esa forma tenes esa ventana entre interrupciones para que active nuevamente la interrupcion.
« Última modificación: 12 de Mayo de 2015, 19:33:48 por KILLERJC »

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Re: TecladoMatricial
« Respuesta #4 en: 12 de Mayo de 2015, 21:44:46 »
Hay algunas cosas malas en el codigo, por ejemplo no podes estar esperando que se deje de presionar todo dentro de una interrupcion, la idea o concepto de una interrupcion es que se atienda lo mas rapido posible y salga. Por eso normalmente activo una flag que luego en mi programa principal actuo dependiendo de lo que se activo. Ademas solamente se activarian en los flancos esa interrupcion.
En simulacion no tenes rebotes, asi que si vas a implementar algun anti-rebote podes hacerlo por hw, o pensarlo de otra forma.
Tambien veo que en la rutina del teclado haces un MOVLW pero luego te falto ponerlo en PORTB, Tambien podria haberlo simplificado poniendo todo a 1 y el carry tambien a 1 y solo rotarlo

Con respecto al antirebote, si lo queres hacer por soft, no podes hacerlo como estas haciendolo, seguro que existen algunas formas, pero la unica que se me ocurre es:
- Implementar que cada X tiempo se lean las entradas, es decir el timer active la lectura de las entradas, con lo cual tenes esa ventana entre interrupciones del timer que vas a tener tu antirebote. Con lo cual no te serviria de nada tener la interrupcion por PORTB. Y es parecido al ejemplo que di antes.
- Para hacerlo en la interrupcion, deberias desabilitar la interrupcion del PORTB, y activarla nuevamente con el timer (limpiando flags, etc) asi de esa forma tenes esa ventana entre interrupciones para que active nuevamente la interrupcion.

Muchas gracias por la respuesta, no entendi, porque no se puede implementar el antirrebote como lo hice yo, que tiene de mal?. osea lo tengo que hacer por software al antirrebote, y es verdad con lo ultimo, olvide de ponerlo en PORT B

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: TecladoMatricial
« Respuesta #5 en: 12 de Mayo de 2015, 23:40:48 »
El objetivo de la interrupcion es que se atienda y se salga inmediatamente, sino seria lo mismo que tenerlo en el programa principal. Me intento explicar:

Cuando ocurre una interrupcion , se deja el programa principal de lado y luego se vuelve al mismo. Casi como si nada hubiera ocurrido, pero realmente se hizo caso a esa interrupcion.

Si haces un bucle como hiciste, esto:

ANTIR
     BTFSC PORTB, 4
            GOTO ANTIR

Primero no es un antirebote, ya que en un rebote tenes varios 0 o 1 en periodos cortos de tiempo (Por lo que vos detectes como un 1 puede ser un rebote, lo cual entraria mas veces a la interrupcion). Por otra parte hasta que no soltes el boton no va a salir de ese bucle. Eso quiere decir que va a quedar atrapado en la interrupcion hasta que soltes el boton, si se produce el overflow del TMR0 no lo va a atender por que obviamente estan desabilitadas las interrupciones y esta atrapado ahi. Ademas si tu idea es hacer mas cosas, estarias "retrasando", o mejor dicho prihibiendo la ejecucion de lo demas hasta que soltes el boton

Si yo hiciera eso en el programa principal es otra cosa, por que ante una interrupcion, entraria a la misma y saldria, es decir las interrupciones siguen ocurriendo. Como deben ser.
Espero haberme hecho entender cual esmi punto de vista.
Es lo mismo que poner un delay dentro de una interrupcion.

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Re: TecladoMatricial
« Respuesta #6 en: 13 de Mayo de 2015, 00:38:27 »
El objetivo de la interrupcion es que se atienda y se salga inmediatamente, sino seria lo mismo que tenerlo en el programa principal. Me intento explicar:

Cuando ocurre una interrupcion , se deja el programa principal de lado y luego se vuelve al mismo. Casi como si nada hubiera ocurrido, pero realmente se hizo caso a esa interrupcion.

Si haces un bucle como hiciste, esto:

ANTIR
     BTFSC PORTB, 4
            GOTO ANTIR

Primero no es un antirebote, ya que en un rebote tenes varios 0 o 1 en periodos cortos de tiempo (Por lo que vos detectes como un 1 puede ser un rebote, lo cual entraria mas veces a la interrupcion). Por otra parte hasta que no soltes el boton no va a salir de ese bucle. Eso quiere decir que va a quedar atrapado en la interrupcion hasta que soltes el boton, si se produce el overflow del TMR0 no lo va a atender por que obviamente estan desabilitadas las interrupciones y esta atrapado ahi. Ademas si tu idea es hacer mas cosas, estarias "retrasando", o mejor dicho prihibiendo la ejecucion de lo demas hasta que soltes el boton

Si yo hiciera eso en el programa principal es otra cosa, por que ante una interrupcion, entraria a la misma y saldria, es decir las interrupciones siguen ocurriendo. Como deben ser.
Espero haberme hecho entender cual esmi punto de vista.
Es lo mismo que poner un delay dentro de una interrupcion.

Entendi perfectamente, pero podre hacer eso mismo que hice pero en el programa principal?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: TecladoMatricial
« Respuesta #7 en: 13 de Mayo de 2015, 01:38:50 »
Implementa o trata de implementar lo que te dije, es decir usar ese mismo timer como antirebote, es decir:
- Detecta cambio RB, interrupcion RB -> Me asguro que no sea por que se solto (1111). Pongo en 1 un flag y guardo el contador del timer en otro registro (esto para que sea al menos un ciclo de interrupcion). Desactivo interrupcion PORTB. Salgo
- Ocurre interrupcion del timer, procedo a mostrar el otro display,recargo timer, etc. Pregunto por el flag, y si contador guardado es igual a contador del timer (suponiendo que ya lo incrementaste), si se cumplen ambas condiciones, procedo a leer mi teclado matricial. Limpio flags activo nuevamente la interrupcion del PORTB.

Listo. Antirebote realizado con interrupciones. Tiempo minimo de tener apretado el boton va a ser como tomes la diferencia del contador (lo guardado y lo actual), por ejemplo si usas los 3 ciclos, entonces seria 3 * tiempo de overflow del timer, la idea seria como minimo 2 ciclos. Esto te daria tiempo para que ocurra el rebote y recien ahi leer el teclado. Luego de eso cuando se suelte se pone todo a 1111 e ignoro esa interrupcion.

Si lo queres hacer en el programa principal entonces seria algo asi como propuse yo al comienzo, lo que abarca tu flag puede ser solamente el teclado y lo del timer hacerlo en la interrupcion. Aunque aqui vas a necesitar de un registro para guardar el valor previo del puerto cuadno se detecto algo.

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Re: TecladoMatricial
« Respuesta #8 en: 13 de Mayo de 2015, 20:30:39 »
Implementa o trata de implementar lo que te dije, es decir usar ese mismo timer como antirebote, es decir:
- Detecta cambio RB, interrupcion RB -> Me asguro que no sea por que se solto (1111). Pongo en 1 un flag y guardo el contador del timer en otro registro (esto para que sea al menos un ciclo de interrupcion). Desactivo interrupcion PORTB. Salgo
- Ocurre interrupcion del timer, procedo a mostrar el otro display,recargo timer, etc. Pregunto por el flag, y si contador guardado es igual a contador del timer (suponiendo que ya lo incrementaste), si se cumplen ambas condiciones, procedo a leer mi teclado matricial. Limpio flags activo nuevamente la interrupcion del PORTB.

Listo. Antirebote realizado con interrupciones. Tiempo minimo de tener apretado el boton va a ser como tomes la diferencia del contador (lo guardado y lo actual), por ejemplo si usas los 3 ciclos, entonces seria 3 * tiempo de overflow del timer, la idea seria como minimo 2 ciclos. Esto te daria tiempo para que ocurra el rebote y recien ahi leer el teclado. Luego de eso cuando se suelte se pone todo a 1111 e ignoro esa interrupcion.

Si lo queres hacer en el programa principal entonces seria algo asi como propuse yo al comienzo, lo que abarca tu flag puede ser solamente el teclado y lo del timer hacerlo en la interrupcion. Aunque aqui vas a necesitar de un registro para guardar el valor previo del puerto cuadno se detecto algo.

Muchas gracias por la respustas ((:-)) , ultima y no te jodo mas jaja.
Hice esta rutina para el ANTIRREBOTE, anda bien ,aunque se que no es la mejor manera de hacerlo, Esta es la rutina en cuestion:
Código: [Seleccionar]
Fila3
    MOVLW B'00001110'
    MOVWF PORTB
    BTFSC PORTB, 7 ; Columna 3
        GOTO $+3
        CALL ANTIRREBOTE
    RETLW D'6'
    MOVLW B'00001101'
    MOVWF PORTB
    BTFSC PORTB, 7 ; Columna 2
        GOTO $+3
        CALL ANTIRREBOTE
    RETLW D'5'
    MOVLW B'00001011'
    MOVWF PORTB
    BTFSC PORTB, 7 ; Columna 1
        GOTO $+3
        CALL ANTIRREBOTE
    RETLW D'4'
    BTFSS PORTB, 7 ; Columna 0
        CALL ANTIRREBOTE
    RETLW D'3'
 
ANTIRREBOTE
    MOVLW 0XFF
    MOVWF ContANT
BUCLE DECFSZ ContANT,F
    GOTO BUCLE
    RETURN

Pego la ultima fila nomas, para no hacer tanto lio, en las demas filas hago lo mismo. en si pongo un retardo de 256US, nose si me quedare corto esos micro segundos o no, que opinas?
« Última modificación: 13 de Mayo de 2015, 21:11:09 por rosalva40 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: TecladoMatricial
« Respuesta #9 en: 14 de Mayo de 2015, 03:09:53 »
Lo que estas haciendo es un simple delay.

No es tan excesivo como esperar hasta que se deje de presionar como hiciste antes, pero es tiempo que el micro se la pasa haciendo nada y no pudiendo atender las interrupciones.
Lo cual va con tu idea principal de que el micro este desocupado para hacer otras cosas.

A mi me quedo algo asi:

Código: ASM
  1. ;-------------------------------------------------
  2. ;
  3. ;Palabra de configuracion
  4. ;
  5. ;-------------------------------------------------
  6.  
  7. ; __config 0xFFFD
  8.  __CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
  9.  
  10. ;-------------------------------------------------
  11. ;
  12. ; Definicion de variables
  13. ;
  14. ;-------------------------------------------------
  15.  
  16. W_TEMP EQU 0X21
  17. STATUS_TEMP EQU 0X22
  18. Cont1 EQU 0x23
  19. Cont2 EQU 0x24
  20. Cont3 EQU 0x25
  21. Cont4 EQU 0x26
  22. Cont1A EQU 0x27
  23. Cont2A EQU 0x28
  24. Cont3A EQU 0x29
  25. Cont4A EQU 0x30
  26. ContLED EQU 0x31
  27. ContTMR EQU 0x32
  28. FLAG EQU 0x33
  29.  
  30. ;-------------------------------------------------
  31. ;
  32. ; Vectores de reset/interrupcion
  33. ;
  34. ;-------------------------------------------------
  35.  
  36.     ORG 0x00
  37.     GOTO EMPEZAR
  38.     ORG 0x04
  39.     GOTO INTERRUPCION
  40.  
  41. ;-------------------------------------------------
  42. ;
  43. ; Configuracion
  44. ;
  45. ;-------------------------------------------------
  46.  
  47. EMPEZAR
  48.  
  49.     MOVLW 0x07
  50.     MOVWF CMCON
  51.     BSF STATUS, RP0 ; Banco 1
  52.     BCF STATUS, RP1
  53.  
  54.  
  55.     MOVLW b'11110000'
  56.     MOVWF TRISB ; Puerto B como entrada
  57.     CLRF TRISC ; Puerto C como salida
  58.     CLRF TRISD ; Puerto D como salida
  59.  
  60.     MOVLW B'00000111' ; ------ Configuramos el option REG con disivor 1:64 y R PULL up
  61.     MOVWF OPTION_REG
  62.     MOVLW B'00101000' ; ------ Habilito Interrupcione por EXT
  63.     MOVWF INTCON
  64.  
  65.     BCF STATUS, RP0 ; Banco 0
  66.  
  67.     MOVLW B'11110000'
  68.     MOVWF PORTB
  69.     CLRF PORTC
  70.     CLRF PORTD
  71.  
  72.     MOVLW D'16'
  73.     MOVWF Cont1A
  74.     MOVWF Cont2A
  75.     MOVWF Cont3A
  76.  
  77.     MOVLW D'3'
  78.     MOVWF ContLED
  79.  
  80.     MOVLW D'3'
  81.     MOVWF ContTMR
  82.  
  83.     MOVLW D'99'
  84.     MOVWF TMR0
  85.  
  86.     MOVF PORTB,W      ;Leo el PORTB y limpio flags antes de activar las interrupciones.
  87.     BCF INTCON, RBIF
  88.     BCF INTCON, T0IF
  89.     BSF INTCON, GIE
  90.  
  91. ;-------------------------------------------------
  92. ;
  93. ; Programa Principal
  94. ;
  95. ;-------------------------------------------------
  96.  
  97. INICIO
  98.  
  99.     nop
  100.     GOTO INICIO
  101.  
  102. ;-------------------------------------------------
  103. ;
  104. ; Tabla Hex - 7 segmentos
  105. ;
  106. ;-------------------------------------------------
  107.  
  108. TABLA
  109.     ADDWF PCL,F
  110.     RETLW B'00000000'
  111.     RETLW B'01011100' ; F
  112.     RETLW B'01111110' ; E
  113.     RETLW B'01001111' ;D
  114.     RETLW B'00110110' ;c
  115.     RETLW B'00011111'
  116.     RETLW B'01101111'
  117.     RETLW B'01101111'
  118.     RETLW B'01111111'
  119.     RETLW B'01100001' ;7
  120.     RETLW B'00111111'
  121.     RETLW B'00111011';5
  122.     RETLW B'01011001'
  123.     RETLW B'01101011';3
  124.     RETLW B'01101110'
  125.     RETLW B'01000001'
  126.     RETLW B'01110111'
  127.  
  128.  
  129. ;-------------------------------------------------
  130. ;
  131. ; Rutina de Interrupcion
  132. ;
  133. ;-------------------------------------------------
  134.  
  135.  
  136. INTERRUPCION
  137.     MOVWF W_TEMP
  138.     SWAPF STATUS,W
  139.     MOVWF STATUS_TEMP
  140.  
  141.     BTFSC INTCON,T0IF           ;El orden aca es importante
  142.     GOTO INTERRUPCIONINT
  143.     BTFSC INTCON,RBIF
  144.     GOTO INTERRUPCIONEXT
  145.  
  146. RETORNA
  147.  
  148.     SWAPF STATUS_TEMP,W
  149.     MOVWF STATUS
  150.     SWAPF W_TEMP,F
  151.     SWAPF W_TEMP,W
  152.     RETFIE
  153.  
  154. ;-------------------------------------------------
  155. ;
  156. ; Rutina de interrupcion del PORTB
  157. ;
  158. ;-------------------------------------------------
  159.  
  160.  
  161. INTERRUPCIONEXT
  162.  
  163.     COMF PORTB,W       ; Complemento , para saber si es que se solto el boton. Esto hace que si todas las entradas estan a 1 (1111 sin nada presionado) sean 0 y poder ver el flag Z
  164.     ANDLW 0xF0         ; Separo unicamente entradas
  165.     BTFSC STATUS,Z
  166.     GOTO INT_PORTB_SALIR  ; Se solto el boton, no hay nada presionado, todas las entradas en 1111, asi que salgo
  167.  
  168.     CLRF FLAG
  169.     BSF FLAG,7         ; Flag que entro aqui
  170.     MOVF ContTMR,W
  171.     IORWF FLAG,F       ; Guardo el valor del contador en el nibble bajo, esto para no crear otro registro.
  172.    
  173.     BCF INTCON, RBIE   ; Desactivo interrupciones por PORTB asi no toma en cuenta cualquier rebote.
  174.     GOTO RETORNA
  175.  
  176.  
  177. ;-------------------------------------------------
  178. ;
  179. ; Rutina de interrupcion del TMR0
  180. ;
  181. ;-------------------------------------------------
  182.  
  183. INTERRUPCIONINT
  184.  
  185.     BCF INTCON,T0IF
  186.     MOVLW D'99'
  187.     MOVWF TMR0
  188.     DECFSZ ContTMR,F  ; Loop contador de interrupciones de timer
  189.     GOTO MANEJO_KBD
  190.  
  191.     MOVLW D'3'
  192.     MOVWF ContTMR     ;  Si se cumplio lo recargo
  193.  
  194.     MOVF ContLED,W    ;  Que display tengo que encender?
  195.     CALL TABLALED
  196.     DECFSZ ContLED,F  ;  Llego a 0? Lo recargo y vuelvo
  197.     GOTO MANEJO_KBD
  198.     MOVLW D'3'
  199.     MOVWF ContLED
  200.    
  201. MANEJO_KBD
  202.     BTFSS FLAG,0
  203.     GOTO RETORNA      ; En caso de que no se activo el PORTB salgo
  204.     MOVLW 0x0F        ; Separo el nibble que me interesa
  205.     ANDWF FLAG,W
  206.     SUBWF ContTMR,W   ; Reviso si es igual
  207.     BTFSS STATUS,Z    ; Si es igual entonces realizo mi codigo, sino
  208.     GOTO RETORNA
  209.     BCF FLAG,7        ; Borro flag
  210.  
  211.     COMF PORTB,W       ; Compruebo nuevamente que no sea 0, por si se solto muy rapido.
  212.     ANDLW 0xF0         ;
  213.     BTFSC STATUS,Z
  214.     GOTO INT_PORTB_AUX
  215.  
  216.     MOVF Cont2A,W      ; En caso de que realmente se haya presionado un boton
  217.     MOVWF Cont1A       ; Rotacion del display
  218.     MOVF Cont3A,W
  219.     MOVWF Cont2A
  220.  
  221.     CALL Ver_Teclado   ; Veo que tecla se presiono
  222.     MOVWF Cont3A
  223.  
  224.     MOVLW B'00000000'  ; Pone a 0 el PORTB, esto implica que puede llegar a dispararse de nuevo la interrupcion o activarse el flag
  225.     MOVWF PORTB
  226.  
  227. INT_PORTB_AUX
  228.     BSF INTCON, RBIE   ; Habilito la interrupcion nuevamente
  229.  
  230. INT_PORTB_SALIR
  231.     MOVF PORTB,W       ; Leo asi me permite la limpieza del flag
  232.     BCF INTCON, RBIF   ; Limpieza del flag
  233.     GOTO RETORNA
  234.  
  235. ;-------------------------------------------------
  236. ;
  237. ; Funciones auxiliares de la interrupcion del TMR0
  238. ;
  239. ;-------------------------------------------------
  240.  
  241. TABLALED
  242.     ADDWF PCL,F
  243.     GOTO LED0
  244.     GOTO LED2
  245.     GOTO LED1
  246.     GOTO LED0
  247.  
  248. LED0
  249.     MOVF Cont1A,W
  250.     CALL TABLA
  251.     MOVWF PORTD
  252.     BCF PORTC,3         ; Acomode para que siempre desactive todo y luego active.
  253.     BCF PORTC,2
  254.     BSF PORTC,1
  255.     RETURN
  256.  
  257. LED1
  258.     MOVF Cont2A,W
  259.     CALL TABLA
  260.     MOVWF PORTD
  261.     BCF PORTC,1
  262.     BCF PORTC,3
  263.     BSF PORTC,2
  264.     RETURN
  265.  
  266. LED2
  267.     MOVF Cont3A,W
  268.     CALL TABLA
  269.     MOVWF PORTD
  270.     BCF PORTC,1
  271.     BCF PORTC,2
  272.     BSF PORTC,3
  273.     RETURN
  274.  
  275. ;-------------------------------------------------
  276. ;
  277. ; Funciones auxiliares de la interrupcion del PORTB
  278. ;
  279. ;-------------------------------------------------
  280.  
  281. Ver_Teclado
  282.     BTFSS PORTB, 4 ; Fila 0
  283.         GOTO Fila0
  284.     BTFSS PORTB, 5 ; Fila 1
  285.         GOTO Fila1
  286.     BTFSS PORTB, 6 ; Fila 2
  287.         GOTO Fila2
  288.         GOTO Fila3    ; Fila 3 - No queda otra
  289.  
  290. Fila0
  291.     MOVLW B'00001110'
  292.     MOVWF PORTB
  293.     BTFSS PORTB, 4 ; Columna 3
  294.     RETLW D'15'
  295.     MOVLW B'00001101'
  296.     MOVWF PORTB
  297.     BTFSS PORTB, 4 ; Columna 2
  298.     RETLW D'12'
  299.     MOVLW B'00001011'
  300.     MOVWF PORTB
  301.     BTFSS PORTB, 4 ; Columna 1
  302.     RETLW D'9'
  303.     RETLW D'1'
  304.          
  305.  
  306.  
  307. Fila1
  308.     MOVLW B'00001110'
  309.     MOVWF PORTB
  310.     BTFSS PORTB, 5 ; Columna 3
  311.     RETLW D'14'
  312.     MOVLW B'00001101'
  313.     MOVWF PORTB
  314.     BTFSS PORTB, 5 ; Columna 2
  315.     RETLW D'11'
  316.     MOVLW B'00001011'
  317.     MOVWF PORTB
  318.     BTFSS PORTB, 5 ; Columna 1
  319.     RETLW D'8'
  320.     RETLW D'16'
  321.  
  322. Fila2
  323.     MOVLW B'00001110'
  324.     MOVWF PORTB
  325.     BTFSS PORTB, 6 ; Columna 3
  326.     RETLW D'13'
  327.     MOVLW B'00001101'
  328.     MOVWF PORTB
  329.     BTFSS PORTB, 6 ; Columna 2
  330.     RETLW D'10'
  331.     MOVLW B'00001011'
  332.     MOVWF PORTB
  333.     BTFSS PORTB, 6 ; Columna 1
  334.     RETLW D'7'
  335.     RETLW D'2'
  336.  
  337. Fila3
  338.     MOVLW B'00001110'
  339.     MOVWF PORTB
  340.     BTFSS PORTB, 7 ; Columna 3
  341.     RETLW D'6'
  342.     MOVLW B'00001101'
  343.     MOVWF PORTB
  344.     BTFSS PORTB, 7 ; Columna 2
  345.     RETLW D'5'
  346.     MOVLW B'00001011'
  347.     MOVWF PORTB
  348.     BTFSS PORTB, 7 ; Columna 1
  349.     RETLW D'4'
  350.     RETLW D'3'
  351.  
  352.     END

Si hay un error es por que estaba bastante dormido.
« Última modificación: 14 de Mayo de 2015, 03:13:20 por KILLERJC »

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Re: TecladoMatricial
« Respuesta #10 en: 14 de Mayo de 2015, 08:33:41 »
Lo que estas haciendo es un simple delay.

No es tan excesivo como esperar hasta que se deje de presionar como hiciste antes, pero es tiempo que el micro se la pasa haciendo nada y no pudiendo atender las interrupciones.
Lo cual va con tu idea principal de que el micro este desocupado para hacer otras cosas.

A mi me quedo algo asi:

Código: ASM
  1. ;-------------------------------------------------
  2. ;
  3. ;Palabra de configuracion
  4. ;
  5. ;-------------------------------------------------
  6.  
  7. ; __config 0xFFFD
  8.  __CONFIG _FOSC_XT & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_ON & _CPD_OFF & _WRT_OFF & _CP_OFF
  9.  
  10. ;-------------------------------------------------
  11. ;
  12. ; Definicion de variables
  13. ;
  14. ;-------------------------------------------------
  15.  
  16. W_TEMP EQU 0X21
  17. STATUS_TEMP EQU 0X22
  18. Cont1 EQU 0x23
  19. Cont2 EQU 0x24
  20. Cont3 EQU 0x25
  21. Cont4 EQU 0x26
  22. Cont1A EQU 0x27
  23. Cont2A EQU 0x28
  24. Cont3A EQU 0x29
  25. Cont4A EQU 0x30
  26. ContLED EQU 0x31
  27. ContTMR EQU 0x32
  28. FLAG EQU 0x33
  29.  
  30. ;-------------------------------------------------
  31. ;
  32. ; Vectores de reset/interrupcion
  33. ;
  34. ;-------------------------------------------------
  35.  
  36.     ORG 0x00
  37.     GOTO EMPEZAR
  38.     ORG 0x04
  39.     GOTO INTERRUPCION
  40.  
  41. ;-------------------------------------------------
  42. ;
  43. ; Configuracion
  44. ;
  45. ;-------------------------------------------------
  46.  
  47. EMPEZAR
  48.  
  49.     MOVLW 0x07
  50.     MOVWF CMCON
  51.     BSF STATUS, RP0 ; Banco 1
  52.     BCF STATUS, RP1
  53.  
  54.  
  55.     MOVLW b'11110000'
  56.     MOVWF TRISB ; Puerto B como entrada
  57.     CLRF TRISC ; Puerto C como salida
  58.     CLRF TRISD ; Puerto D como salida
  59.  
  60.     MOVLW B'00000111' ; ------ Configuramos el option REG con disivor 1:64 y R PULL up
  61.     MOVWF OPTION_REG
  62.     MOVLW B'00101000' ; ------ Habilito Interrupcione por EXT
  63.     MOVWF INTCON
  64.  
  65.     BCF STATUS, RP0 ; Banco 0
  66.  
  67.     MOVLW B'11110000'
  68.     MOVWF PORTB
  69.     CLRF PORTC
  70.     CLRF PORTD
  71.  
  72.     MOVLW D'16'
  73.     MOVWF Cont1A
  74.     MOVWF Cont2A
  75.     MOVWF Cont3A
  76.  
  77.     MOVLW D'3'
  78.     MOVWF ContLED
  79.  
  80.     MOVLW D'3'
  81.     MOVWF ContTMR
  82.  
  83.     MOVLW D'99'
  84.     MOVWF TMR0
  85.  
  86.     MOVF PORTB,W      ;Leo el PORTB y limpio flags antes de activar las interrupciones.
  87.     BCF INTCON, RBIF
  88.     BCF INTCON, T0IF
  89.     BSF INTCON, GIE
  90.  
  91. ;-------------------------------------------------
  92. ;
  93. ; Programa Principal
  94. ;
  95. ;-------------------------------------------------
  96.  
  97. INICIO
  98.  
  99.     nop
  100.     GOTO INICIO
  101.  
  102. ;-------------------------------------------------
  103. ;
  104. ; Tabla Hex - 7 segmentos
  105. ;
  106. ;-------------------------------------------------
  107.  
  108. TABLA
  109.     ADDWF PCL,F
  110.     RETLW B'00000000'
  111.     RETLW B'01011100' ; F
  112.     RETLW B'01111110' ; E
  113.     RETLW B'01001111' ;D
  114.     RETLW B'00110110' ;c
  115.     RETLW B'00011111'
  116.     RETLW B'01101111'
  117.     RETLW B'01101111'
  118.     RETLW B'01111111'
  119.     RETLW B'01100001' ;7
  120.     RETLW B'00111111'
  121.     RETLW B'00111011';5
  122.     RETLW B'01011001'
  123.     RETLW B'01101011';3
  124.     RETLW B'01101110'
  125.     RETLW B'01000001'
  126.     RETLW B'01110111'
  127.  
  128.  
  129. ;-------------------------------------------------
  130. ;
  131. ; Rutina de Interrupcion
  132. ;
  133. ;-------------------------------------------------
  134.  
  135.  
  136. INTERRUPCION
  137.     MOVWF W_TEMP
  138.     SWAPF STATUS,W
  139.     MOVWF STATUS_TEMP
  140.  
  141.     BTFSC INTCON,T0IF           ;El orden aca es importante
  142.     GOTO INTERRUPCIONINT
  143.     BTFSC INTCON,RBIF
  144.     GOTO INTERRUPCIONEXT
  145.  
  146. RETORNA
  147.  
  148.     SWAPF STATUS_TEMP,W
  149.     MOVWF STATUS
  150.     SWAPF W_TEMP,F
  151.     SWAPF W_TEMP,W
  152.     RETFIE
  153.  
  154. ;-------------------------------------------------
  155. ;
  156. ; Rutina de interrupcion del PORTB
  157. ;
  158. ;-------------------------------------------------
  159.  
  160.  
  161. INTERRUPCIONEXT
  162.  
  163.     COMF PORTB,W       ; Complemento , para saber si es que se solto el boton. Esto hace que si todas las entradas estan a 1 (1111 sin nada presionado) sean 0 y poder ver el flag Z
  164.     ANDLW 0xF0         ; Separo unicamente entradas
  165.     BTFSC STATUS,Z
  166.     GOTO INT_PORTB_SALIR  ; Se solto el boton, no hay nada presionado, todas las entradas en 1111, asi que salgo
  167.  
  168.     CLRF FLAG
  169.     BSF FLAG,7         ; Flag que entro aqui
  170.     MOVF ContTMR,W
  171.     IORWF FLAG,F       ; Guardo el valor del contador en el nibble bajo, esto para no crear otro registro.
  172.    
  173.     BCF INTCON, RBIE   ; Desactivo interrupciones por PORTB asi no toma en cuenta cualquier rebote.
  174.     GOTO RETORNA
  175.  
  176.  
  177. ;-------------------------------------------------
  178. ;
  179. ; Rutina de interrupcion del TMR0
  180. ;
  181. ;-------------------------------------------------
  182.  
  183. INTERRUPCIONINT
  184.  
  185.     BCF INTCON,T0IF
  186.     MOVLW D'99'
  187.     MOVWF TMR0
  188.     DECFSZ ContTMR,F  ; Loop contador de interrupciones de timer
  189.     GOTO MANEJO_KBD
  190.  
  191.     MOVLW D'3'
  192.     MOVWF ContTMR     ;  Si se cumplio lo recargo
  193.  
  194.     MOVF ContLED,W    ;  Que display tengo que encender?
  195.     CALL TABLALED
  196.     DECFSZ ContLED,F  ;  Llego a 0? Lo recargo y vuelvo
  197.     GOTO MANEJO_KBD
  198.     MOVLW D'3'
  199.     MOVWF ContLED
  200.    
  201. MANEJO_KBD
  202.     BTFSS FLAG,0
  203.     GOTO RETORNA      ; En caso de que no se activo el PORTB salgo
  204.     MOVLW 0x0F        ; Separo el nibble que me interesa
  205.     ANDWF FLAG,W
  206.     SUBWF ContTMR,W   ; Reviso si es igual
  207.     BTFSS STATUS,Z    ; Si es igual entonces realizo mi codigo, sino
  208.     GOTO RETORNA
  209.     BCF FLAG,7        ; Borro flag
  210.  
  211.     COMF PORTB,W       ; Compruebo nuevamente que no sea 0, por si se solto muy rapido.
  212.     ANDLW 0xF0         ;
  213.     BTFSC STATUS,Z
  214.     GOTO INT_PORTB_AUX
  215.  
  216.     MOVF Cont2A,W      ; En caso de que realmente se haya presionado un boton
  217.     MOVWF Cont1A       ; Rotacion del display
  218.     MOVF Cont3A,W
  219.     MOVWF Cont2A
  220.  
  221.     CALL Ver_Teclado   ; Veo que tecla se presiono
  222.     MOVWF Cont3A
  223.  
  224.     MOVLW B'00000000'  ; Pone a 0 el PORTB, esto implica que puede llegar a dispararse de nuevo la interrupcion o activarse el flag
  225.     MOVWF PORTB
  226.  
  227. INT_PORTB_AUX
  228.     BSF INTCON, RBIE   ; Habilito la interrupcion nuevamente
  229.  
  230. INT_PORTB_SALIR
  231.     MOVF PORTB,W       ; Leo asi me permite la limpieza del flag
  232.     BCF INTCON, RBIF   ; Limpieza del flag
  233.     GOTO RETORNA
  234.  
  235. ;-------------------------------------------------
  236. ;
  237. ; Funciones auxiliares de la interrupcion del TMR0
  238. ;
  239. ;-------------------------------------------------
  240.  
  241. TABLALED
  242.     ADDWF PCL,F
  243.     GOTO LED0
  244.     GOTO LED2
  245.     GOTO LED1
  246.     GOTO LED0
  247.  
  248. LED0
  249.     MOVF Cont1A,W
  250.     CALL TABLA
  251.     MOVWF PORTD
  252.     BCF PORTC,3         ; Acomode para que siempre desactive todo y luego active.
  253.     BCF PORTC,2
  254.     BSF PORTC,1
  255.     RETURN
  256.  
  257. LED1
  258.     MOVF Cont2A,W
  259.     CALL TABLA
  260.     MOVWF PORTD
  261.     BCF PORTC,1
  262.     BCF PORTC,3
  263.     BSF PORTC,2
  264.     RETURN
  265.  
  266. LED2
  267.     MOVF Cont3A,W
  268.     CALL TABLA
  269.     MOVWF PORTD
  270.     BCF PORTC,1
  271.     BCF PORTC,2
  272.     BSF PORTC,3
  273.     RETURN
  274.  
  275. ;-------------------------------------------------
  276. ;
  277. ; Funciones auxiliares de la interrupcion del PORTB
  278. ;
  279. ;-------------------------------------------------
  280.  
  281. Ver_Teclado
  282.     BTFSS PORTB, 4 ; Fila 0
  283.         GOTO Fila0
  284.     BTFSS PORTB, 5 ; Fila 1
  285.         GOTO Fila1
  286.     BTFSS PORTB, 6 ; Fila 2
  287.         GOTO Fila2
  288.         GOTO Fila3    ; Fila 3 - No queda otra
  289.  
  290. Fila0
  291.     MOVLW B'00001110'
  292.     MOVWF PORTB
  293.     BTFSS PORTB, 4 ; Columna 3
  294.     RETLW D'15'
  295.     MOVLW B'00001101'
  296.     MOVWF PORTB
  297.     BTFSS PORTB, 4 ; Columna 2
  298.     RETLW D'12'
  299.     MOVLW B'00001011'
  300.     MOVWF PORTB
  301.     BTFSS PORTB, 4 ; Columna 1
  302.     RETLW D'9'
  303.     RETLW D'1'
  304.          
  305.  
  306.  
  307. Fila1
  308.     MOVLW B'00001110'
  309.     MOVWF PORTB
  310.     BTFSS PORTB, 5 ; Columna 3
  311.     RETLW D'14'
  312.     MOVLW B'00001101'
  313.     MOVWF PORTB
  314.     BTFSS PORTB, 5 ; Columna 2
  315.     RETLW D'11'
  316.     MOVLW B'00001011'
  317.     MOVWF PORTB
  318.     BTFSS PORTB, 5 ; Columna 1
  319.     RETLW D'8'
  320.     RETLW D'16'
  321.  
  322. Fila2
  323.     MOVLW B'00001110'
  324.     MOVWF PORTB
  325.     BTFSS PORTB, 6 ; Columna 3
  326.     RETLW D'13'
  327.     MOVLW B'00001101'
  328.     MOVWF PORTB
  329.     BTFSS PORTB, 6 ; Columna 2
  330.     RETLW D'10'
  331.     MOVLW B'00001011'
  332.     MOVWF PORTB
  333.     BTFSS PORTB, 6 ; Columna 1
  334.     RETLW D'7'
  335.     RETLW D'2'
  336.  
  337. Fila3
  338.     MOVLW B'00001110'
  339.     MOVWF PORTB
  340.     BTFSS PORTB, 7 ; Columna 3
  341.     RETLW D'6'
  342.     MOVLW B'00001101'
  343.     MOVWF PORTB
  344.     BTFSS PORTB, 7 ; Columna 2
  345.     RETLW D'5'
  346.     MOVLW B'00001011'
  347.     MOVWF PORTB
  348.     BTFSS PORTB, 7 ; Columna 1
  349.     RETLW D'4'
  350.     RETLW D'3'
  351.  
  352.     END

Si hay un error es por que estaba bastante dormido.

Gracias nuevamente, puede ser que en la línea 202 cuando preguntas por la flag, en vez d preguntar por el bit 0, no debería ser el bit 7?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: TecladoMatricial
« Respuesta #11 en: 14 de Mayo de 2015, 10:02:09 »
Si, como dije estaba dormido.

Pense primero en tener un registro unicamente para las flags ( que es lo que deberia hacer, en especial si tu programa va a hacer otra cosa y necesitas de otra flag ) y otro registro para mantener el valor del Contador del TMR.

Pero luego para ahorrarme un registro utilize el mismo. Fue ahi cuando cambie el bit 0 por el bit 7. Y ese me quedo.

Tranquilamente podria NO haber usado el tema del Contador del TMR y esperar a la proxima interrupcion, pero se me pasaba por la cabeza el caso en que se toque la tecla e inmediatamente entrara a la interrupcion del timer, no cumpliendose el tiempo de espera suficiente para un rebote. Como uno normalmente presiona por milisegundos un boton entonces no deberia haber problema de esperar esa cantidad de interrupciones.

Espero que te des cuenta cual es mi idea detras de esto.

Desconectado rosalva40

  • PIC10
  • *
  • Mensajes: 19
Re: TecladoMatricial
« Respuesta #12 en: 14 de Mayo de 2015, 11:28:58 »
Si, como dije estaba dormido.

Pense primero en tener un registro unicamente para las flags ( que es lo que deberia hacer, en especial si tu programa va a hacer otra cosa y necesitas de otra flag ) y otro registro para mantener el valor del Contador del TMR.

Pero luego para ahorrarme un registro utilize el mismo. Fue ahi cuando cambie el bit 0 por el bit 7. Y ese me quedo.

Tranquilamente podria NO haber usado el tema del Contador del TMR y esperar a la proxima interrupcion, pero se me pasaba por la cabeza el caso en que se toque la tecla e inmediatamente entrara a la interrupcion del timer, no cumpliendose el tiempo de espera suficiente para un rebote. Como uno normalmente presiona por milisegundos un boton entonces no deberia haber problema de esperar esa cantidad de interrupciones.

Espero que te des cuenta cual es mi idea detras de esto.

Sisi, entendi bien, muchas gracias,  ((:-)) , fuiste de mucha ayuda


 

anything