Autor Tema: TMR0 como contador, no logro contar los desbordes producidos  (Leído 736 veces)

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

Desconectado DBCooper

  • PIC10
  • *
  • Mensajes: 2
TMR0 como contador, no logro contar los desbordes producidos
« en: 03 de Marzo de 2023, 02:11:31 »
Hola que tal banda, soy un novato en la materia, estoy haciendo una practica para la uni, que trata de realizar un frecuencímetro, se nos pide usar TMR0 como contador para entrada de pulsos externos e interrupciones para hacer un contador de 0 a 999 con 3 displays multiplexados, el problema que tengo es que nose como hacerle para saber cada vez que se genere un overflow, es decir cada vez que en la salida de los 7 segmentos me marquen 256 o más, se le sume la rutina que tengo hecha para sumar 256, pero no logro hacerlo, se pone a 001,002 de nuevo y no logro hacer visualizar el valor correcto, les adjunto el codigo a ver si me pueden echar la mano, he investigado por todo el foro y todo la ethernet pero no he logrado conseguir nada que me ayude

Código: [Seleccionar]
;PROGRAMA: FRECUENCIMETRO, UTILIZANDO PIC16F877 Y DISPLAYS MULTIPLEXADOS


LIST P=16F877
INCLUDE<P16F877.INC>
ERRORLEVEL -302
__CONFIG _HS_OSC & _WDT_OFF & _LVP_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _PWRTE_ON & _DEBUG_OFF & _WRT_OFF

CBLOCK 20H
W_TEMPORAL, STATUS_TEMPORAL, CONT_DESBORDE_1, DESBORDE, CONTADOR, DESBORDES
ENDC

ORG 00H
GOTO INICIO
           
ORG 04H
GOTO INTERRUPCION


INICIO       
BSF STATUS,RP0
    BCF  STATUS,RP1      ; ACCEDO AL BANCO 1
MOVLW B'00000110'
MOVWF ADCON1
MOVLW B'00111111'
MOVWF TRISA
MOVLW B'11111110'   
    MOVWF TRISB
MOVLW B'11111111'
MOVWF TRISC
MOVLW B'10000000'
MOVWF TRISD
MOVLW B'00000111'
MOVWF TRISE


;==================== CONFIGURACION DEL TIMER0 ======================================
MOVLW B'11101000' ; CONFIGURANDO TIMER0 ASIGNANDO PRE ESCALADOR AL WDT PARA QUE PRE ESCALADOR SEA 1:1, IMPULSOS PROVENIENTES DEL PIN RA4 (COMO CONTADOR), INCREMENTO EN CADA FLANCO ASCENDENTE
MOVWF OPTION_REG
    BCF     STATUS,RP0      ; VUELVO AL BANCO 0
    BCF     PORTB,0   
    MOVLW   0FFH           
    MOVWF   TMR0
    MOVLW   b'10100000'     ; Habilitamos GIE y T0IE (interrupción del TMR0) Y TAMBIEN LIMPIO BANDERA SENALIZADORA DE DESBORDE TMR0
    MOVWF   INTCON



;==================== FIN CONFIGURACION DEL TIMER0 ======================================
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE

MOVLW .256
MOVWF CONT_DESBORDE_1
MOVLW .2
MOVWF DESBORDES

GOTO PROGRAMA_PRINCIPAL

 
;==================== RUTINA PARA ATENDER LA INTERRUPCION ===============================
 
INTERRUPCION
BCF INTCON,GIE
MOVWF   W_TEMPORAL  ; Copiamos W a un registro Temporario.-
SWAPF   STATUS_TEMPORAL,W       ;Invertimos los nibles del registro STATUS.-
MOVWF   STATUS_TEMPORAL  ; Guardamos STATUS en un registro temporal.-

;======== Interrupcion por TMR0 ==============
BTFSS INTCON,T0IF     ; Consultamos si es por TMR0
GOTO FIN_INTERRUPCION

;========== RUTINA PARA EL BLOQUE DE LA INTERRUPCION =====================
CALL RETARDO_1S
COMPARACION_1
BCF INTCON,T0IF     ; Borro bandera de control de Interrupcion.-
MOVF TMR0,W
SUBWF CONT_DESBORDE_1,W ; F = 256-TMR0
BTFSS STATUS,Z ; Z = 1 ES IGUAL A 256?
GOTO DESBORDE_0
GOTO DESBORDE_1

DESBORDE_0
MOVF TMR0,W
CALL BIN_BCD_8_BIT
CALL SUMAR_0
CALL MULTIPLEXACION
GOTO ACTUALIZO_TMR0

DESBORDE_1
MOVF TMR0,W
CALL BIN_BCD_8_BIT
CALL SUMAR_256
CALL MULTIPLEXACION


GOTO ACTUALIZO_TMR0[/color]

ACTUALIZO_TMR0
BCF INTCON,T0IF     ; Borro bandera de control de Interrupcion.-
CLRF TMR0
    MOVLW   0FFH           
    MOVWF   TMR0
MOVLW .256
MOVWF CONT_DESBORDE_1
GOTO FIN_INTERRUPCION         ; Restauro valores.- 

MULTIPLEXACION                              ; CON ESTA RUTINA LOGRAMOS REFLEJAR EL VALOR DEL CONTEO EN LOS DISPLAYS, PARA ESTO SE HACE UN LLAMADO A SUBRUTINA TABLA.
MOVF UNIDAD,W                        ; SE PASA EL VALOR DE UNIDAD A W           
MOVWF PORTD                    ; SE MUESTRA EL VALOR SELECCIONADO EN LA TABLA EN EL PUERTO D
    BSF PORTD,4                  ;
    CALL RETARDO_50MS   
BCF PORTD,4         

MOVF DECENA,W ; SE MUEVE EL VALOR DE DECENA AL REGISTRO W
    MOVWF PORTD                    ; LO MUESTRA EN EL PUERTO D
    BSF PORTD,5                 
    CALL RETARDO_50MS
BCF PORTD,5
             
MOVF CENTENA,W ; SE MUEVE EL VALOR DE CENTENA A W
    MOVWF PORTD                        ; SE MUESTRA EN EL PUERTO D
    BSF PORTD,6                      ; SE ENCIENDE EL BIT 5 PARA QUE PUEDA REFLEJARSE EL VALOR EN EL DISPLAY
    CALL RETARDO_50MS 
BCF PORTD,6 

RETURN
                   

;============ FINALIZA LA INTERRUPCION Y SE RESTAURAN LOS VALORES ===============

FIN_INTERRUPCION
SWAPF   STATUS_TEMPORAL,W   ; Invertimos lo nibles de STATUS_Temp.-
MOVWF   STATUS
SWAPF   W_TEMPORAL,F       ; Invertimos los nibles y lo guardamos en el mismo registro.-
SWAPF   W_TEMPORAL,W       ; Invertimos los nibles nuevamente y lo guardamos en W.-
BSF INTCON,GIE
  RETFIE                  ; Salimos de interrupción.-

;============ PROGRAMA PRINCIPAL ===============

PROGRAMA_PRINCIPAL


GOTO PROGRAMA_PRINCIPAL


INCLUDE<RETARDOS_20MHZ.INC>
INCLUDE<BIN_BCD_ASCII_8_10_16_BIT.INC>
 
        END



Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 965
Re:TMR0 como contador, no logro contar los desbordes producidos
« Respuesta #1 en: 03 de Marzo de 2023, 09:26:02 »
... el problema que tengo es que nose como hacerle para saber cada vez que se genere un overflow, es decir cada vez que en la salida de los 7 segmentos me marquen 256 o más, se le sume la rutina que tengo hecha para sumar 256, pero no logro hacerlo, se pone a 001,002 de nuevo ....
Cuando hacés:
Código: [Seleccionar]
MOVLW .256
MOVWF CONT_DESBORDE_1
estás cargando 0 en CONT_DESBORDE_1 , pues .256 son 9 bits
--> para TMR0 > 0 te sale desborde.

Te sugiero generar otra interrupción por overflow de TMR0 y ahí incrementar el byte superior , ya que para contar hasta 1000 necesitas 10bits.

Desconectado DBCooper

  • PIC10
  • *
  • Mensajes: 2
Re:TMR0 como contador, no logro contar los desbordes producidos
« Respuesta #2 en: 03 de Marzo de 2023, 10:09:01 »
... el problema que tengo es que nose como hacerle para saber cada vez que se genere un overflow, es decir cada vez que en la salida de los 7 segmentos me marquen 256 o más, se le sume la rutina que tengo hecha para sumar 256, pero no logro hacerlo, se pone a 001,002 de nuevo ....
Cuando hacés:
Código: [Seleccionar]
MOVLW .256
MOVWF CONT_DESBORDE_1
estás cargando 0 en CONT_DESBORDE_1 , pues .256 son 9 bits
--> para TMR0 > 0 te sale desborde.

Te sugiero generar otra interrupción por overflow de TMR0 y ahí incrementar el byte superior , ya que para contar hasta 1000 necesitas 10bits.

Gracias por tu respuesta, si entiendo que son 9 bits, pero es para que cuando sea 256 se meta en la rutina de sumar_256 y me muestre ese valor en los displays, como generaria esa otra interrupcion que me mencionas? no la tengo muy clara :?:

Desconectado Eduardo2

  • PIC24F
  • *****
  • Mensajes: 965
Re:TMR0 como contador, no logro contar los desbordes producidos
« Respuesta #3 en: 03 de Marzo de 2023, 12:15:56 »
Releyendo tu código veo otras cosas que no se deben hacer de esa forma, una interrupción no se debe usar como una subrutina mas, debe ejecutar las tareas lo mas rápido posible y retornar, nada de andarle metiendo retardos de 1s (ni 1ms)

Esto deberías hacerlo usando los 3 timers, Timer0 para conteo, Timer1 para el tiempo de conteo y Timer2 para el multiplexado.
Lamentablemente es engorroso, pero cualquier programa full en assembler (encima RISC) , salvo que sea muy simple, se vuelve engorroso.