elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Guía rápida para descarga de herramientas gratuitas de seguridad y desinfección


+  Foro de elhacker.net
|-+  Informática
| |-+  Electrónica
| | |-+  Dudas para crear temporizador en ensamblador
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Dudas para crear temporizador en ensamblador  (Leído 23,250 veces)
Fox_Neo

Desconectado Desconectado

Mensajes: 234



Ver Perfil
Dudas para crear temporizador en ensamblador
« en: 20 Marzo 2013, 10:15 am »

Hola quiero crear un temporizador con el PIC P16F886, de 0,5 segundos de pulso osea con una frecuencia de 1Hzy no se como programarlo , tengo la idea pero no se plasmarlo en emsalblador. Os explico:
Voy a usar el oscilador interno del PICde 4MHz lo que es lo mismo con un periodo de 0,25us si una instruccion tarda 4 ciclos de reloj, cada instrucción tarda en ejegutarse 1us.
Tengo que conseguir que oscile a 0,5s--> 500.000us para ello quiero poner el TMR0 inicialmente a 250 y el preescale a 8 con lo que el TMR0 se desborda cada 2000us  (250*8=2000). Si con un contador cuento 250 vecesda 0,5 s (2000us*250=500.000us=0.5s).
Lo que no se hacer o que no entiendo como se le da la orden de que empie a contar  otra cosa que no entiendo es que al ir comparando el valor del contador cuenta como un tiempo de instrucción por tanto ya se retrasaria, no se tengo un cacao muy grande,
se que tengo cuando se supere el desbordamiento del TMR0  cada 2000us tengo que poner el bit TI0IF del registro INTCON  mediante programa a 0.   

Aqui os dejo un diagrama de como creo que funciona:

Gracias


En línea

Meta


Desconectado Desconectado

Mensajes: 3.438



Ver Perfil WWW
Re: Dudas para crear temporizador en ensamblador
« Respuesta #1 en: 20 Marzo 2013, 14:35 pm »

Hola:

Si le interesa usar retardos, aquí hay información.

http://electronica-pic.blogspot.com.es/2012/02/retardos-para-pic12f-16f-y-18f.html

Saludo.


En línea

Fox_Neo

Desconectado Desconectado

Mensajes: 234



Ver Perfil
Re: Dudas para crear temporizador en ensamblador
« Respuesta #2 en: 20 Marzo 2013, 23:30 pm »

Gracias Meta por la ayuda, umm lo único que he sabido hacer es configurar los puertos:
Código
  1. ;***** CONFIGURACIÓN ******************************************************
  2. List p=16F886 ;Tipo de procesador
  3. include "P16F886.INC" ;Definiciones de registros internos
  4. ;Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
  5. ;adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades
  6.  
  7. __config _CONFIG1, _LVP_OFF&_PWRTE_ON&_WDT_OFF&_EC_OSC&_FCMEN_OFF ;Palabra 1 de configuración
  8. __config _CONFIG2, _WRT_OFF&_BOR40V
  9.  
  10. ; _MCLRE_ON: Reset externo ACTIVADO.
  11. ; _CP_OFF: Protección del código DESACTIVADO.
  12. ; _WDT_OFF: Watchdog DESACTIVADO.
  13. ; _IntRC_OSC: Oscilador interno de 4MHz.
  14. ;***** DEFINICIÓN DE VARIABLES
  15. ; Definimos las posiciones de memoria de los datos
  16. CONTADOR equ 0x10
  17. ;**************************************************************************
  18. ; Inicialización del programa:
  19. ; Origen
  20. Org 0x00
  21. goto Inicio ;Vector de reset
  22. org 0x05
  23. ; Configuración de los puertos como entradas y salidas
  24. Inicio clrf PORTB ; Borrado de los biestables de salida
  25. bsf STATUS,RP0 ; Selecciona banco 3 (RP0=RP1=’1’)
  26. bsf STATUS,RP1
  27. clrf ANSEL ; El puerto A de tipo digital
  28. clrf ANSELH ; El puerto B de tipo digital
  29. bcf STATUS,RP1 ; Selecciona banco 1 (RP1=’0’ RP0=’1’)
  30. clrf TRISB ; RB7:RB0 se configuran como salidas
  31. movlw b'00111111'
  32. movwf TRISA ; RA5:RA0 se configuran como entrada
  33. movlw b'00000110' ;movemos el valor de la opción del preescale  al registro W
  34. movwf OPTION_REG ;pasamos el valor de w al registro
  35. bcf STATUS,RP0 ; Se vuelve al banco 0
  36. movlw b'00000111' ;movemos el valor de la opción del preescale  al registro W
  37. movwf INTCON ;
ya más no se estoy bastante perdido :S
Gracias[/size]
En línea

Meta


Desconectado Desconectado

Mensajes: 3.438



Ver Perfil WWW
Re: Dudas para crear temporizador en ensamblador
« Respuesta #3 en: 21 Marzo 2013, 01:33 am »

Hola:

Aquí encontré un ejemplo sencillo.
Código
  1. ;El Timer 0 TMR0.
  2. ;
  3. ;Se trata de comprobar el funcionamiento básico del Timer 0. Cuando se detecta un flanco
  4. ;decendente en RA0 (conectada con un pulsador), se activa la salida RB0 durante un tiempo
  5. ;y luego se desconecta. El TMR0 realiza una temporización de 50mS que se repite tantas veces
  6. ;como se indique en la variable "Temp". Así pues la temporización total será de 50mS*Temp.
  7. ;
  8. ;Suponiendo una frecuencia de trabajo de 4MHz, 4Tosc=1uS. Trabajando con un prescaler de 256,
  9. ;al TMR0 hay que cargarlo con 195 para temporizar 50mS (Temporización=1uS*195*256)
  10.  
  11.  
  12. List p=16F886 ;Tipo de procesador
  13. include "P16F886.INC" ;Definiciones de registros internos
  14.  
  15. ;Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
  16. ;adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades
  17.  
  18. __config _CONFIG1, _LVP_OFF&_PWRTE_ON&_WDT_OFF&_EC_OSC&_FCMEN_OFF&_BOR_OFF ;Palabra 1 de configuración
  19. __config _CONFIG2, _WRT_OFF&_BOR40V ;Palabra 2 de configuración
  20.  
  21. Valor equ .20 ;Constante para temporizar 1 seg (50mS*20)
  22.  
  23. Temp equ 0x020 ;Variable para la temporización
  24.  
  25. org 0x00 ;Vector de RESET
  26. goto Inicio
  27. org 0x05
  28.  
  29. ;*********************************************************************************************
  30. ;Delay: El Timer 0 realiza un retardo de 50mS que se repite tantas veces como se indica en la
  31. ;constante valor
  32.  
  33. Delay movlw Valor
  34. movwf Temp ;Nº de veces a temporizar 50 mS
  35. Delay_1 movlw ~.195  
  36. movwf TMR0 ;Inicia el Timer 0 con 195 (195*256=49.9mS)
  37. bcf INTCON,T0IF ;Repone flag del TMR0
  38. Delay_2 btfss INTCON,T0IF ;Fin de los 50mS ??
  39. goto Delay_2 ;No, el TMR0 no ha terminado
  40. decfsz Temp,F ;Decrementa el contador. Fin de temporización ??
  41.           goto Delay_1 ;No, el TMR0 temporiza otros 50 mS
  42. return ;Si, final de la temporización
  43.  
  44. ;Programa principal
  45. Inicio clrf PORTB ;Borra los latch de salida
  46. bsf STATUS,RP0
  47. bsf STATUS,RP1 ;Selecciona banco 3
  48. clrf ANSEL ;Puerta A digital
  49. clrf ANSELH ;Puerta B digital
  50. bcf STATUS,RP1 ;Selecciona banco 1
  51. movlw b'11111110'
  52. movwf TRISB ;RB0 se configura como salida
  53. movlw b'00111111'
  54. movwf TRISA ;RA5:RA0 se configuran como entrada
  55. movlw b'00000111'
  56. movwf OPTION_REG ;TMR0 con reloj interno y preescaler de 256
  57. bcf STATUS,RP0 ;Selecciona banco 0                                                                        
  58.  
  59. ;Este es el cuerpo principal del programa. Espera a que en RA0 se detecte un flanco descendente
  60.  
  61. Loop btfsc PORTA,0     ;RA0=0 ??
  62.           goto Loop ;No, esperar
  63. bsf PORTB,0 ;Si activar RB0
  64. call Delay ;Temporizar
  65. bcf PORTB,0 ;Desactivar RB0
  66. goto Loop ;Repetir el proceso
  67.  
  68. end


Otro más por aquí.
Código
  1. ;La interrupción del TMR0.
  2. ;
  3. ;Se trata de comprobar la interrupción provocada por el TMR0. El programa
  4. ;lee el estado de los interruptores conectados a RA0 y RA1 para reflejarlo en
  5. ;los leds conectados a RB0 y RB1 respectivamente. Al mismo tiempo el TMR0
  6. ;genera una interrupción cada 0.01 seg. (10 mS) que se repetirá 50 veces con objeto
  7. ;de hacer intermitencia de 500 mS sobre el led conectado a RB3.
  8.  
  9.  
  10. List p=16F886 ;Tipo de procesador
  11. include "P16F886.INC" ;Definiciones de registros internos
  12.  
  13. ;Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
  14. ;adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades
  15.  
  16. __config _CONFIG1, _LVP_OFF&_PWRTE_ON&_WDT_OFF&_EC_OSC&_FCMEN_OFF&_BOR_OFF ;Palabra 1 de configuración
  17. __config _CONFIG2, _WRT_OFF&_BOR40V ;Palabra 2 de configuración
  18.  
  19. Contador equ 0x020 ;Variable para la temporización
  20.  
  21. org 0x00 ;Vector de RESET
  22. goto Inicio
  23. org 0x04 ;Vector de interrupción
  24. goto Interrupcion
  25. org 0x05
  26.  
  27. Interrupcion   bcf INTCON,T0IF ;Repone flag del TMR0
  28. decfsz Contador,F ;Decrementa el contador. Ha habido 50 interrupciones ??
  29.           goto Seguir ;No, no han pasado los 500 mS
  30. Con_si_0   movlw .50
  31.           movwf Contador   ;Repone el contador nuevamente para contar 50 interrupciones
  32.           movlw b'00001000'
  33. xorwf PORTB,F ;RB3 cambia de estado
  34. Seguir     movlw ~.39
  35.           movwf TMR0       ;Repone el TMR0 con 39
  36.           retfie ;Retorno de interrupción
  37.  
  38. Inicio clrf PORTB ;Borra los latch de salida
  39. bsf STATUS,RP0
  40. bsf STATUS,RP1 ;Selecciona banco 3
  41. clrf ANSEL ;Puerta A digital
  42. clrf ANSELH ;Puerta B digital
  43. bcf STATUS,RP1 ;Selecciona banco 1
  44. clrf TRISB ;RB7:RB0 se configuran como salida
  45. movlw b'00111111'
  46. movwf TRISA ;RA5:RA0 se configuran como entrada
  47. movlw b'00000111'
  48. movwf OPTION_REG ;Preescaler de 256 para el TMR0
  49. bcf STATUS,RP0 ;Selecciona banco 0                                                                        
  50.  
  51. ;El TMR0 se carga con 39. Con un preescaler de 256 y a una frecuencia de 4MHz se obtiene una interrupción
  52. ;cada 10mS. Se habilita la interrupción del TMR0.
  53.  
  54. movlw ~.39
  55. movwf TMR0 ;Carga el TMR0 con 39
  56. movlw .50
  57. movwf Contador ;Nº de veces a repetir la interrupción
  58. movlw b'10100000'
  59. movwf INTCON ;Activa la interrupción del TMR0
  60.  
  61. ;Este es el cuerpo principal del programa. Consiste en leer constantemente el estado de RA0 y RA1 para visualizar
  62. ;sobre RB0 y RB1 sin que cambie el estado actual de RB7
  63.  
  64. Loop btfsc PORTA,0     ;Testea el estado de RA0
  65.           goto RA0_ES_1
  66.           bcf PORTB,0 ;Desactiva RB0
  67.           goto TEST_RB1
  68. RA0_ES_1   bsf PORTB,0 ;Activa RB0
  69. TEST_RB1   btfsc PORTA,1     ;Testea el estado de RA1
  70.           goto RA1_ES_1
  71.           bcf PORTB,1 ;Desactiva RB1
  72.           goto Loop
  73. RA1_ES_1   bsf PORTB,1 ;Activa RB1
  74. goto Loop
  75.  
  76. end ;Fin del programa fuente
  77.  

Saludo.
En línea

Fox_Neo

Desconectado Desconectado

Mensajes: 234



Ver Perfil
Re: Dudas para crear temporizador en ensamblador
« Respuesta #4 en: 21 Marzo 2013, 16:41 pm »

Muchas garcias Meta por la ayuda creo que estoy avanzando hasta ahora llevo lo siguiente, me falta poner que cuando el contador de usuario llegue a 0 se active la salida:
Código
  1. ;**************************************************************************
  2. ;***** CONFIGURACIÓN ******************************************************
  3. List p=16F886 ;Tipo de procesador
  4. include "P16F886.INC" ;Definiciones de registros internos
  5. ;Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
  6. ;adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades
  7.  
  8. __config _CONFIG1, _LVP_OFF&_PWRTE_ON&_WDT_OFF&_EC_OSC&_FCMEN_OFF ;Palabra 1 de configuración
  9. __config _CONFIG2, _WRT_OFF&_BOR40V
  10.  
  11. ; _MCLRE_ON: Reset externo ACTIVADO.
  12. ; _CP_OFF: Protección del código DESACTIVADO.
  13. ; _WDT_OFF: Watchdog DESACTIVADO.
  14. ; _IntRC_OSC: Oscilador interno de 4MHz.
  15. ;***** DEFINICIÓN DE VARIABLES
  16. ; Definimos las posiciones de memoria de los datos
  17. CONTADOR equ 0x20
  18. ;**************************************************************************
  19. ; Inicialización del programa:
  20. ; Origen
  21. Org 0x00
  22. goto Inicio ;Vector de reset
  23. org 0x05
  24. ; Configuración de los puertos como entradas y salidas
  25. Inicio clrf PORTB ; Borrado de los biestables de salida
  26. bsf STATUS,RP0 ; Selecciona banco 3 (RP0=RP1=’1’)
  27. bsf STATUS,RP1
  28. clrf ANSEL ; El puerto A de tipo digital
  29. clrf ANSELH ; El puerto B de tipo digital
  30. bcf STATUS,RP1 ; Selecciona banco 1 (RP1=’0’ RP0=’1’)
  31. clrf TRISB ; RB7:RB0 se configuran como salidas
  32. movlw b'00111111'
  33. movwf TRISA ; RA5:RA0 se configuran como entrada
  34. movlw b'00000010' ;movemos el valor de la opción del preescale  al registro W EN ESTE CASO A 8
  35. movwf OPTION_REG ;pasamos el valor de w al registro
  36. bcf STATUS,RP0 ; Se vuelve al banco 0
  37. movlw b'00000111' ;movemos el valor de la opción del preescale  al registro W
  38. movwf INTCON
  39. ; Fin de la inicialización del programa.
  40.  
  41. empezar MOVLW .250 ;INICIALIZAR CONTADOR
  42. MOVWF CONTADOR
  43.  
  44. esperar BTFSS PORTA,0 ;comprobamos si en interuptor esta en ON
  45. GOTO esperar
  46. MOVLW d'5' ;INICIALIZAR TMR0 A 5 PARA QUE CUENTE HASTA 250 YA QUE DESBORDA A 256 para simular x ejemplo poner 252
  47. MOVWF TMR0 ;CARGA EL VALOR DE 5 EN TMR0
  48. CLRF INTCON ;POR SI MIENTRAS SE ESPERABA A QUE SE ACTIVARA EL INTERRUPTOR SE HA DESBORDADO
  49. esperardes BTFSS INTCON,T0IF ;VERIFICAMOS CUANDO LLEGA A 256 MEDIANTE EL BIT 2  DEL REGISTRO INTCON
  50. GOTO   esperardes ;SI NO ES UNO HAY QUE ESPERAR
  51. CLRF INTCON ;SE HA ALCANZADO DESBORDAMIENTO HAN PASADO 2000us SE BORRA EL DESBORDAMIENTO
  52. DECFSZ CONTADOR,1 ;COMPROBAR QUE EL CONTADOR HA LLEGADO A 0 CUANDO OCURRE SALTA UNA INSTRUCCION
  53. GOTO esperar
  54. GOTO empezar ;EL CONTADOR ESTA A 0 , YA HAN PASADO 0,5 SEGUNDOS
  55. end

¿Como lo veis de momento?  :)

Gracias por la ayuda.[/size]
En línea

Fox_Neo

Desconectado Desconectado

Mensajes: 234



Ver Perfil
Re: Dudas para crear temporizador en ensamblador
« Respuesta #5 en: 22 Marzo 2013, 01:50 am »

Bueno por fin lo he conseguido  me ha costado lo suyo pero lo he conseguido  ;D
aqui esta:

Código
  1. ;***** CONFIGURACIÓN ******************************************************
  2. List p=16F886 ;Tipo de procesador
  3. include "P16F886.INC" ;Definiciones de registros internos
  4. ;Ajusta los valores de las palabras de configuración durante el ensamblado.Los bits no empleados
  5. ;adquieren el valor por defecto.Estos y otros valores se pueden modificar según las necesidades
  6.  
  7. __config _CONFIG1, _LVP_OFF&_PWRTE_ON&_WDT_OFF&_EC_OSC&_FCMEN_OFF ;Palabra 1 de configuración
  8. __config _CONFIG2, _WRT_OFF&_BOR40V
  9.  
  10. ; _MCLRE_ON: Reset externo ACTIVADO.
  11. ; _CP_OFF: Protección del código DESACTIVADO.
  12. ; _WDT_OFF: Watchdog DESACTIVADO.
  13. ; _IntRC_OSC: Oscilador interno de 4MHz.
  14. ;***** DEFINICIÓN DE VARIABLES
  15. ; Definimos las posiciones de memoria de los datos
  16. CONTADOR equ 0x20
  17. AUX equ 0x21
  18. ;**************************************************************************
  19. ; Inicialización del programa:
  20. ; Origen
  21. Org 0x00
  22. goto Inicio ;Vector de reset
  23. org 0x05
  24. ; Configuración de los puertos como entradas y salidas
  25. Inicio clrf PORTB ; Borrado de los biestables de salida
  26. bsf STATUS,RP0 ; Selecciona banco 3 (RP0=RP1=’1’)
  27. bsf STATUS,RP1
  28. clrf ANSEL ; El puerto A de tipo digital
  29. clrf ANSELH ; El puerto B de tipo digital
  30. bcf STATUS,RP1 ; Selecciona banco 1 (RP1=’0’ RP0=’1’)
  31. clrf TRISB ; RB7:RB0 se configuran como salidas
  32. movlw b'00111111'
  33. movwf TRISA ; RA5:RA0 se configuran como entrada
  34. movlw b'00000010' ;movemos el valor de la opción del preescale  al registro W EN ESTE CASO A 8
  35. movwf OPTION_REG ;pasamos el valor de w al registro
  36. bcf STATUS,RP0 ; Se vuelve al banco 0
  37. movlw b'00000111' ;movemos el valor de la opción del preescale  al registro W
  38. movwf INTCON
  39. ; Fin de la inicialización del programa.
  40.  
  41. ;______________________________ACTIVACIÓN INICIAL DE LA SALIDA_________________________________________________________
  42. ESPERAR BTFSS PORTA,0 ;PRIMERA VEZ QUE SE VA A VER SI ESTA ACTIVADO EL INTERUPTOR
  43. GOTO ESPERAR
  44. MOVLW b'0000001' ;SE ACTIVA LA SALIDALA PRIMERA VEZ QUE SE PONE EL INTERRUPTOR
  45. MOVWF   PORTB
  46. MOVLW 0X01 ;INICIALIZO EL REGISTRO AUX PARA INDICAR QUE SE HA ACTIVADO EL INTERRUPTOR
  47. MOVWF AUX
  48. ;__________________________________________________________________________________________________________
  49. empezar
  50. MOVLW .2 ;INICIALIZAR CONTADOR A 250 PARA SIMULAR PONER EL CONTADOR A 2
  51. MOVWF CONTADOR
  52.  
  53. esperar2
  54. CALL COMP_ENTRADA ;COMPRUEBA EL ESTADO DE LA ENTRADA
  55. BTFSS AUX,0 ;SI EL RESULTADO DE LA LLAMADA HA DADO 0 NO SE SALTA UNA INSTRUCCIÓN POR TANTO TIENE QUE REINICIARSE EL PROGRAMA
  56. GOTO ESPERAR
  57. MOVLW d'252' ;INICIALIZAR TMR0 A 5 PARA QUE CUENTE HASTA 250 YA QUE DESBORDA A 256 para simular x ejemplo poner 252
  58. MOVWF TMR0 ;CARGA EL VALOR DE 5 EN TMR0
  59. CLRF INTCON ;POR SI MIENTRAS SE ESPERABA A QUE SE ACTIVARA EL INTERRUPTOR SE HA DESBORDADO
  60. esperardes BTFSS INTCON,T0IF ;VERIFICAMOS CUANDO LLEGA A 256 MEDIANTE EL BIT 2  DEL REGISTRO INTCON CUANDO LLEGA SE DESBORADA DANDO UN 1
  61. GOTO   esperardes ;SI NO ES 1 HAY QUE ESPERAR
  62. CLRF INTCON ;SE HA ALCANZADO DESBORDAMIENTO HAN PASADO 2000us SE BORRA EL DESBORDAMIENTO
  63. DECFSZ CONTADOR,1 ;COMPROBAR QUE EL CONTADOR HA LLEGADO A 0 CUANDO OCURRE SALTA UNA INSTRUCCION
  64. GOTO esperar2
  65. GOTO activarsal ;EL CONTADOR ESTA A 0 , YA HAN PASADO 0,5 SEGUNDOS
  66. activarsal
  67. MOVLW b'0000001'
  68. XORWF   PORTB,F ;INVIERTE EL VALOR DE LA SALIDA
  69. GOTO empezar
  70.  
  71. ;_______________________SUBRUTINAS________________________________________________
  72.  
  73. COMP_ENTRADA NOP
  74. esperar3 BTFSS PORTA,0
  75. GOTO SALIDA0
  76. RETURN
  77.  
  78. SALIDA0 CLRF PORTB
  79. CLRF AUX ;AL APAGAR EL INTERUPTOR EN MITAD DEL PROCESO ENTRA AQUI  Y SEÑALO CON UN 0 QUE SE HA APAGADO EN INTERRUPTOR ES COMO EN C PONER EL RESULTADO DE UNA FUNCIÓN
  80. GOTO esperar3
  81.  
  82.  
  83. end

Gracias por la ayuda, si veis algo que se puede mejorar o reducir el programa me gustaría saberlo o si veis algún fallo.
Salu2 
En línea

Meta


Desconectado Desconectado

Mensajes: 3.438



Ver Perfil WWW
Re: Dudas para crear temporizador en ensamblador
« Respuesta #6 en: 23 Marzo 2013, 03:44 am »

Hola:

Puedes comprobarlo con un simulador de PIC como el Proteus 7.10.

Saludo.
En línea

Firos
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.410


Enseña lo que sepas... y oculta lo peor...


Ver Perfil
Re: Dudas para crear temporizador en ensamblador
« Respuesta #7 en: 26 Marzo 2013, 21:32 pm »

Si ya has conseguido que funcione ahora podrías perfeccionarlo.


Cuando comprobamos si un interruptor está a "1" o a "0" hay que eliminar rebotes.

Es decir, cualquier modo de contacto piezoeléctrico al hacer que conecten sus dos "bornes" hay ahí un "ruido" que en ocasiones puede ser que realmente el interruptor no esté a "1" o que en cuanto le des el contador automáticamente se detenga (en caso de que cuando detecte cero se pare).


Por esto mismo te recomiendo que hagas una cosa. Hazte una subrutina de retardos, como la que tienes de 0,5 segundos en este mismo hilo pero con muchas otras de 20 milisegundos, 50 milisegundos, 100 milisegundos, etc, etc.

Para hacer la comprobación de un pulsador es tan fácil como poner:
Código:
bucle        btfss     PORTA,1 ; Comprueba pulsador conectado en RA1.
             goto     bucle

             call       R20MS ; Haz una subrutina y solo tendras que poner esto en el código, sin tener que escribirla tu cada dos por tres.

             btfss     PORTA,1; Comprueba de nuevo, eliminando los rebotes
             goto      bucle

             TU CODIGO -> Y aqui sigues con tu codigo.



En breves te pongo otro enlace con un ejemplo de una subrutina
En línea

El final del camino no está determinado, lo determinamos nosotros mismos paso a paso, día a día, y se puede cambiar.
Fox_Neo

Desconectado Desconectado

Mensajes: 234



Ver Perfil
Re: Dudas para crear temporizador en ensamblador
« Respuesta #8 en: 29 Marzo 2013, 00:20 am »

Gracias Firos por responder siempre me gustan tus respuestas y aprendo bastante. A ver si lo he entendido, te refieres que se compruebe el estado de la entrada cada cierto tiempo ¿no?
En línea

Firos
Ex-Staff
*
Desconectado Desconectado

Mensajes: 1.410


Enseña lo que sepas... y oculta lo peor...


Ver Perfil
Re: Dudas para crear temporizador en ensamblador
« Respuesta #9 en: 29 Marzo 2013, 12:21 pm »

Gracias Firos por responder siempre me gustan tus respuestas y aprendo bastante. A ver si lo he entendido, te refieres que se compruebe el estado de la entrada cada cierto tiempo ¿no?


No...

Mira esta imagen:


Bien, en la parte de arriba, vemos una señal que va desde 0 a 5 V pero... al ser un interruptor mecánico, el contacto que hacen los dos bornes metálicos para dejar pasar la corriente no es perfecto y rebota un poco, dando ese efecto que aparece en la parte de arriba a la izquierda de la imagen, una señal que hace "ziczac".

Esos rebotes no los percibimos porque transcurren en microsegundos. El problema es que los microprocesadores trabajan mucho más rápido. Por ejemplo, un microprocesador trabajando a 4Mhz realiza una instrucción en cada microsegundo.

Eso que ves a la derecha es una forma de eliminar esos rebotes sin usar ningun programa, haciéndolo mediante Hardware pero eso no nos interesa aquí (aunque no está mal saberlo). Como ves, la señal de la derecha va desde "0" lógico a "1" lógico sin ningún problema.


Ahora bien, ¿como eliminamos esto mediante un programa? Con el código que te he puesto.

Tendríamos que comprobarlo un par de veces en un tiempo mínimo, mayor que el de los rebotes y menor de el que una persona pudiera cerrar y abrir el interruptor.

Por esto mismo puedes hacer un retardo de 20 milisegundos (20000 microsegundos) para que no tenga interferencias e implementarlo en el código.


Lo que se suele hacer cuando programamos para simplificar el código son "subrutinas" o "funciones" que son partes de código que se repiten y que con ponerlas una vez en una parte de el código y llamarlas desde donde las queremos ejecutar nos basta.

Por ejemplo: Si el PIC lo tenemos trabajando a 4Mhz con lo que tenemos 1 instrucción por segundo, podemos usar un par de contadores para tal efecto (sin usar los TIMERS para no mantenerlos ocupados y poder usarlos para hacer retardos de otro tipo como PWM, capturas de señal, retardos de tiempo para encender y apagar LEDS, etc, etc).

Código:
Imagina que tenemos 2 contadores. Con uno, podemos contar hasta 256, ¿verdad? Y como tenemos trabajando el microprocesador a 4Mhz sabemos que cada vez que ejecutemos una instrucción para incrementarlo (como INCF) tardaremos 1uS (microsegundo).

¿Y si usamos otro contador? Podríamos contar 256 veces el otro contador. Por lo tanto:
256 * 256 = 65536

Podríamos contar trabajando a 4Mhz con dos contadores hasta 65536 uS (65536 milisegundos). Pues bien, ahora solo nos hace falta despejar la formula.

XXX * 200 = 20000  <- Pongo 200 por poner algo, también podríamos ponerle 256 y solo tendríamos que borrar el contador con "CLRF" para que empiece a contar.

20000 / 200 = 100   <- Pues ya sabemos lo que tenemos que cargar en cada contador.

Esto es una manera rápida y cutre de hacerlo. Lo que tendríamos que hacer es un diagrama de flujo (un esquema) con los pasos que hacemos en el contador y sumarle los pasos que tarda en cada acción en cada bucle porque con estos cálculos que te he puesto para que lo entendamos todos en realidad va a tardar bastante mas de 20000 uS (aunque no lo percibirá el ojo humano y podríamos despreciarlo si la finalidad es únicamente comprobar el interruptor).



Esta es la que uso yo, que tiene un desfase de 1uS (que 1/20000 es un fallo mínimo):
Código:
;********************************************************************
; "R20MS"
;tsubrutina R20MS = (4.RET1.RET2 + 4.RET2 + 1) micseg.
;Rutina de temporización 20 milisegundos.
;********************************************************************

R20MS movlw .25 ;Carga RET2.
movwf RET2 ; "

R20MS1: movlw .199 ;Carga RET1.
movwf RET1 ; "

R20MS2: clrwdt ;Inicializa WDT.
decfsz RET1,F ;Decrementa RET1 hasta cero.
goto R20MS2 ;Si RET1 no es cero repite decremento.
decfsz RET2,F ;Si RET1=0 decrementa RET2.
goto R20MS1 ;Si RET2 no es 0 repite el bucle.
return


Y la tengo metida dentro de un fichero al que llamo "retardos.inc". Los contadores están en las posiciones altas 0x63, por ahí, para que si programo no me equivoque y ponga otro registro en el mismo sitio.


Luego, en el programa principal, en la parte de abajo ponemos:
Código:
include "retardos.inc"

end

Y con eso nos incluirá al compilar el programa la subrutina en nuestro programa. Ahora, desde cualquier otra parte de el programa podemos llamarla con:
Código:
call R20MS


Con lo que si miras el programa del POST anterior lo podrás ver mejor:
Si ya has conseguido que funcione ahora podrías perfeccionarlo.


Cuando comprobamos si un interruptor está a "1" o a "0" hay que eliminar rebotes.

Es decir, cualquier modo de contacto piezoeléctrico al hacer que conecten sus dos "bornes" hay ahí un "ruido" que en ocasiones puede ser que realmente el interruptor no esté a "1" o que en cuanto le des el contador automáticamente se detenga (en caso de que cuando detecte cero se pare).


Por esto mismo te recomiendo que hagas una cosa. Hazte una subrutina de retardos, como la que tienes de 0,5 segundos en este mismo hilo pero con muchas otras de 20 milisegundos, 50 milisegundos, 100 milisegundos, etc, etc.

Para hacer la comprobación de un pulsador es tan fácil como poner:
Código:
bucle        btfss     PORTA,1 ; Comprueba pulsador conectado en RA1.
             goto     bucle

             call       R20MS ; Haz una subrutina y solo tendras que poner esto en el código, sin tener que escribirla tu cada dos por tres.

             btfss     PORTA,1; Comprueba de nuevo, eliminando los rebotes
             goto      bucle

             TU CODIGO -> Y aqui sigues con tu codigo.



En breves te pongo otro enlace con un ejemplo de una subrutina


Espero que haya quedado claro :)

Un saludo.
En línea

El final del camino no está determinado, lo determinamos nosotros mismos paso a paso, día a día, y se puede cambiar.
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Ayuda con Temporizador para archivo .Bat
Scripting
joaquinrekpo 2 8,338 Último mensaje 7 Noviembre 2014, 17:28 pm
por joaquinrekpo
Encender un led cada 0.5 segundos usando temporizador en ensamblador
Electrónica
EIVL14 1 3,701 Último mensaje 30 Diciembre 2016, 07:49 am
por Meta
Cómo crear un temporizador para apagar tu PC de forma automática
Noticias
wolfbcn 0 1,597 Último mensaje 31 Diciembre 2016, 22:04 pm
por wolfbcn
ensamblador dudas
ASM
snowspring 2 2,558 Último mensaje 18 Mayo 2018, 18:18 pm
por snowspring
Temporizador en menú para cerrar venta.
Scripting
MaX2 3 2,299 Último mensaje 10 Febrero 2022, 22:56 pm
por .xAk.
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines