Autor Tema: no logro hacer andar multiplex display en 16f627A ¡ayuda por favor!  (Leído 2091 veces)

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

Desconectado bluesboy

  • PIC12
  • **
  • Mensajes: 89
Buenas gente, soy novato en esto.
Antes que nada gracias por el tiempo que le pongan a esto. Gracias.
Hice el programa que pongo a continuacion. la idea es que si se activa un sensor, por rb7 config como interrupcion, cuente en unos display de 7 seg, de 4 cifras. tengo 2 chips pq necesitaba hacer otras cosas y en los dos hace lo mismo. lo borro, lo grabo y nada.
Lo pruebo en el pic simulator y va genial, pero en la realidad no funciona, lo que hace es mostrar alternativamente, la unidad en todos los display y el cero, con lo cual quedan los 4 displays en 0 y la cifra de la unidad apenas mas intensa. Baje los tiempos para ver que pasaba y ponia en un tiempo todos ceros y en otro la unidad en los 4.
No tengo idea de donde puede estar el error :(. Y lamentablemente necesito solucionarlo. :shock:
Les dejo el programa.

SE AGRADECE CUALQUIER SUGERENCIA.
Gracias. Sebastián.


; **** Encabezado ****
        LIST       P=16F627A   ; Microcontrolador utilizado.-
        INCLUDE    <P16F627A.INC>    ; Definicion de registros SFR.-
        __CONFIG   _INTOSC_OSC_NOCLKOUT & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _MCLRE_ON & _BOREN_OFF & _LVP_OFF &_CPD_OFF
;**** Definicion de Variables ****
        ; En esta posicion se declaran los registros de usuario (GPR).
UNIDAD      EQU 0X29              ;Guardo Conteo unidad.
DECENA      EQU 0X2A                ;Decena.
CENTENA     EQU 0X2B                ;Centena.
MILLAR      EQU 0X2C                ;Unidad de mil.
CONTADOR1   EQU 0X20           ;registro utlizado en demora 5mS
CONTADOR2   EQU 0X21           ;registro usado en demora   5mS
CONTADOR    EQU 0X22            ;registro usado en Rutina Activ de Display RAD
CONTADOR3   EQU 0X23        ;Registro utilizado en demora antirrebote
CONTADOR4   EQU 0X24        ;Registro utilizado en demora antirrebote
W_TEMP      EQU 0X25        ;REGISTRO TEMPORAL PARA INTERRUPCION
STATUS_TEMP EQU 0X26         ;REGISTRO TEMPORAL PARA INTERRUPCION
DEMORADO1   EQU 0X27
DEMORADO2   EQU 0X28
        ; FINAL DE DECLARACION DE REGISTROS.
        ;Empieza declaración de bits.
        MUESTROU    EQU 3   ;CONTROL 1º DISPLAY
        MUESTROD    EQU 2   ;control 2º display
        MUESTROC    EQU 1   ;control 3º display
        MUESTROM    EQU 0   ;control 4 display
        CUENTA      EQU 6   ;BIT6 porta para saber si cuenta o descuenta.
;
;**** Inicio del Microcontrolador ****
RESET   ORG       0x00
        GOTO   INICIO      ; Salto a inicio del programa.-
        ORG     0X04        ;VECTOR INTERRUPCION
        BTFSC   INTCON,RBIF
        GOTO    INTEXT
        RETFIE
;**** Programa principal ****
        ORG     0X07
INICIO
;CONFIGURACIONES PIC
        BCF     STATUS,6
        BSF     STATUS,5    ;CAMBIO A BANCO1
        MOVLW   0x70
        MOVWF   TRISA   ;seeessss
        MOVLW   0x80
        MOVWF   TRISB   ;Esssssss RB7 como entrada para rbif
        MOVLW   0xDF
        MOVWF   OPTION_REG  ; Pull-Up deshabilitados, , Timer0|interno, 1:1
        BCF     STATUS,5
        BCF     STATUS,6    ;PASO A BANCO 0
        MOVLW   0x07             ; Configuro Comparador Analogico
        MOVWF   CMCON          ; V1in-=GND, V1in+=GND, C1out=Off| V2in-=GND, V2in+=GND, C2out=Off
        BSF     INTCON,GIE
        BSF     INTCON,RBIE
;PROGRAMA
        CLRF    PORTB
        CLRF    PORTA   ;Desactivo todos los displays y sensores, botones.
        CLRF    UNIDAD
        CLRF    DECENA
        CLRF    CENTENA
        CLRF    MILLAR
;
;RUTINA DE ACTIVACION DE DISPLAY
RAD
        MOVLW   D'20'   ;Cargo contador de repeticiones display
        MOVWF   CONTADOR
REFRESCO
        MOVF    UNIDAD,0        ;Obtengo código 7 seg para unidad
        CALL    BCD7SEG
        BCF     PORTA,MUESTROM  ;Apago display MILLAR
        MOVWF   PORTB           ;Cargo unidad en PORTB
        BSF     PORTA,MUESTROU  ;Enciendo display unidad.
        CALL    DEMORA5MS
        MOVF    DECENA,0        ;Obtengo código 7 seg para decena
        CALL    BCD7SEG
        BCF     PORTA,MUESTROU  ;apago display unidad
        MOVWF   PORTB           ;cargo decena en portb
        BSF     PORTA,MUESTROD  ;Enciendo display decena
        CALL    DEMORA5MS
        MOVF    CENTENA,0       ;Obtengo código 7 seg para centena
        CALL    BCD7SEG
        BCF     PORTA,MUESTROD    ;APAGO DISPLAY DECENA
        MOVWF   PORTB           ;Cargo centena en portB
        BSF     PORTA,MUESTROC  ;Enciendo display Centena
        CALL    DEMORA5MS
        MOVF    MILLAR,0        ;Obtengo código 7 seg para centena
        CALL    BCD7SEG
        BCF     PORTA,MUESTROC  ;Apago display centena
        MOVWF   PORTB           ;Cargo millar en portB
        BSF     PORTA,MUESTROM  ;Enciendo display Millar
        CALL    DEMORA5MS
        DECFSZ  CONTADOR,1      ;¿Se repitió 20 veces?
        GOTO    REFRESCO
        GOTO    RAD             ;queda constantemente mostrando display hasta que llega interrupcion.
BCD7SEG                      ; retlw b'gfedcba'  para display catodo comun
        ADDWF   PCL,1   ; Se incrementa el contador del programa.-
        DT 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0xFF, 0x6F
;
;DEMORA 5mS
DEMORA5MS
        MOVLW   0XFF
        MOVWF   CONTADOR1
REPETICION1
        MOVLW   0X05
        MOVWF   CONTADOR2
REPETICION2
        DECFSZ  CONTADOR2,1
        GOTO    REPETICION2
        DECFSZ  CONTADOR1,1
        GOTO    REPETICION1
        RETURN
;INTERRUPCION
INTEXT
        MOVWF   W_TEMP ; Copiamos W a un registro Temporario.-
        SWAPF   STATUS, W   ;Invertimos los nibles del registro STATUS.-
        MOVWF   STATUS_TEMP ; Guardamos STATUS en un registro temporal.-
        CALL    ANTIRE
ESPERA  BTFSC   PORTB,7     ;¿Sigue pasando POR EL SENSOR?
        GOTO    ESPERA          ;sigue pasando SENSOR ¡SI SE QUEDA COLGADO, SE DETIENE EL DISPLAY!
        BTFSS   PORTA,CUENTA        ;NO ¿CUENTA O DESCUENTA?
        GOTO    DESCUENTA           ;NO ESTA APRETADO, DESCUENTA.
        ;CALL    ANTIRE        ;CUENTA ANTIRREBOTE EMPIEZA RUTINA DE CUENTA ¡¡tal vez se saque esto!!
        INCF    UNIDAD,1    ;Icremento unidad
        MOVLW   D'10'       ;cargo 10 para resetear unidad si llega a 10
        SUBWF   UNIDAD,0
        BTFSS   STATUS,Z
        GOTO    FININT         ;NO ES 10, muestro unidad
        CLRF    UNIDAD      ;Si reseteo
        INCF    DECENA,1    ;Incremento decena
        MOVLW   D'10'       ;cargo 10 para resetar decena si llega a 10
        SUBWF   DECENA,0
        BTFSS   STATUS,Z
        GOTO    FININT
        CLRF    DECENA      ;Reseteo
        INCF    CENTENA,1   ;Incremento Centena
        MOVLW   D'10'       ;cargo 10 para resetar si llega a 10
        SUBWF   CENTENA,0
        BTFSS   STATUS,Z
        GOTO    FININT
        CLRF    CENTENA     ;Reseteo
        INCF    MILLAR,1    ;Incremento Millar
        MOVLW   D'10'       ;Cargo 10 para resetar si Millar llega a 10
        SUBWF   MILLAR,0
        BTFSS   STATUS,Z
        GOTO    FININT
        CLRF    MILLAR      ;RESETEO
        GOTO    FININT
DESCUENTA
ESPERA2 BTFSC   PORTB,7     ;¿Sigue pasando POR EL SENSOR?
        GOTO    ESPERA2          ;sigue pasando SENSOR ¡SI SE QUEDA COLGADO SE DETIENE EL DISPLAY!
        MOVLW   D'0'            ;Comienzo de rutina de NO RESTAR SI TODO ES 0
        SUBWF   MILLAR,0
        BTFSS   STATUS,Z
        GOTO    RESTA
        MOVLW   D'0'
        SUBWF   CENTENA,0
        BTFSS   STATUS,Z
        GOTO    RESTA
        MOVLW   D'0'
        SUBWF   DECENA,0
        BTFSS   STATUS,Z
        GOTO    RESTA
        MOVLW   D'0'
        SUBWF   UNIDAD,0
        BTFSS   STATUS,Z
        GOTO    RESTA
        GOTO    FININT       ; Es todo 0, no resta.
RESTA   DECF    UNIDAD,1    ;
        MOVLW   0XFF
        SUBWF   UNIDAD,0      ;¿LE RESTO 1 A 0?
        BTFSS   STATUS,Z
        GOTO    FININT         ;NO, ACTUALIZA DISPLAY
        MOVLW   0X09        ;SI, RESETEA UNIDAD
        MOVWF   UNIDAD
        DECF    DECENA,1
        MOVLW   0XFF
        SUBWF   DECENA,0
        BTFSS   STATUS,Z    ;¿LE RESTE 1 A 0?
        GOTO    FININT         ;NO, ACTUALIZA DISPLAY
        MOVLW   0X09        ;SI, RESETEA DECENA
        MOVWF   DECENA
        DECF    CENTENA,1
        MOVLW   0XFF
        SUBWF   CENTENA,0
        BTFSS   STATUS,Z    ;¿LE RESTE 1 A 0?
        GOTO    FININT         ;NO, ACTUALIZO DISPLAY
        MOVLW   0X09
        MOVWF   CENTENA     ;RESETEO CENTENA
        DECF    MILLAR,1
        BTFSS   STATUS,Z    ;¿MILLAR VALE 0?
        GOTO    FININT         ;NO, ACTUALIZO DISPLAY
        MOVLW   0X00
        MOVWF   MILLAR      ;PONGO EN CERO MILLAR
        GOTO    FININT         ;SI, actualizo display.
FININT  BCF     INTCON,RBIF
        SWAPF   STATUS_TEMP,W   ; Invertimos lo nibles de STATUS_Temp.-
        MOVWF   STATUS
        SWAPF   W_TEMP,1   ; Invertimos los nibles y lo guardamos en el mismo registro.-
        SWAPF   W_TEMP,W   ; Invertimos los nibles nuevamente y lo guardamos en W.-
        RETFIE
;
;antirrebote
;
ANTIRE  MOVLW   0XFF            ;Carga contador
        MOVWF   CONTADOR3       ;Inicia contador 3
REP1    MOVLW   0XFF
        MOVWF   CONTADOR4       ;Inicia contador 4
REP2    DECFSZ  CONTADOR4,1     ;decrementa contador 4 hasta que vale 0
        GOTO    REP2            ;vuelve a decrementar.
        DECFSZ  CONTADOR3,1     ;decrementa con3 y vuelve a cargar cont2
        GOTO    REP1            ;cuando termina de decremtar 1 sale del ciclo
        RETURN
        END

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: no logro hacer andar multiplex display en 16f627A ¡ayuda por favor!
« Respuesta #1 en: 28 de Mayo de 2013, 23:46:22 »
Hola,

me gustaría sugerirte varias cosas, pero voy a enfocarme en las dos más importantes.

Primero: El guardado de los registros W y STATUS, dentro de la interrupción, debería hacerse ni bien se ingresa al vector de interrupción y restaurarse justo antes de salir. Así como lo estás haciendo, podés tener problemas, además de que de agregar otras interrupciones, vas a tener el código de guardado y restaurado repetido en cada interrupción si continuás poniendolos allí en cada interrupción. Algo MUY importante, es que los registros W_TEMP, STATUS_TEMP, etc. DEBEN asignarse a posiciones de memoria dentro del rango [0x70~0x7F] debido a que dicho rango es especial, ya que se encuentra compartido entre todos los bancos. Si bien pareciese que no es relevante, te invito a que te fijes lo que sucediese si lo dejás así, y por algún motivo al momento de producirse la interrupción, el banco actual de trabajo fuese el 1. Se guardarían en las posiciones 0xA5 y 0xA6 en lugar de las 0x25 y 0x26.

Segundo: Los simuladores suelen discrepar con el hardware real. Si bien no analice en profundidad el código, veo la ausencia de algo imprescindible para lograr salir de una interrupción por cambio del puertob, que es realizar una lectura sobre el mísmo para que el registro comparador interno (que es el que se usa para comparar el valor actual del puerto y detectar un cambio) se actualice y no siga interrumpiendo eternamente. Hacer un MOVF PORTB,F luego de la etiqueta INTEXT debería bastar.  Recuerda sacar el guardado y restaurado de W y STATUS donde te recomiendo, caso contrario el MOVF PORTB,F te va a afectar el valor real del flag STATUS,Z.

Saludos.

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado bluesboy

  • PIC12
  • **
  • Mensajes: 89
Re: no logro hacer andar multiplex display en 16f627A ¡ayuda por favor!
« Respuesta #2 en: 31 de Mayo de 2013, 12:58:13 »
Gracias BrunoF, no sabía lo de las interrupciones, ya me estoy guardando la info.

El equipo no funcionaba porque estaba usado transistores mosfet para el multiplexado y estos tienen una capacidad en el gate que alenta el tiempo de respuesta.
Lo solucione poniendo 4 BC337.

Muchas gracias. :-/