Autor Tema: Encendido de leds y uso de subrutina  (Leído 2675 veces)

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

Desconectado danelect23

  • PIC10
  • *
  • Mensajes: 4
Encendido de leds y uso de subrutina
« en: 05 de Septiembre de 2013, 23:44:44 »
Hola, Primero que nada me presento, soy Daniel, nuevo en el foro y estoy empezando con este tema de los pics.
  Estoy trabajando con un pic16f84a, conecte un led en la pata RA0 y otro en RA1, un pulsador NA en RB0
 Lo que quiero hacer es que RA0 destelle, pero al mantener activado el pulsador conectado en RB0 (configurado como entrada), que destelle el pulsador conectado en RA1. Logre hacer esto, pero quiero que al soltar el pulsador se apage RA1 y vuelva a destellar RA0. El que armé, al soltar el pulsador, sigue destellando RA1. Es decir no vuelve ala rutina inicial.
   La idea ademas es aprender a usar un poco mas gosub y goto.

Uno de los programas que probe es el siguiente
  pense que usando GOSUB O GOTO iba a lograr hacer lo que quiero, pero probe de varias formas y la verdad no se como se usan. Desde ya muchas gracias

   TRISA=%00000
 TRISB=%11111111
 porta=0
 portb=0

Led  var porta.0
led2 var porta.1

Run1:                
High led                        
Pause 1000                      
Low led                    
Pause 1000    
if portb.0=0  then gosub run2
High led                        
Pause 1000
goto run1

run2:
high led2
pause 100
low led2
pause 100
high led2
pause 100
low led2
pause 100
goto run2
return             `no me queda claro donde colocar return, y si goto run2 esta bien ahi o no.
End                
« Última modificación: 06 de Septiembre de 2013, 10:41:40 por dogflu66 »

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Encendido de leds y uso de subrutina
« Respuesta #1 en: 06 de Septiembre de 2013, 11:16:36 »
Este código debería de hacer lo que quieres y es muy recomendable que evites usar los Gotos, a la larga es mejor.
El Goto solo se usa una sola vez para generar el bucle infinito en la subrutina principal main.
Es conveniente trabajar siempre desde una subrutina principal, a mi me gusta llamarla main.

TRISA = %00000
TRISB = %11111111
PORTA = 0
PORTB = 0

Symbol led = PORTA.0  'Asigna nombre al disositivo en Basic del PSI
Symbol led2 = PORTA.1

main:  'Subrutina principal
   Gosub run1  'Salta a la subrutina run1 y vuelve

   'Bucle tipo While/Wend
   While PORTB.0 = 0  'Si RB0=0 ejecuta el código que hay entre While y Wend.
      Gosub run2  'Salta a run2 y vuelve
   Wend  'Mientras RB0=0 retorna al While inmediato superior.

Goto main  'Genera bucle infinito, solo para rutina principal.
End                                               
'Subrutinas
run1:  'Nombre o etiqueta subrutina
   High led  'Cambia el estado del pin configrado como digital
   WaitMs 1000  'Hace una pausa de los mSeg. especificados en el Basic del PSI
   Low led
   WaitMs 1000
Return  'Fin subrutina run1, retorna a la línea siguiente despues del salto
run2:  'Nombre o etiqueta subrutina
   High led2
   WaitMs 100
   Low led2
   WaitMs 100
Return  'Fin subrutina run2,  retorna a la línea siguiente despues del salto
Saludos desde Granada, España.

Desconectado danelect23

  • PIC10
  • *
  • Mensajes: 4
Re: Encendido de leds y uso de subrutina
« Respuesta #2 en: 08 de Septiembre de 2013, 22:40:04 »
Muchas gracias, compilado el error que me tiro fue en "WaitMs", los cambie todos por "pause", y no marco más error. lo cargué al pic y anda de diez.
  una consulta..los gosub siempre deben ir asociados a un return?
en  este caso "Gosub run1" va asociado al return de la subrutina run 1 y el "Gosub run2" al return de la subrutina run 2?
  Habra forma que al pulsar el pulsador de RB0 la salida responda más rápidamente (vendria a ser la respuesta del pic, que sea mas rapida)? por que tarda un poco, en relación a lo que tarda el reset (si pongo la pata reset a masa, no tarda casi nada en reiniciarse)


Symbol led = PORTA.0  'Asigna nombre al disositivo en Basic del PSI
Symbol led2 = PORTA.1

main:                'Subrutina principal
               'Salta a la subrutina run1 y vuelve

                    'Bucle tipo While/Wend
    While PORTB.0 = 0   'Si RB0=0 ejecuta el código que hay entre While y Wend.
    Gosub run2          'Salta a run2 y vuelve
    Wend                'Mientras RB0=0 retorna al While inmediato superior.

    Goto main           'Genera bucle infinito, solo para rutina principal.
    End                                               
                    'Subrutinas
                   
run1:               'Nombre o etiqueta subrutina
   High led         'Cambia el estado del pin configrado como digital
   pause 1000       'Hace una pausa de los mSeg. especificados en el Basic del PSI
   Low led
   pause 1000
   return           'Fin subrutina run1, retorna a la línea siguiente despues del salto
run2:               'Nombre o etiqueta subrutina
   High led2
   pause 100
   Low led2
   pause 100
   return          'Fin subrutina run2,  retorna a la línea siguiente despues del salto
« Última modificación: 08 de Septiembre de 2013, 23:37:22 por danelect23 »

Desconectado danelect23

  • PIC10
  • *
  • Mensajes: 4
Re: Encendido de leds y uso de subrutina
« Respuesta #3 en: 09 de Septiembre de 2013, 15:51:57 »
hola, el tutorial que decis es en ensamblador no? Por ahora me voy a quedar con PBP, de a poco voy a aprender ensamblador, que me parece bastante mas complejo. Gracias
« Última modificación: 09 de Septiembre de 2013, 15:57:16 por danelect23 »

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Encendido de leds y uso de subrutina
« Respuesta #4 en: 09 de Septiembre de 2013, 18:40:06 »
Cada Gosub tiene su Return; Return marca el final de la subrutina y Gosub si necesita un argumento que es un nombre o etiqueta donde debe saltar.
Saludos desde Granada, España.

Desconectado dogflu66

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3510
Re: Encendido de leds y uso de subrutina
« Respuesta #5 en: 10 de Septiembre de 2013, 08:56:14 »
Para dar agilidad a los periféricos y al programa en general hay que dejar de utilizar los Pause, en mi caso Waitms. De echo pasa lo mismo que con el Goto, no se utilizan.

Código: [Seleccionar]
'Practicas para la introducción a las bases de tiempos (sin usar las interrupciones).
'Ejemplo para simulador
Define CLOCK_FREQUENCY = 4  'Se trabaja a 4Mhz
AllDigital  'Puerto A se utilizara como digital
TRISB.0 = 1  'Input
TRISA.0 = 0  'Output
TRISA.1 = 0  'Output

Symbol led = PORTA.0  'Asigna nombre al disositivo en Basic del PSI
Symbol led2 = PORTA.1

Call _btreset()

main:  'Subrutina principal

'Control tecla y parpadeo led2
If RB0 = 0 Then Gosub run2  'Salta a la subrutina
If RB0 = 1 Then led2 = 0  'Apaga led contrario

'Control tecla y parpadeo led
If RB0 = 1 Then Gosub run1  'Salta a la subrutina
If RB0 = 0 Then led = 0  'Apaga led contrario

Call _btcall()  'Actualiza las bases de tiempos
Goto main  'Genera bucle infinito, solo para rutina principal.
End                                              
'Subrutinas
run1:  'Nombre o etiqueta subrutina
If _btimer.1 = 1 Then
Call _btsetup(1, 1000)
Toggle led  'Invierte el estado del pin configrado como digital
Endif
Return  'Fin subrutina run1, retorna a la línea siguiente despues del salto
run2:  'Nombre o etiqueta subrutina
If _btimer.0 = 1 Then
Call _btsetup(0, 100)
Toggle led2
Endif
Return  'Fin subrutina run2,  retorna a la línea siguiente despues del salto
'**********************************************************
'Funciones para el control de hasta 8 bases de tiempos: _btimer.0 a _btimer.7
'**********************************************************
'Función principal las bases de tiempos:
'_bt = indica la base de tiempos para configurar
'_waitms = tiempo que contará la base de tiempos seleccionada con _bt
'_setup = operación a realizar con la base de tiempos indicada por _bt
Function _btimer(_bt As Byte, _waitms As Word, _setup As Byte) As Byte
Dim _cont(7) As Word  'Numero de contadores, tantos como bases de tiempos

If _setup = 1 Then _btimer = 255  'Configura las bases de tiempos como terminadas o desbordadas
''Recarga las bases de tiempos con el tiempo a contar y las activa
If _setup = 2 Then
If _bt = 0 Then
_cont(0) = _waitms
_btimer.0 = 0
Endif
If _bt = 1 Then
_cont(1) = _waitms
_btimer.1 = 0
Endif
If _bt = 2 Then
_cont(2) = _waitms
_btimer.2 = 0
Endif
If _bt = 3 Then
_cont(3) = _waitms
_btimer.3 = 0
Endif
Endif

If _setup = 0 Then
'Contadores de las bases de tiempos, descontando
If _cont(0) > 0 Then _cont(0) = _cont(0) - 1
If _cont(1) > 0 Then _cont(1) = _cont(1) - 1
If _cont(2) > 0 Then _cont(2) = _cont(2) - 1
If _cont(3) > 0 Then _cont(3) = _cont(3) - 1

'Estado de las bases de tiempos, terminaron de contar
If _cont(0) = 0 Then _btimer.0 = 1
If _cont(1) = 0 Then _btimer.1 = 1
If _cont(2) = 0 Then _btimer.2 = 1
If _cont(3) = 0 Then _btimer.3 = 1

WaitMs 1  'Tiempo patron
Endif

End Function                                      
'Funciones auxiliares para el control de las bases de tiempos:
'********************************************************
'Actualiza las bases de tiempos.
Proc _btcall()
Call _btimer(0, 0, 0)
End Proc                                          
'Recarga las bases de tiempos.
Proc _btsetup(_bt As Byte, _waitms As Word)
Call _btimer(_bt, _waitms, 2)
End Proc                                          
'Inicializa las bases de tiempos, todas desbordadas.
Proc _btreset()
Call _btimer(0, 0, 1)
End Proc                          
« Última modificación: 26 de Septiembre de 2013, 13:49:53 por dogflu66 »
Saludos desde Granada, España.

Desconectado danelect23

  • PIC10
  • *
  • Mensajes: 4
Re: Encendido de leds y uso de subrutina
« Respuesta #6 en: 10 de Septiembre de 2013, 20:54:25 »
 bueno, voy a seguir investigando y armando circuitos. Un millón de gracias por la ayuda que me diste.  ((:-))


 

anything