Autor Tema: Problema con rebotes no solucionables por software.  (Leído 7169 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Problema con rebotes no solucionables por software.
« Respuesta #15 en: 04 de Diciembre de 2008, 08:31:34 »
Yo uso C de CCS, pero no te preocupes, que hay mucho asmadicto por aquí que te echará una mano.

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Problema con rebotes no solucionables por software.
« Respuesta #16 en: 04 de Diciembre de 2008, 13:37:12 »
Hola:

En el código que pusiste, faltan algunos detalles importantes, por ejemplo cuando ingresas al RSI debes guardar, por lo menos, el registro W y STATUS, y al salir del RSI debes recuperarlos. Recuerda que el RSI apunta a la dirección 04 de la memoria de programa, entonces antes del label ISR debes colocar el ORG H'04'.

Ten en cuenta siempre que el valor que hayas cargado al prescaler se borra cuando escribes un valor al Timer0 por ello primero debes cargar el valor que deseas al Timer0 y a continuación cargas el valor del prescaler. Antes del retfie debes borrar los flags de las interrupciones que se producen.

Javicho.

Desconectado japdos

  • PIC10
  • *
  • Mensajes: 13
Re: Problema con rebotes no solucionables por software.
« Respuesta #17 en: 05 de Diciembre de 2008, 06:26:34 »
Javicho, 'casi' todo lo que me dices, estaba hecho, solo que al cortar y pega el código, pues no lo he puesto.
La copia y restauracion de los registros W y demás está en la subrutina OPERATIVA.
El poner a cero de nuevo el flag de la interrupcion producida, no lo copié.
y efectivamente en la direccion 0x04 tengo un goto a ISR...
Date cuenta que tenía el programa entero funcionando correctamente, me refiero a la versión que sólo usaba interrupciones por cambio de estado del puerto B (y que es la que tenía el problema de los rebotes).
Ahora al meter la T0I es cuando he empezado a tener ese problema de no producirse la int.
Lo que no sabía era que el preescaler se borra, quizá hayas dado ahí con mi problema,  aunque pienso que de borrarse y quedar sin preescalar, se producirían más interrupciones que las calculadas.... y no se me produce ninguna.
Incluso si cargo en el inicio del programa el timer, nunca se llega a producir (ni siquiera una vez)


(es que poner todo el código aquí es un tocho impresionante, siento haber copiado y pegado mal).

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Problema con rebotes no solucionables por software.
« Respuesta #18 en: 05 de Diciembre de 2008, 12:46:52 »
Los registros w y status se guardan al comienzo del RSI, algo asi:

;---------------
RSI   movwf   W_TEMP1
   swapf   STATUS,w
   clrf      STATUS
   movwf   STATUS_TEMP
   movf   PCLATH,w
   movwf   PCLATH_TEMP
   clrf      PCLATH
   movf   FSR,w
   movwf   FSR_TEMP
;---------------
   btfsc   INTCON,T0IF
   goto   Interrupción_TMR0
...
...
...
;---------------
Salir_RSI
   movlw   .131
   movwf   TMR0
   Banco1
   movlw   b'00000100'      ;4mS = (4/4MHz) * 32 * (256-131=125)
   movwf   OPTION_REG   ;precarga de TMR0: 131 y prescaler de 8
   Banco0

   movlw   b'11111000'
   andwf   INTCON,f      ;LIMPLIA todos los FLAGS Y RESTABLECE INTS.
   movf   FSR_TEMP,w
   movwf   FSR
   movf   PCLATH_TEMP,w
   movwf   PCLATH
   swapf   STATUS_TEMP,w
   movwf   STATUS
   swapf   W_TEMP1,f
   swapf   W_TEMP1,w
   retfie
;---------------
En este ejemplo cada 4mS se produce el desborde del Timer0

Javicho.

Desconectado japdos

  • PIC10
  • *
  • Mensajes: 13
Re: Problema con rebotes no solucionables por software.
« Respuesta #19 en: 10 de Diciembre de 2008, 07:17:17 »
Bueno, pues ya está efectuado el cambio en todo el código.
Ahora, según vuestras indicaciones, tengo un bucle principal, donde testeo la pulsación de los botones, y una ISR activada por desbordamiento del timer, encargada de visualizar los displays.
Parece que todo funciona bien, salvo unas excepciones que me están volviendo loco.
Los marcadores se muestran correctamente, y 7 botones funcionan bien, otros 7 no funcionan.
El bucle principal del programa es el siguiente:
polling
   btfsc BANDERAS,F_PARTIDA_REINICIAR
   goto INICIO_2                        ; Si se tiene la orden de reiniciar, salta del bucle principal

   MOVF   PORTB,W         ; Lee el valor del botón pulsado (a través de RB4-7)
   andlw   b'11110000'      ; Del puerto B se queda solamente con el nibble alto (rb4-7)
   sublw   b'00000000'   ; y se comprueba que no haya ningun boton pulsado
   btfsc   STATUS,2       ; (¿rb4-7=0?)
   goto    fin_polling   ; sí, no hay boton pulsado, sigue testeando
   call Retardo_10ms     ; no, espera a que es estabilice y...
   MOVF   PORTB,W            ; Vuelve a leer el puerto para leer el valor estabilizado
   movwf    BTN_PRES      ; Lo almacena en una variable
   andlw   b'11110000'      ; Del puerto B se queda solamente con el nibble alto (rb4-7)
   sublw   b'00000000'    ; y se comprueba que no sea un rebote
   btfsc   STATUS,2       ; si lo es...
   goto    fin_polling   ; sigue testeando
   call ejecuta            ; si no es rebote efectua los calculos
   call convierte_bcd   
EsperaDejePulsar
   MOVF   PORTB,W         ; Mientras el boton está pulsado continua en un bucle leyendo el puerto
   andlw   b'11110000'      ; hasta que sea soltado
   sublw   b'00000000'
   btfss   STATUS,2      
   goto EsperaDejePulsar   
fin_polling goto polling

La rutina de la ISR, como he dicho antes, visualiza alternativamente cada display (cada 500us). y la subrutina "ejecuta", hace los calculos de suma dependiendo de qué boton de los 14 existentes se haya pulsado.
Cada botón suma un valor determinado, los 7 primeros suman bien, pero los últimos 7 no lo hacen.

Después de devanarme mucho los sesos, pienso que quizá sea  un problema 'hardware':
Como no tengo un pin de un puerto para indicar la pulsación de un botón, sino que son 4 pines a la vez, tengo que comprobar con comparacion de palabras enteras y quizá esto sea un problema porque no todos los bits estén a la vez. Esto es así por el encoder que utilizo y que he comentado anteriormente, lo que ocurre, es que el encoder, no es de 16 entradas y 4 salidas (sino que son dos 74ls148 de 8 entradas y 3 salidas, colocados encadenados en cascada), y quizá se deba a un comportamiento relativo a los tiempos en los que tarda el acarreo en llegar al cuarto bit de la salida que conforman los 2 enconder unidos. Pienso esto, porque curiosamente, los botones que no funcionan, son los que tienen ese cuarto bit a 1.
1XXX no suman nada (si los pulso rápidamente repetidas veces, alguna vez sí suman el valor correcto, pero 1 de cada 30...)
0XXX sí suman bien siempre.

(el diseño electrónico funciona porque con la versión anterior del programa (con RBIE) , sumaba los 14 valores correctamente. pero estaba el problema del rebote. Y como he comentado antes, si pulso repetidas veces, tb suma correctamente el valor del botón pulsado.

¿Puede ser? ¿y como puedo solventarlo? sino, ¿a alguien se le ocurre qué otra cosa puede estar pasando?

gracias de nuevo.

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Problema con rebotes no solucionables por software.
« Respuesta #20 en: 11 de Diciembre de 2008, 13:47:47 »
Lo que pasa es que 10mS de delay antirebote es muy poco dale entre 20 y 50mS y en la rutina "EsperaDejePulsar" ten en cuenta que tambien se produce rebote del pulsador al soltarlo, es decir, el rebote se produce cuando presionas y cuando sueltas el pulsador.

Javicho.