Autor Tema: cronometro con boton pausa y continua  (Leído 3909 veces)

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

Desconectado akilez69

  • PIC10
  • *
  • Mensajes: 10
cronometro con boton pausa y continua
« en: 21 de Noviembre de 2007, 12:49:18 »
Hola que tal a todos los integrantes de este maravilloso foro, mi inquietud es la siguiente y espero de me puedan ayudar: el cronometro que se muestra abajo cuenta con un botón de reset (RB0) y botón de pausa y continuación de cuenta (RB1), el detalle es que no consigo hacer que este botón (RB1) que detiene la cuenta haga regresar a la cuenta al cronometro  :?  , lo del reset si funciona :)  .
Lo que debe suceder es que cuando el RB1 (pulsador) se pone a un uno lógico se va a la rutina pausa y si es cero lógico pos que siga la cuenta; y si después de estar en pausa, otra vez se presiona el RB1 colocándose a un uno lógico el cronometro debe volver a la cuenta (cosa que no sucede). Dentro de la rutina pausa intente testear el RB1 nuevamente pero me di cuenta después que hay un tipo de conflicto entre el testear el RB1 que lleva a la subrutina pausa y el RB1 que esta dentro de esta subrutina, es por eso que lo puse comentario como lo podrán observar, esta en las ultimas lineas del programa.
Espero me hayan entendido, y puedan guiarme en la solución de este problemita. 
Gracias
saludos coordiales  :)


list p=16f877A ; list directive to define processor
#include <p16f877A.inc> ; processor specific variable definitions
#INCLUDE <Macros.inc>

__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF


errorlevel -302
gg EQU 0X75
ff EQU 0X74
ee EQU 0X73
dd EQU 0X72
cc EQU 0X71
bb EQU 0X70
aa EQU 0X69
w_temp EQU 0x68 ; variable used for context saving
status_temp EQU 0x67 ; variable used for context saving
pclath_temp EQU 0x66 ; variable used for context saving
numero EQU 0x65
temporal EQU 0x64

ORG 0X000
nop ; nop required for icd
goto main ; go to beginning of program


ORG 0X004 ; interrupt vector location

movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into w register
movwf pclath_temp ; save off contents of PCLATH register

goto RutInterrupcion

SalirInterrupcion

movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt

main
Banco1
movlw b'00000011'
movwf TRISB
clrf TRISD
Banco0
bsf INTCON,GIE
bsf INTCON,INTE

Inicio:
CALL Inicio_LCD
movlw 'C'
call EnviaCarLCD
movlw 'R'
call EnviaCarLCD
movlw 'O'
call EnviaCarLCD
movlw 'N'
call EnviaCarLCD
movlw 'O'
call EnviaCarLCD
;RESET
clrf gg ; Inicializa todos los datos del reloj.
clrf ff
clrf ee
clrf dd
clrf cc
clrf bb
clrf aa


g:
call muestra
btfsc PORTB,1 ;testeando RB1
call pausa
;play
incf gg,f
movf gg,w
sublw d'9'
btfsc STATUS,C
goto g
goto f

f: movlw d'0'
movwf gg
incf ff,f
movf ff,w
sublw d'9'
btfsc STATUS,C
goto g
goto e

e: movlw d'0'
movwf ff
incf ee,f
movf ee,w
sublw d'9'
btfsc STATUS,C
goto g
goto d

d: movlw d'0'
movwf ee
incf dd,f
movf dd,w
sublw d'9'

btfsc STATUS,C
goto g
goto c

c: movlw d'0'
movwf dd
incf cc,f
movf cc,w
sublw d'5'
btfsc STATUS,C
goto g
goto b1

b1: movlw d'0'
movwf cc
incf bb,f
movf bb,w
sublw d'9'
btfsc STATUS,C
goto g
goto a

a: movlw d'0'
movwf bb
incf aa,f
movf aa,w
sublw d'5'
btfsc STATUS,C
goto g
goto Inicio

muestra:
movf DISP_CLEAR,w
call EnviaCmdLCD

movlw DISP_LINEA2 ;
call EnviaCmdLCD

movlw ' '
call EnviaCarLCD
movlw ' '
call EnviaCarLCD
movlw ' '
call EnviaCarLCD
movlw ' '
call EnviaCarLCD
movf aa,w
addlw 0x30 ;para pasar a ASCII
call EnviaCarLCD ;n
movf bb,w
addlw 0x30 ;para pasar a ASCII
call EnviaCarLCD ;n

movlw ':'
call EnviaCarLCD

movf cc,w
addlw 0x30 ;para pasar a ASCII
call EnviaCarLCD ;n
movf dd,w
addlw 0x30 ;para pasar a ASCII
call EnviaCarLCD ;n

movlw ':'
call EnviaCarLCD
movf ee,w
addlw 0x30 ;para pasar a ASCII
call EnviaCarLCD ;n
movf ff,w
addlw 0x30 ;para pasar a ASCII
call EnviaCarLCD ;n
movf gg,w
addlw 0x30 ;para pasar a ASCII
call EnviaCarLCD ;n

return

RutInterrupcion
btfsc PORTB,0
goto IntExter
goto SalirInterrupcion
IntExter
clrf gg ; Inicializa todos los datos del reloj.
clrf ff
clrf ee
clrf dd
clrf cc
clrf bb
clrf aa
goto SalirintExter

SalirintExter
bcf INTCON,INTF
goto SalirInterrupcion
pausa
call muestra
; btfss PORTB,1
goto pausa
; goto play
return

INCLUDE "ModuloLCD.asm"
INCLUDE "ModuloDELAY10M.asm"
end

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: cronometro con boton pausa y continua
« Respuesta #1 en: 21 de Noviembre de 2007, 16:40:35 »
Hola.¿Lo modificaste vos a este codigo? ¿Es tuyo?
Hacer un goto al loop principal desde una subrutina es un error grave porque se sobrecarga el stack en esta familia de micros y no hay formas de librerarlo. El RESET es inminente a la larga.

Yo creo que poniendolo asi:

SalirintExter
bcf INTCON,INTF
goto SalirInterrupcion
pausa
call muestra
btfss PORTB,1
goto pausa

return

ya tiene que andarte. Yo le pondria una subrutina de antirebote, pero bueno a eso lo dejo a discrecion tuya.

Saludos
« Última modificación: 21 de Noviembre de 2007, 16:44:17 por BrunoF »
"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 akilez69

  • PIC10
  • *
  • Mensajes: 10
Re: cronometro con boton pausa y continua
« Respuesta #2 en: 22 de Noviembre de 2007, 01:25:31 »
Hola que tal BrunoF, muchas gracias por tu respuesta. Y si, si es mi codigo :).
En cuanto a la sobrecarga de la pila, o stack como usted lo llama, pensé q solo sucedía con los comando ‘call’ en modo anidado en un máximo de 8 veces ^o), corrígeme si me equivoco :oops:.
Bueno cuando hago la modificación que propones, efectivamente se pone en pausa y si presiono otra vez se pone en play pero no como yo espero, me explico: le pongo pausa y cuando le pongo play sigue contando pero de repente suelto el pulsador (proteus) y se pone en pausa otra vez, repito el procedimiento y ahí si continua el conteo, y recién funciona como yo quiero, y como mencionaste el antirebote, pues definitivamente le falta un antirebote.
Si no fuese mucho pedir me podrías ilustrar tu diseño de antirebote, ya que días atrás habré encontrado uno, pero no le di bola.
Ah por cierto por que me preguntaste que si lo había modificado o si era mío?, y otra vez muchas gracias por tu respuesta  :)
Saludos cordiales

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: cronometro con boton pausa y continua
« Respuesta #3 en: 22 de Noviembre de 2007, 02:06:12 »
Hola que tal BrunoF, muchas gracias por tu respuesta. Y si, si es mi codigo :).
En cuanto a la sobrecarga de la pila, o stack como usted lo llama, pensé q solo sucedía con los comando ‘call’ en modo anidado en un máximo de 8 veces ^o), corrígeme si me equivoco :oops:.

Para simplicarlo: En esta familia la escalera tiene 8 escalones. Cuando haces un call, subís un escalón. Hay 3 formas de bajarlo luego: return,retfie o un reset(baja todos). Entonces. En ningún momento podés subir más allá del escalón 8.

Esto es un ejemplo de reset por Overflow del STACK:
           org 0x00
Loop
           call SubRutina
           goto Loop

SubRutina
         nop
         goto Loop
          nop
          return


En ese ejemplo, se ejecutan calls, pero nunca un return. Cuando se llame por novena vez, el PIC producirá un RESET por desbordamiento superior del STACK.


Esto es un ejemplo de reset por Underflow del STACK:
         org 0x00
Loop
         call  SubRutina
         return                      ;Aqui underflow

SubRutina
         nop
         return

Se ejecuta un call. Se sube un escalón. Dentro de SubRutina, se produce un return. Se vuelve al escalón más bajo, pero inmediatamente se produce otro return en la linea comentada. Esto produce un RESET del micro.

Bueno cuando hago la modificación que propones, efectivamente se pone en pausa y si presiono otra vez se pone en play pero no como yo espero, me explico: le pongo pausa y cuando le pongo play sigue contando pero de repente suelto el pulsador (proteus) y se pone en pausa otra vez, repito el procedimiento y ahí si continua el conteo, y recién funciona como yo quiero, y como mencionaste el antirebote, pues definitivamente le falta un antirebote.
Si no fuese mucho pedir me podrías ilustrar tu diseño de antirebote, ya que días atrás habré encontrado uno, pero no le di bola.

Hay muchas formas de hacer un antirebote. Yo generalmente uso este programita:

http://www.todopic.com.ar/foros/index.php?topic=5968.0

Y podés usarlo así (64ms de antirebote y reacomodé todos los registros en la RAM)

CBLOCK 0x20
aa,bb,cc,dd,ee,ff,gg,
temporal,numero,
pclath_temp,status_temp,w_temp,
PDel0,PDel1
ENDC

SalirintExter
bcf INTCON,INTF
goto SalirInterrupcion
pausa
call muestra
call AntiRebote
btfss PORTB,1
goto pausa

call AntiRebote
return

AntiRebote  movlw     .89       ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .143      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel1, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  goto PDelL3         ; 2 ciclos delay
PDelL3 
        return              ; 2+2 Fin

Ah por cierto por que me preguntaste que si lo había modificado o si era mío?, y otra vez muchas gracias por tu respuesta  :)
Saludos cordiales

Te pregunte porque vi todos los comentarios en inglés y me resultó extraño.

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 akilez69

  • PIC10
  • *
  • Mensajes: 10
Re: cronometro con boton pausa y continua
« Respuesta #4 en: 22 de Noviembre de 2007, 03:39:56 »
Muchas gracias por tu respuesta BrunoF, eres una persona muy servicial. Bueno me acabo de dar cuenta que yo estaba incurriendo en el error de overflow que me mencionas,  entonces a la novena vez que pulsaba pausa y continua se iba a originar un reset.
En cuanto al programita que calcula retardos esta bravazo, viendo la dirección que dejaste, pues concluyo que no es el único programa que hace retardo y que hay para cada necesidad que se presente. Pero ahora viendo esto de retardos, pues resulta que mi cronometro no esta sincronizado, ósea que se atrasa, existe alguna subrutina que en vez de retardarlo pueda adelantarlo :lol:, o tengo que probar con valores de cristales y la ventana de stopwatch (aunque no se usarlo del todo bien).
Dime por que reacomodaste la RAM a partir de la 0x20? Si bien es cierto cuando la pones a partir de la 0x70 se copia también en los demás bancos (16F877A), o será que por que no trabajo en estos bancos para este programa, y resulta innecesario ponerlo a partir de la 0x70; es por eso?.
Ah por lo de los comentarios en ingles, pues resulta que es parte de la plantilla para el 16F877A que extraje de mplab, uso la v7.50, es por eso que se vio los comentarios en ingles.
Saludos cordiales :)

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: cronometro con boton pausa y continua
« Respuesta #5 en: 22 de Noviembre de 2007, 05:08:54 »
Muchas gracias por tu respuesta BrunoF, eres una persona muy servicial. Bueno me acabo de dar cuenta que yo estaba incurriendo en el error de overflow que me mencionas,  entonces a la novena vez que pulsaba pausa y continua se iba a originar un reset.

Las lineas que hubiesen producido el error estaban comentadas en el archivo que me pasaste. Solamente te avisaba por si soles hacerlo asi ya que te vas a agarrar la cabeza buscando el error e iba a ser ese...

En cuanto al programita que calcula retardos esta bravazo, viendo la dirección que dejaste, pues concluyo que no es el único programa que hace retardo y que hay para cada necesidad que se presente. Pero ahora viendo esto de retardos, pues resulta que mi cronometro no esta sincronizado, ósea que se atrasa, existe alguna subrutina que en vez de retardarlo pueda adelantarlo :lol:, o tengo que probar con valores de cristales y la ventana de stopwatch (aunque no se usarlo del todo bien).

Podes hacerlo haciendo uso del MPLAB SIM y su StopWatch junto a un par de BreakPoints para acelerar el proceso de medición pero es un metodo muy lento y tedioso. Inclusive puede que resulte muchas veces impreciso.

Yo te recomiendo que si tu cronómetro no requiere de extrema precisión recurras al uso de un Timer para contar intervalos de tiempo. Es lo más seguro y sencillo.

Dime por que reacomodaste la RAM a partir de la 0x20? Si bien es cierto cuando la pones a partir de la 0x70 se copia también en los demás bancos (16F877A), o será que por que no trabajo en estos bancos para este programa, y resulta innecesario ponerlo a partir de la 0x70; es por eso?.

Supuse que tu intención había sido esa. Que dichas 16 posiciones de RAM son accesibles desde cualquiera de los cuatro bancos de este PIC, y por eso las estabas utilizando. Y muy bien has hecho tu al pensar que las cambie porque considere que no era necesario ponerlas alli ya que solo trabajas con el primer banco de la FLASH del PIC.

Ah por lo de los comentarios en ingles, pues resulta que es parte de la plantilla para el 16F877A que extraje de mplab, uso la v7.50, es por eso que se vio los comentarios en ingles.
Saludos cordiales :)

Pues perfecto entonces! ;).

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 akilez69

  • PIC10
  • *
  • Mensajes: 10
Re: cronometro con boton pausa y continua
« Respuesta #6 en: 22 de Noviembre de 2007, 09:43:53 »
Gracias por tu ayuda Bruno, se ha solucionado mi inquietud y despejado mis dudas  :-/ y pues se nota que en este tema de los pics eres un capo y que no se te escapa ninguna :).
Saludos cordiales y éxitos.