TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: ohsielos en 25 de Noviembre de 2010, 20:45:22

Título: Intermitentes moto.
Publicado por: ohsielos en 25 de Noviembre de 2010, 20:45:22
Ante todo presentarme, saludaros y agradeceros toda la ayuda que me podais brindar.

Estoy intentando sustituir el módulo de intermitencias de mi moto para poder eliminar las bombillas incandescentes e instalar leds. Si lo hago sin sustituirlo no parpadean al no detectar consumo y suponer que alguna se ha fundido.

Funcionamiento actual del módulo de intermitencias a reproducir:
-Dispongo de un pulsador en la mano izquierda y otro en la derecha que al pulsarlos envía 12v. al módulo de intermitencias.
- Al pulsar cualquiera de ellos parpadean los indicadores del lado correspondiente 9 veces y se para. (En realidad dura mas o menos según la velocidad, pero con que lo haga 9 o 10 veces me sirve).
- Si estando parpadeando vuelvo a pulsar el del mismo lado, deja de parpadear. Y si pulso el del lado contrario se pone a parpadear el de ese lado.
- Si pulso ambos botones durante 1 segundo (o al mismo tiempo) parpadean los 4 indicadores sin fin (estado emergencia o avería) hasta que pulso los dos de nuevo.

He conseguido con un 16F84A que al pulsar un botón u otro me realice el ciclo de 9 destellos y se apague, pero no consigo que al volver a pulsar mientras parpadea se detenga, ni tampoco que funcionen los 4 a la vez.

A ver si consigo pasaros lo que he hecho:
Código: ASM
  1. __CONFIG _CP_OFF& _WDT_OFF&_PWRTE_ON&_XT_OSC   
  2.                
  3.         LIST    P=16F84A
  4.         INCLUDE <P16F84A.INC>
  5.        
  6.         CBLOCK 0x0C
  7.         ENDC
  8.        
  9. #DEFINE LED_I   PORTB,3
  10. #DEFINE LED_D   PORTB,4        
  11. #DEFINE PUL_I PORTA,2
  12. #DEFINE PUL_D PORTA,1
  13.  
  14. ;ZONA CODIGOS************
  15.  
  16.         ORG     0
  17. Inicio 
  18.         bsf     STATUS,RP0      ;Acceso Banco 1.
  19.         bcf     LED_I           ;Línea Led RB3 configurada como salida.
  20.         bcf     LED_D           ;Línea Led RB4 configurada como salida.
  21.         bsf     PUL_I           ;Lìnea PUL RA2 configurada como entrada.
  22.         bsf     PUL_D           ;Lìnea PUL RA1 configurada como entrada.
  23.         bcf     STATUS,RP0      ;Acceso Banco 0.
  24.  
  25.        
  26.         movlw   0x09   
  27.         movwf   R_ContC         ;Cargamos el contador con el nº de blinks.    
  28.         bcf             LED_I           ;Apagamos los leds.
  29.         bcf             LED_D
  30.  
  31.        
  32. Check_Pul                                       ;Chequeo pulsadores.
  33.        
  34.         btfsc   PUL_I                   ;Pulsador PUL_I presionado salta. Pulsador=1?
  35.         call    Espera_I                ;No. Lee PUL_D.
  36.         btfsc   PUL_D
  37.         call    Espera_D                ;No. Vuelve a leerlos..
  38.         goto    Check_Pul
  39.        
  40. Espera_I       
  41.         call    Retardo_255ms   ;Retardo para que ralentice
  42.         call    Retardo_255ms   ;arranque parpadeo.
  43.         bcf             PUL_I                  
  44.         call    Principal_I             ;Va al ciclo de parpadeo.
  45.        
  46. Espera_D       
  47.         call    Retardo_255ms   ;Retardo para que ralentice
  48.         call    Retardo_255ms   ;arranque parpadeo.
  49.         bcf             PUL_D
  50.         call    Principal_D             ;Va al ciclo de parpadeo.      
  51.        
  52.                        
  53. Principal_I    
  54.        
  55.         bsf             LED_I                   ;Enciende el led
  56.         call    Retardo_50ms    ;durante este tiempo.
  57.         bcf             LED_I                   ;Lo apaga durante la suma de
  58.         call    Retardo_255ms   ;este retardo
  59.         call    Retardo_255ms   ;éste,
  60.         call    Retardo_255ms   ;éste,
  61.         call    Retardo_255ms   ;éste,
  62.         call    Retardo_200ms   ;y éste.      
  63.         decfsz  R_ContC,F               ;Cuenta el nº de blinks.
  64.         goto    Principal_I             ;Se repite 9 veces (instrucción 23).
  65.         goto    Inicio
  66.        
  67. Principal_D    
  68.        
  69.         bsf             LED_D                   ;Enciende el led
  70.         call    Retardo_50ms    ;durante este tiempo.
  71.         bcf             LED_D                   ;Lo apaga durante la suma de
  72.         call    Retardo_255ms   ;este retardo
  73.         call    Retardo_255ms   ;éste,
  74.         call    Retardo_255ms   ;éste,
  75.         call    Retardo_255ms   ;éste,
  76.         call    Retardo_200ms   ;y éste.      
  77.         decfsz  R_ContC,F               ;Cuenta el nº de blinks.
  78.         goto    Principal_D             ;Se repite 9 veces (instrucción 27).
  79.         goto    Inicio 
  80.        
  81.        
  82. ;Subrutinas Retardo_200ms, Retardo_100ms y Retardo_1ms*******  
  83.  
  84.         CBLOCK
  85.         R_ContA                 ;Contadores para los retardos
  86.         R_ContB
  87.         R_ContC
  88.         ENDC
  89.        
  90. Retardo_255ms
  91.         movlw   d'255'
  92.         goto    Retardos_ms    
  93. Retardo_200ms
  94.         movlw   d'200'
  95.         goto    Retardos_ms
  96. Retardo_100ms
  97.         movlw   d'100'
  98.         goto    Retardos_ms
  99. Retardo_20ms
  100.         movlw   d'20'
  101.         goto    Retardos_ms
  102. Retardo_50ms
  103.         movlw   d'50'
  104.         goto    Retardos_ms            
  105. Retardo_1ms
  106.         movlw   d'1'
  107. Retardos_ms
  108.         movwf   R_ContB
  109. R1ms_BucleExterno
  110.         movlw   d'249'
  111.         movwf   R_ContA
  112. R1ms_BucleInterno
  113.         nop
  114.         decfsz  R_ContA,F
  115.         goto    R1ms_BucleInterno
  116.         decfsz  R_ContB,F
  117.         goto    R1ms_BucleExterno
  118.         return
  119.                
  120.        
  121.         END

Vaya por delante que es la primera vez que intento programar un microcontrolador y llevo semanas leyendo y probando.
Y esto que debe ser muy simple, para mí es un mundo. O igual lo que pretendo es imposible.... :(

De todas formas todos los comentarios serán bienvenido, pero tengan en cuenta que estoy bastante verde  :oops:

Saludos


Edito: intenté (para que dejara de destellar si se pulsa un botón)colar un call después de la línea 62 y 76 (antes del decfsz) para que fuera a una subrutina y me pusiera el contador de parapadeos a 1 de forma que al retornar finalizara la cuenta de parpadeos y volviera a esperar alguna pulsación. Pero no funciona: cuando le doy al botón para que empiece a parpadear, destella una vez y se para.

Código: ASM
  1. btfss   PUL_I           ;Chequeo si se ha vuelto a pulsar.
  2.         call    ReseteoContC
  3.         decfsz  R_ContC,F               ;Cuenta el nº de blinks.
  4.         goto    Principal_I             ;Se repite 9 veces.
  5.         goto    Inicio
  6.        
  7. ReseteoContC
  8.         clrf    R_ContC         ;Borro contador de blinks.
  9.         movlw   0x01            ;Coloco un 1 en
  10.         movwf   R_ContC         ;el contador.
  11.         return
Título: Re: Intermitentes moto.
Publicado por: juan47 en 28 de Noviembre de 2010, 17:24:26
Hola ohsielos
 Soy novato en estos quehaceres pero veo lo siguiente y es pero que algun amable compañero pueda ayudarte mejor que yo
 Lo primero es comentarte que en las etiquetas Principal_I y Principal_D al final pones un goto inicio
Volviendo de esta manera a configurar de nuevo la pic
 Tambien decir, si no estoy equivocado, es el hecho que si tienes un intermitente trabajando si pulsas para que cambie o se pare
este pulsador no sera reconocido hasta que no vuelva el programa a la etiqueta Check_Pul
Por ello yo te recomiendo que efectues el reconocimiento de los pulsadores atraves de la interrupcion RB4-RB7
para asi en cualquier momento que quieras cambiar el estado de los leds sea mas rapido

  Un saludo
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 29 de Noviembre de 2010, 14:48:05
Te digo como lo haria yo.
Primero un bucle de espera.


ESPERA

btfss   PUL_I   
goto    $+3
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

Con esta rutina estara en espera hasta que se pulse uno de los lulsadores o los dos, si se pulsa alguno llama a antirrebotes, que es una temporizacion de 20ms para que pasen los rebotes de la pulsacion, y a continuacion va al bucle MAIN, ahi se mirara que pulsador se activo y lo que hay que hacer.

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS


MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA


Ahora esta el tema de que pare cuando esta activado, creo que la mejor opcion es ponerles unos "FLAGS" por software, unos bits de un registro al que le llamaremos FLAGS, el bit 0 sera para DERECHA  el bit 1 para IZQUIERDA, y el bit 2 para los_dos cuando el MAIN nos envie a estas rutinas cheqeuamos ese flag, si esta a 0 activara intermitente y lo pondremos a 1, asi la proxima vez estara a 1 entonces tocara apagar y ponerlo a 0 para la proxima

IZQUIERDA

btfss  FLAG,0
goto   ACTIVAR_I
bcf    FLAG,0
bcf    LED_I
return         ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1


ACTIVAR_I
bsf   FLAG_I
btfsc  PUL_I
goto   ESPERA  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto  ESPERA
bsf   LED_I    ; enciende intermitente izquierda
call  DEMORA   ;esta un tiempo encendido
bcf   LED_I    ; apaga
call  DEMORA
incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10         ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ACTIVAR_I    ; no, vuelve a repetir secuencia
return           ; ya van 10 va a main

Para derecha es igual cambiando los nombres de led, flag...

para los dos seria parecido.

LOS_DOS
btfss  FLAG,2  ; flag para saber si apagamos o encendemos
goto   ACTIVAR_LOSDOS
CLRF   PORTB
bcf    FLAG,2  ;apagamos intermitentes y borramos flag, ya que estaba a 1


ACTIVAR_LOSDOS
bsf   FLAG,2   ; el flag estaba a 0 lo activamos
btfsc  PUL_I
goto   ESPERA  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto  ESPERA
movlw  0x18
movwf  PORTB  ; ponemos a 1 bits 3 y 4 del puerto B
call   DEMORA  ; tiempo encendidos
clrf   PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
return




ANTIRREBOTES ; retardo 20ms para antirrebote
   movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        decfsz    PDel3, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel2,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
PDelL8  goto PDelL9         ; 2 ciclos delay
PDelL9  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


DEMORA ; retardo de 500ms para intermitencia
   movlw     .239      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .232      ; 1 set numero de repeticion  (A)
        movwf     PDel1     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  goto PDelL3         ; 2 ciclos delay
PDelL3  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
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  goto PDelL6         ; 2 ciclos delay
PDelL6  goto PDelL7         ; 2 ciclos delay
PDelL7  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.






Bueno esta hecho sobre la marcha y sin depurar,ni lo pase por el MPLAB SI AL COMPILAR TIRA ERRORES NO TE ASUSTES JEJEJE echale un ojo y si quieres acabalo y miramos los posibles errores que pueda tener. El tiempo de encendido y apagado lo puse en 500ms, pero se puede poner como se quiera sin problema. Si tienes problemas postealos por aqui.
   

Título: Re: Intermitentes moto.
Publicado por: ohsielos en 30 de Noviembre de 2010, 11:26:23
Muchas gracias  Juan y Tapi por contestar. Estuve investigando en pbasic a ve si me aclaraba mejor y pude hacerlo funcionar bastante bien. La cancelación de la intermitencia y el arranque de los cuatro a la vez no está muy allá porque hay que darle al pulsador en el momento justo, o mantenerlo pulsado un tiempo determinado, pero me podría valer.

Voy a intentar el programa que me ha pasado Tapi (menuda currada compañero, muchas gracias) intentaré terminarlo a ver si me va mejor.

Juan, en lo de las interrupciones estoy verde como una coliflor.

En cuanto pruebe algo, les cuento.

De nuevo, les reitero mi agradecimiento.

Saludos
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 30 de Noviembre de 2010, 16:00:49
Tapi8, he intentado completar el programa que me has pasado.
Lo primero que he hecho ha sido activar el wdt en la primera línea porque lo tenía desactivado.
Después te he cambiado la línea:
ACTIVAR_I
bsf   FLAG_I
por:
ACTIVAR_I
bsf   FLAG,0

(no me cuadraba que existiera un FLAG_I) .

Le añadí las líneas correspondientes para las etiquetas DERECHA y ACTIVAR_D

Al realizar el quickbuid con el mplab me tiraba errores al no encontrar definidos: REG_1, FLAG, CONTADOR, PDel0, PDel1, PDel2 y PDel3. Ni el END.
Los coloqué (como Dios me dió a entender  :oops:) entre un CBLOCK y ENDC. Y el END al final.

El quickbuild ya no da error  :), pero no funciona nada, todo apagado  :(.

Si eres tan amable de echarle un vistazo, te lo agradeceré, porque con las tablas, ese signo goto '$+3', el watchdog ladrando y esos bucles me has dejado descolocado.

Te adjunto el programa:

Código: ASM
  1. __CONFIG _CP_OFF& _WDT_ON&_PWRTE_ON&_XT_OSC    
  2.                
  3.         LIST    P=16F84A
  4.         INCLUDE <P16F84A.INC>
  5.        
  6.         CBLOCK 0x0C
  7.         CONTADOR
  8.         PDel0
  9.         PDel1
  10.         PDel2
  11.         PDel3
  12.         ENDC
  13.        
  14. REG_1   equ     0x01
  15. FLAG    equ     0x02   
  16.  
  17.        
  18. #DEFINE LED_I PORTB,3
  19. #DEFINE LED_D PORTB,4
  20. #DEFINE PUL_I PORTA,2
  21. #DEFINE PUL_D PORTA,1
  22.  
  23. ;ZONA CODIGOS************
  24.         ORG     0
  25.        
  26. ESPERA
  27.  
  28.         btfss   PUL_I  
  29.         goto    $+3
  30.         call    ANTIRREBOTES
  31.         goto    MAIN
  32.         btfss   PUL_D
  33.         goto    ESPERA
  34.         call    ANTIRREBOTES
  35.         goto    MAIN   
  36.  
  37. TABLA                                   ;esta tabla nos dirÁ que hay que hacer
  38.         addwf   PCL,1
  39.         goto    ESPERA          ; aqui nunca vendra, pero por si acaso....
  40.         goto    DERECHA
  41.         goto    IZQUIERDA
  42.         goto    LOS_DOS
  43.  
  44. MAIN
  45.  
  46.         btfss   PUL_D           ; miramos si en PUL_D hay un 1 o un 0
  47.         bcf     REG_1,0         ; y escribimos en un registro lo que haya
  48.         btfsc   PUL_D           ; en el bit 0
  49.         bsf             REG_1,0
  50.         btfss   PUL_I           ; hacemos lo mismo con el otro pulsador
  51.         bcf             REG_1,1         ; este lo escribimos en el bit 1
  52.         btfsc   PUL_I
  53.         bsf             REG_1,1         ; aquí ya tenemos los dos pulsadores leidos
  54.                                                 ; y anotados en un registro
  55.         movf    REG_1,0         ; lo movemos a W
  56.         call    TABLA
  57.         goto    ESPERA
  58.  
  59. IZQUIERDA
  60.  
  61.         btfss   FLAG,0
  62.         goto    ACTIVAR_I
  63.         bcf             FLAG,0
  64.         bcf             LED_I
  65.         return                  ; apaga flag e intermitente y vuelve a MAIN,
  66.                                                 ; FLAG estaba a 1
  67.  
  68.  
  69. ACTIVAR_I
  70.         bsf             FLAG,0
  71.         btfsc   PUL_I
  72.         goto    ESPERA          ; si mientras esta ejecutando una secuencia
  73.                                                 ; se pulsa un boton empieza de nuevo
  74.         btfsc   PUL_D
  75.         goto    ESPERA
  76.         bsf             LED_I           ; enciende intermitente izquierda
  77.         call    DEMORA          ; está un tiempo encendido
  78.         bcf             LED_I           ; apaga
  79.         call    DEMORA
  80.         incf    CONTADOR,1  ; para número de veces que encenderá
  81.         movlw   .10         ; le pongo 10 pero pueden ser las que tu quieras
  82.         subwf   CONTADOR,0
  83.         btfss   STATUS,Z        ; van 10 veces?
  84.         goto    ACTIVAR_I       ; no, vuelve a repetir secuencia
  85.         return                  ; ya van 10 va a main
  86.  
  87. DERECHA
  88.  
  89.         btfss   FLAG,1
  90.         goto    ACTIVAR_D
  91.         bcf             FLAG,1
  92.         bcf             LED_D
  93.         return                  ; apaga flag e intermitente y vuelve a MAIN,
  94.                                                 ; FLAG estaba a 1
  95.  
  96. ACTIVAR_D
  97.         bsf             FLAG,1
  98.         btfsc   PUL_D
  99.         goto    ESPERA          ; si mientras esta ejecutando una secuencia
  100.                                                 ; se pulsa un boton empiezade nuevo
  101.         btfsc   PUL_D
  102.         goto    ESPERA
  103.         bsf             LED_D           ; enciende intermitente izquierda
  104.         call    DEMORA          ; está un tiempo encendido
  105.         bcf             LED_D           ; apaga
  106.         call    DEMORA
  107.         incf    CONTADOR,1  ; para número de veces que encenderá
  108.         movlw   .10         ; le pongo 10 pero pueden ser las que tu quieras
  109.         subwf   CONTADOR,0
  110.         btfss   STATUS,Z        ; van 10 veces?
  111.         goto    ACTIVAR_D       ; no, vuelve a repetir secuencia
  112.         return                  ; ya van 10 va a main
  113.  
  114.  
  115. LOS_DOS
  116.         btfss   FLAG,2          ; flag para saber si apagamos o encendemos
  117.         goto    ACTIVAR_LOSDOS
  118.         CLRF    PORTB
  119.         bcf     FLAG,2          ; apagamos intermitentes y borramos flag,
  120.                                                 ; ya que estaba a 1
  121.  
  122.  
  123. ACTIVAR_LOSDOS
  124.         bsf     FLAG,2          ; el flag estaba a 0 lo activamos
  125.         btfsc   PUL_I
  126.         goto    ESPERA          ; si mientras esta ejecutando una secuencia
  127.                                                 ; se pulsa un boton empieza de nuevo
  128.         btfsc   PUL_D
  129.         goto    ESPERA
  130.         movlw   0x18
  131.         movwf   PORTB           ; ponemos a 1 bits 3 y 4 del puerto B
  132.         call    DEMORA          ; tiempo encendidos
  133.         clrf    PORTB           ; lo hago así porque supongo que
  134.                                                 ; no tienes mas cosas coectadas en PORTB
  135.         return
  136.  
  137. ANTIRREBOTES                    ; retardo 20ms para antirrebote
  138.  
  139.         movlw   .21             ; 1 set numero de repeticion  (B)
  140.     movwf       PDel2           ; 1 |
  141. PLoop3  
  142.         movlw   .237            ; 1 set numero de repeticion  (A)
  143.     movwf     PDel3     ; 1 |
  144. PLoop4  
  145.         clrwdt              ; 1 clear watchdog
  146.     decfsz      PDel3,1         ; 1 + (1) es el tiempo 0  ? (A)
  147.     goto        PLoop2          ; 2 no, loop
  148.     decfsz      PDel2,1         ; 1 + (1) es el tiempo 0  ? (B)
  149.     goto        PLoop1          ; 2 no, loop
  150. PDelL8  
  151.         goto    PDelL9          ; 2 ciclos delay
  152. PDelL9  
  153.         clrwdt              ; 1 ciclo delay
  154.     return              ; 2+2 Fin.
  155.  
  156.  
  157. DEMORA                                  ; retardo de 500ms para intermitencia
  158.         movlw   .239            ; 1 set numero de repeticion  (B)
  159.     movwf       PDel0           ; 1 |
  160. PLoop1  
  161.         movlw   .232            ; 1 set numero de repeticion  (A)
  162.     movwf       PDel1           ; 1 |
  163. PLoop2  
  164.         clrwdt              ; 1 clear watchdog
  165. PDelL1  
  166.         goto    PDelL2          ; 2 ciclos delay
  167. PDelL2  
  168.         goto    PDelL3          ; 2 ciclos delay
  169. PDelL3  
  170.         clrwdt              ; 1 ciclo delay
  171.     decfsz      PDel1,1         ; 1 + (1) es el tiempo 0  ? (A)
  172.     goto        PLoop2          ; 2 no, loop
  173.     decfsz      PDel0,1         ; 1 + (1) es el tiempo 0  ? (B)
  174.     goto        PLoop1          ; 2 no, loop
  175. PDelL4  
  176.         goto    PDelL5          ; 2 ciclos delay
  177. PDelL5  
  178.         goto    PDelL6          ; 2 ciclos delay
  179. PDelL6  
  180.         goto    PDelL7          ; 2 ciclos delay
  181. PDelL7  
  182.         clrwdt              ; 1 ciclo delay
  183.     return              ; 2+2 Fin.
  184.        
  185.         end



Pues nada. Un saludo y muchísimas gracias.

Edito.- lo he editado para colocar los contadores entre 'cblock y endc' y las dos líneas siguientes equ para flag y reg_1. Pero tampoco tira.
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 01 de Diciembre de 2010, 15:19:16
Quitale el WDT,WDT_OFF  no esta contemplado en el programa, sale en las rutinas de tiempo porque las hago con un programa que las genera automaticamente EL PDel, , lo tienes en este subforo al principio.
Debes poner FLAG y REG_1 entre CBLOCK Y ENDC ya que son registros de RAM.
El fallo principal es que no has configurado los puertos.pon esto al principio del programa antes de ESPERA.

org   0X00               ; VECTOR DE RESET
   GOTO   INICIO               ; va a inicio
   ORG   0x04               ; VECTOR DE INTERRUPCIONES



   ORG   0X05
INICIO
   BSF   STATUS,5            ; activa la pagina 1
   MOVLW   0XFF               ; carga FF en W
   MOVWF   TRISA               ; puerto A todos entradas
   MOVLW   0X00               ; carga 00000000 en W
   MOVWF   TRISB               ; mueve W a puerto B (todos salidaS)
   BCF   STATUS,5            ; volvemos a la pagina 0
        clrf    PORTB                              ; ponemos a o para empezar con intermitentes apagados

Aqui estaba mal, ponlo asi, esto fue fallo mio:

LOS_DOS
btfss  FLAG,2  ; flag para saber si apagamos o encendemos
goto   ACTIVAR_LOSDOS
CLRF   PORTB
bcf    FLAG,2  ;apagamos intermitentes y borramos flag, ya que estaba a 1
return

ACTIVAR_LOSDOS
bsf   FLAG,2   ; el flag estaba a 0 lo activamos
btfsc  PUL_I
goto   ESPERA  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto  ESPERA
movlw  0x18
movwf  PORTB  ; ponemos a 1 bits 3 y 4 del puerto B
call   DEMORA  ; tiempo encendidos
clrf   PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
call   DEMORA
goto   ACTIVAR_LOSDOS
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 04 de Diciembre de 2010, 11:44:10
Hola de nuevo.
Tapi8, tengo algún tipo de problema con el progrma porque no funciona. Llevo dos días intentando averiguar el motivo.
Una vez programdo el pic, lo monto en la plaquita de pruebas que hice y no se encienden los leds. Para probar que funciona lo reprogramo con el que hice en basic y sí funciona: parapadea, le cuesta salir, etc...pero va.
Lo mas curioso es que la simulación funciona bien en el mplab. Incluso lo cargo en el pic simulator ide, bajándole previamente el tiempo de retardos para que se vea el parpadeo en la ventanita de '8 x led Board' y se encienden y apagan correctamente al pulsar el RA0 o 1.
No me cuadra que las simulaciones vayan bien y al programarlo e instalar no funcione.
Lo programo con el WinPic800, y debe ir bien porque ya te digo que el que diseñé en basic, grabo el hex resultante sin problemas y va.
Incluso lo he simplificado al máximo para probar (con la tabla, que me gustó eso), de manera que al pulsar se encienda el led correspondiente y se quede ahí en un bucle y tampoco. Te lo dejo para que lo veas, es muy simple:

Código: ASM
  1. __CONFIG _CP_OFF& _WDT_OFF&_PWRTE_ON&_XT_OSC   
  2.                
  3.         LIST    P=16F84A
  4.         INCLUDE <P16F84A.INC>
  5.        
  6.         CBLOCK 0x0C
  7.         ENDC
  8.        
  9.  
  10.  
  11.        
  12. #DEFINE LED_I   PORTB,3
  13. #DEFINE LED_D   PORTB,4        
  14. #DEFINE PUL_I   PORTA,2
  15. #DEFINE PUL_D   PORTA,1
  16.  
  17. ;ZONA CODIGOS************
  18.         ORG     0
  19. Inicio 
  20.         bsf     STATUS,RP0      ;Acceso Banco 1.
  21.         clrf    TRISB
  22.  
  23.         movlw   b'00110'
  24.         movwf   TRISA
  25.         bcf     STATUS,RP0      ;Acceso Banco 0.
  26.         clrf    PORTB
  27.         clrf    PORTA
  28.        
  29.  
  30.        
  31. ESPERA
  32.         btfss   PUL_I
  33.         goto    $+2
  34.         goto    MAIN
  35.         btfss   PUL_D
  36.         goto    ESPERA
  37.         goto    MAIN
  38.        
  39. TABLA
  40.         addwf   PCL,1
  41.         goto    ESPERA
  42.         goto    DERECHA
  43.         goto    IZQUIERDA
  44.         goto    LOS_DOS
  45.        
  46. MAIN
  47.         btfss   PUL_D
  48.         bcf     REG_1,0
  49.         btfsc   PUL_D
  50.         bsf     REG_1,0
  51.         btfss   PUL_I
  52.         bcf     REG_1,1
  53.         btfsc   PUL_I
  54.         bsf     REG_1,1
  55.         movf    REG_1,0
  56.         call    TABLA
  57.         goto    ESPERA
  58.        
  59. IZQUIERDA
  60.  
  61.         BSF     LED_I
  62.        
  63.         goto    IZQUIERDA
  64.        
  65.        
  66.  
  67.        
  68. DERECHA
  69.  
  70.         BSF     LED_D
  71.        
  72.         goto    DERECHA
  73.  
  74.  
  75. LOS_DOS
  76.        
  77.         BSF     LED_I
  78.         BSF     LED_D
  79.         GOTO    LOS_DOS
  80.        
  81.        
  82.         CBLOCK
  83.         REG_1
  84.         ENDC
  85.  
  86.        
  87.         END

En fín, sigo haciendo pruebas a ver. Si se te ocurre algo me lo comentas.

Gracias.
Título: Re: Intermitentes moto.
Publicado por: juan47 en 04 de Diciembre de 2010, 15:44:15
Hola
Me he mirado por encima el ultimo ccodigo de programa y he encontrado que en la comparacion
btfss no le dices el bit al que tiene que apuntar
Instrucciones orientadas a Bit
BCF f,b      Coloca a 0 el bit b del registro f


BSF f,b       Coloca a 1 el bit b del registro f

BTFSC f,b   Salta si el bit b del reg. f es 0


BTFSS f,b    Salta si el bit b del reg. f es 1
   



Un saludo
Título: Re: Intermitentes moto.
Publicado por: juan47 en 04 de Diciembre de 2010, 16:08:29
Hola
Pido disculpas al no haberme tomado con calma la lectura del codigo
Si que se apunta al bit pues se tiene definido al principio del codigo

Un saludo
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 04 de Diciembre de 2010, 16:18:21
Hola Juan, tengo definidos los pulsadores y los leds al principio:
#DEFINE LED_I    PORTB,3
#DEFINE LED_D   PORTB,4
#DEFINE PUL_I    PORTA,2
#DEFINE PUL_D   PORTA,1

ahí ya le digo el registro y el bit en cuestión. Las que no llevan alguno de estos cuatro, ya lo especifico como por ejemplo
bsf   STATUS,RP0.

A mí lo que me trae de cabeza es que simule bien y al programar no funcione nada.

Gracias Juan por tu interés.

Edito: acabo de leer tu segundo mensaje después de publicar éste. No tienes por qué pedirlas. Gracias de nuevo.
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 05 de Diciembre de 2010, 07:47:54
El programa te deberia funcionar, pero eso si, solo se enciende una vez el que pulses o los dos, pero nada mas, despues tienes que resetear para poder encender el otro, tampoco parpadea solo se quedaria encendido y nada mas, a lo mejor el que funcione asi te esta despistando.
Por otro lado ayer tuve tiempo de ponerme con el MPLAB y ver fallos del programa de estos dias, creo que consegui hacer uno que funciona bien, te explico como va:
Si se pulsa cualquiera de los don enciende el de ese lado, enciende cuando se suelta, si se pulsa el que esta encendido, cuando se suelta apaga, si se pulsa el contrario, al soltar enciende el contrario, si se pulsan los dos encienden los dos, al soltar.
Le puse un antirrebotes de 300ms en lugar del de 20ms, porque me imagino que los humanos no somos capaces de pulsar exactamente al mismo tiempo, entonces este tiempo de espera compensaria ese error, ya que sino encenderia el que se pulsara primero. Esto cuando hagas pruebas veras si ese tiempo se puede rebajar o hay que aumentarlo, es el antirrebotes.
Por otro lado esta la cadencia del parpadeo, era de 500ms pero creo que va muy rapido, incluso creo que no se ajustaria a la legalidad ( esto te lo dirian en una ITV o en trafico) entonces la he puesto mas grande de 1500ms, pero no puede estar 1.5s en un bucle de temporizacion ya que si se pulsara para desactivar muchas veces no se enteraria, ya que mientras esta en el bucle no atiende a los pulsadores, se podria hacer por interrupciones o usar el TIMER, PERO COMO EN EL PRIMER POST DICES QUE ESTAS VERDE, he tratado de hacer el programa sin usar nada de esto, ademas no lo considero imprescindible, lo que he hecho es una temporizacion pequeña de 50ms , a la que se llama 30 veces, cada vez que se llama se chequean los pulsadores, de esta manera se hace un chequeo cada 50ms, es casi imposible pulsar un boton y soltarlo en ese tiempo (ni Valentino Rossi ni Jorge Lorenzo son capaces, porque cuando vean esos intermitentes te la pediran).
Código: [Seleccionar]
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>

__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; oscilador XT

CBLOCK 0x0C

CONTADOR
CONTADOR_1
PDel0
PDel1
PDel2
PDel3
PDel4
REG_1
FLAG
 ENDC


#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1


ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCIONES



ORG 0X05
INICIO
bsf STATUS,5 ; activa la pagina 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas aunque este puerto no se va a usar
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidaS)
bcf STATUS,5 ; volvemos a la pagina 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
; todos los LEDs apagados

clrf CONTADOR
clrf FLAG





ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS


MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA


IZQUIERDA
btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
clrf CONTADOR
btfss  FLAG,0
goto   ACTIVAR_I


DESACTIVAR_I

bcf    FLAG,0
bcf    LED_I
clrf CONTADOR
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return         ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1


ACTIVAR_I
bsf   FLAG,0
btfsc  PUL_I
goto   DESACTIVAR_D  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto  DERECHA

ENCIENDE_I
bsf   LED_I    ; enciende intermitente izquierda
call  DEMORA   ;esta un tiempo encendido
btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .50 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf   LED_I    ; apaga
call  DEMORA
btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .50 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10         ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ACTIVAR_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I

DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
clrf CONTADOR
btfss FLAG,1
goto ACTIVAR_D

DESACTIVAR_D

bcf FLAG,1
bcf LED_D
clrf CONTADOR
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return         ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
 
ACTIVAR_D
bsf FLAG,1
btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
bsf LED_D     ; enciende intermitente izquierda

ENCIENDE_D

call DEMORA   ; está un tiempo encendido
btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .50 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D     ; apaga
call DEMORA
btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .50 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10         ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z   ; van 10 veces?
goto ACTIVAR_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D


LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
btfss  FLAG,2  ; flag para saber si apagamos o encendemos
goto   ACTIVAR_LOSDOS

DESACTIVAR_LOSDOS
btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
bcf    FLAG,2  ;apagamos intermitentes y borramos flag, ya que estaba a 1
clrf PORTB   ; apagamos intermitentes
return

ACTIVAR_LOSDOS
bsf   FLAG,2   ; el flag estaba a 0 lo activamos
btfsc  PUL_I
goto   DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
movlw  0x18
movwf  PORTB  ; ponemos a 1 bits 3 y 4 del puerto B

ENCIENDE_LOSDOS

call   DEMORA  ; tiempo encendidos
btfsc  PUL_I
goto   DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
incf CONTADOR_1,1
movlw .50 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf   PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
call   DEMORA
btfsc  PUL_I
goto   DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
incf CONTADOR_1,1
movlw .50 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto   ACTIVAR_LOSDOS



ANTIRREBOTES                ; 300ms, aparte de servir de antirrebotes, tambien compensara
    ; si no se pulsan exactamente al mismo tiempo los dos botones
    movlw     .154      ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .243      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
PDelL8  goto PDelL9         ; 2 ciclos delay
PDelL9  goto PDelL10         ; 2 ciclos delay
PDelL10 
        decfsz    PDel3, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL11  goto PDelL12         ; 2 ciclos delay
PDelL12  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.
;-----------------------------------------------



DEMORA     ; retardo de 50ms que se repetira las veces que sea necesario
    ; para completar el tiempo adecuado para las intermitencias
movlw     .55       ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 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
        return              ; 2+2 Fin.
END

Bueno ya me diras los defectos que pueda tener
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 05 de Diciembre de 2010, 11:45:49
Hola, Tapi8.
Muchas gracias por el nuevo programa.
Respecto al antiguo, como ya te comenté, no enciende nada de nada; ni pulsando ni sin pulsar. Me da que debe haber algo con la tabla que no le sienta bien al micro. Porque ya te digo que simulaba perfectamente.
Eso sí, tuve que cambiar la situación de la llamada a 'antirrebotes' porque donde tu la colocaste al volver se iba a leer 'main' para colocar en 'reg_1' los valores que tenía que leer la tabla y ya no estaba pulsado por venir de antirrebotes y siempre había un 0,0 con lo cual la table me enviaba a 'espera'. Puse el antirrebotes al comienzo de las llamadas a 'derecha' e 'izquierda' y simulaba perfecto.

Digo yo: no será que el PIC16F84A tiene algo en contra de las tablas?? Por cierto para asegurarme me cogí un programita con una tabla sencilla en la cual después del addwf venían instrucciones 'retlw', y sí funcionaba esa tabla, con lo cual creo que no van por ahí los tiros.  :huh:

En cuanto pueda pruebo éste que has puesto a ver qué pasa. Si tardo en contestar es porque le doy mil vueltas para intentar hacerlo funcionar sin molestar a nadie.

Gracias de nuevo. Te debo una ronda.

Saludos
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 06 de Diciembre de 2010, 08:01:36
El antirrebotes es de 300ms, debe ir donde esta puesto, porque cuando detecta pulsacion en ESPERA lo hace para asegurarse de que en MAIN ya han pasado los rebotes y la lectura que haga va a ser la correcta, la puse bastante grande por lo que te explique de que al pulsar los dos si no se hace exactamente al mismo tiempo, cosa que creo que es normal, asumira que se pulso uno solo, el primero, si en las pruebas ves que esto no pasa se puede reducir, incluso a 20ms este es el tiempo que necesita el antirrebotes. Se hacen con este programa no se si ya lo has bajado.

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


En cuanto a las tablas no creo que sean problema pero te hice un programa sin ellas las he cambiado por otra rutina.


Código: [Seleccionar]
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>

__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; oscilador XT

CBLOCK 0x0C

CONTADOR
CONTADOR_1
PDel0
PDel1
PDel2
PDel3
PDel4
REG_1
FLAG
 ENDC


#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1


ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCIONES



ORG 0X05
INICIO
bsf STATUS,5 ; activa la pagina 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas aunque este puerto no se va a usar
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidaS)
bcf STATUS,5 ; volvemos a la pagina 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
; todos los LEDs apagados

clrf CONTADOR
clrf FLAG





ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN




MAIN
clrf REG_1 ;

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
movlw .3
subwf REG_1,0 ; miramos si REG_1 vale 3, serian los dos botones pulsados
btfsc STATUS,Z
goto LOS_DOS ; vale 3 encendemos los dos intermitentes
movlw .2
subwf REG_1,0 ; miramos si REG_1 vale 2, seria boton derecha
btfsc STATUS,Z
goto IZQUIERDA ; vale 2 encendemos intermitente derecha
movlw .1
subwf REG_1,0 ; miramos si REG_1 vale 1, seria boton izquierda
btfsc STATUS,Z
goto DERECHA ; vale 1 encendemos intermitente izquierda
goto ESPERA ; no es ninguno fueron rebotes, va a esperar pulsacion



IZQUIERDA
btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
clrf CONTADOR
goto   ENCIENDE_I


DESACTIVAR_I

bcf    LED_I
clrf CONTADOR
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
goto ESPERA         ; apaga flag e intermitente y vueleve a ESPERA, FLAG estaba a 1




ENCIENDE_I
bsf   LED_I    ; enciende intermitente izquierda
call  DEMORA   ;esta un tiempo encendido
btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .30 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf   LED_I    ; apaga
call  DEMORA
btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .30 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ENCIENDE_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I



DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
clrf CONTADOR
goto ENCIENDE_D

DESACTIVAR_D


bcf LED_D
clrf CONTADOR
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
goto ESPERA          ; apaga flag e intermitente y vueleve a ESPERA, FLAG estaba a 1

 


ENCIENDE_D
bsf LED_D
call DEMORA    ; está un tiempo encendido
btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .30 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D      ; apaga
call DEMORA
btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto IZQUIERDA
incf CONTADOR_1,1
movlw .30 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z    ; van 10 veces?
goto ENCIENDE_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D


LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
goto   ACTIVAR_LOSDOS

DESACTIVAR_LOSDOS
btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
bcf    FLAG,2  ;apagamos intermitentes y borramos flag, ya que estaba a 1
clrf PORTB    ; apagamos intermitentes
goto ESPERA          ; apaga flag e intermitente y vueleve a ESPERA, FLAG estaba a 1


ACTIVAR_LOSDOS

btfsc  PUL_I
goto   DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
movlw  0x18
movwf  PORTB  ; ponemos a 1 bits 3 y 4 del puerto B

ENCIENDE_LOSDOS

call   DEMORA  ; tiempo encendidos
btfsc  PUL_I
goto   DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
incf CONTADOR_1,1
movlw .30 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf   PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
call   DEMORA
btfsc  PUL_I
goto   DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
incf CONTADOR_1,1
movlw .30 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto   ACTIVAR_LOSDOS



ANTIRREBOTES                ; 300ms, aparte de servir de antirrebotes, tambien compensara
    ; si no se pulsan exactamente al mismo tiempo los dos botones
    movlw     .154      ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .243      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
PDelL8  goto PDelL9         ; 2 ciclos delay
PDelL9  goto PDelL10         ; 2 ciclos delay
PDelL10 
        decfsz    PDel3, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL11  goto PDelL12         ; 2 ciclos delay
PDelL12  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.
;-----------------------------------------------



DEMORA     ; retardo de 50ms que se repetira las veces que sea necesario
    ; para completar el tiempo adecuado para las intermitencias
movlw     .55       ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 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
        return              ; 2+2 Fin.
END
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 06 de Diciembre de 2010, 09:57:05
TAPI8 eres un genio  :-/ :-/ :-/.
Efectivamente, las tablas no son el problema porque he conseguido hacer funcionar tu programa anterior.
Tal como lo dejaste funcionaba bien, pero el tiempo encendido era muy largo. Los leds lucen instantáneamente (gran ventaja sobre las lámparas incandescentes) y me gustaba el efecto flash de un tiempo corto (50ms).
Al intentar bajarlo disminuyendo el valor .50 a .5 o .1 de la línea:
movlw   .50      ; número de veces que se repite el retardo de 50ms
ocurría que al montarlo en mi plaquita de pruebas y pulsar uno de los dos pulsadores el primer destello duraba 6 segundos, y los restantes 9 iban bien (50ms). Estuve toda la tarde dándole vueltas modificando los tiempos de antirrebotes y cambiándolo de sitio pero nada, hasta que me me dije: si solo quiero que vaya una vez a 'demora' (50ms) borro todo el tema de que vaya a contar y pase directamente a apagar.
Y así es como va perfecto, también le he bajado un poco el tiempo apagado de .50 a .40 y el tiempo de antirrebotes, iba un poco 'espeso', con la calculadora Picdel que me dijiste calculé para 150ms y cambié los números simplemente. Ahora va perfecto.
Se ha quedado así:

Código: ASM
  1. __CONFIG _CP_OFF& _WDT_OFF&_PWRTE_ON&_XT_OSC   
  2.                
  3.         LIST    P=16F84A
  4.         INCLUDE <P16F84A.INC>
  5.        
  6.         CBLOCK 0x0C
  7.         CONTADOR
  8.         CONTADOR_1
  9.         PDel0
  10.         PDel1
  11.         PDel2
  12.         PDel3
  13.         PDel4
  14.         REG_1
  15.         FLAG
  16.          ENDC
  17.  
  18.  
  19. #DEFINE LED_I PORTB,3
  20. #DEFINE LED_D PORTB,4
  21. #DEFINE PUL_I PORTA,2
  22. #DEFINE PUL_D PORTA,1
  23.        
  24.         ORG     0X00            ; VECTOR DE RESET
  25.         goto    INICIO          ; va a inicio
  26.         ORG     0x04            ; VECTOR DE INTERRUPCIONES
  27.  
  28.  
  29.  
  30.         ORG     0X05
  31. INICIO
  32.         bsf     STATUS,5        ; activa la página 1
  33.         movlw   0XFF            ; carga FF en W
  34.         movwf   TRISA           ; puerto A todos entradas aunque este puerto no se va a usar
  35.         movlw   0X00            ; carga 00000000 en W
  36.         movwf   TRISB           ; mueve W a puerto B (todos salidas)
  37.         bcf     STATUS,5        ; volvemos a la página 0
  38.         clrf    PORTB           ; ponemos a cero el puerto B para empezar con
  39.                                 ; todos los LEDs apagados
  40.         clrf    CONTADOR
  41.         clrf    FLAG
  42.  
  43. ESPERA                          ; Leemos los pulsadores.
  44.         btfss   PUL_I           ; si está pulsado Izq. va a ANTIRREBOTES, si no
  45.         goto    $+3             ; va tres posiciones para adelante
  46.         call    ANTIRREBOTES    ; al volver de Antirrebotes se va a MAIN
  47.         goto    MAIN
  48.         btfss   PUL_D           ; si está pulsado va a ANTIRREBOTES, si no
  49.         goto    ESPERA          ; vuelve a leer los pulsadores.
  50.         call    ANTIRREBOTES    ; al volver de Antirrebotes se va a MAIN
  51.         goto    MAIN
  52.  
  53. TABLA                           ;esta tabla nos dirá que hay que hacer
  54.         addwf   PCL,1
  55.         goto    ESPERA          ; aquí nunca vendrá, pero por si acaso....
  56.         goto    DERECHA
  57.         goto    IZQUIERDA
  58.         goto    LOS_DOS
  59.  
  60.  
  61. MAIN
  62.         btfss   PUL_D           ; miramos si en PUL_D hay un 1 o un 0
  63.         bcf     REG_1,0         ; y escribimos en un registro lo que haya
  64.         btfsc   PUL_D           ; en el bit 0
  65.         bsf     REG_1,0
  66.         btfss   PUL_I           ; hacemos lo mismo con el otro pulsador
  67.         bcf     REG_1,1         ; éste lo escribimos en el bit 1
  68.         btfsc   PUL_I
  69.         bsf     REG_1,1         ; aquí ya tenemos los dos pulsadores leidos y anotados en un registro
  70.         movf    REG_1,0         ; lo movemos a W
  71.         call    TABLA
  72.         goto    ESPERA
  73.  
  74.  
  75. IZQUIERDA
  76.         btfsc   PUL_I           ; Aquí espera hasta que se suelte pulsador
  77.         goto    $-1             ; va una posición para atrás
  78.         clrf    CONTADOR
  79.         btfss   FLAG,0          ; miramos si hay un 1 en el Flag,0
  80.         goto    ACTIVAR_I       ; si no lo hay nos vamos a activar parpadeo Izq.
  81.        
  82.  
  83. DESACTIVAR_I   
  84.         bcf     FLAG,0
  85.         bcf     LED_I
  86.         clrf    CONTADOR
  87.         btfsc   PUL_I           ; espera hasta que se suelte pulsador
  88.         goto    $-1             ; porque si retornara sin esperar volvería a secuencia
  89.         return                  ; apaga flag e intermitente y vuelve a MAIN, FLAG estaba a 1
  90.  
  91.  
  92. ACTIVAR_I
  93.         bsf     FLAG,0          ; ponemos un 1 en el Flag,0
  94.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  95.         goto    DESACTIVAR_I    ; si mientras está ejecutando una secuencia
  96.                                 ; se pulsa un botón empieza de nuevo
  97.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  98.         goto    DERECHA         ; si lo estuviese nos vamos a encender Dcho.
  99.  
  100. ENCIENDE_I
  101.         bsf     LED_I           ; enciende intermitente Izq.
  102.         call    DEMORA          ; está un tiempo encendido
  103.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  104.         goto    DESACTIVAR_I    ; si mientras esta ejecutando una secuencia
  105.                                 ; se pulsa un botón empieza de nuevo
  106.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  107.         goto    IZQUIERDA       ; si lo estuviese nos vamos a encender Izq.
  108. ;       incf    CONTADOR_1,1   
  109. ;       movlw   .5              ; número de veces que se repite el retardo de 50ms
  110. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  111. ;       btfss   STATUS,Z        ; salta si el bit Z de Status es 1.
  112. ;       goto    ENCIENDE_I
  113.         clrf    CONTADOR_1      ; ponemos a 0 contador y nos vamos a apagar el led.
  114.  
  115. APAGA_I
  116.         bcf     LED_I           ; apaga el led Izq.
  117.         call    DEMORA          ; lo mantiene apagado 50ms.
  118.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  119.         goto    DESACTIVAR_I    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  120.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  121.         goto    IZQUIERDA       ; si lo está nos vamos a
  122.         incf    CONTADOR_1,1
  123.         movlw   .40             ; número de veces que se repite el retardo de 50ms
  124.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  125.         btfss   STATUS,Z
  126.         goto    APAGA_I
  127.         clrf    CONTADOR_1      ; ponemos a 0 contador
  128.        
  129.         incf    CONTADOR,1      ; para número de veces que encenderá
  130.         movlw   .10             ; le pongo 10 pero pueden ser las que tu quieras
  131.         subwf   CONTADOR,0
  132.         btfss   STATUS,Z        ; van 10 veces?
  133.         goto    ACTIVAR_I       ; no, vuelve a repetir secuencia
  134.         clrf    CONTADOR       
  135.         goto    DESACTIVAR_I
  136.  
  137. DERECHA
  138.         btfsc   PUL_D           ; Aquí espera hasta que se suelte pulsador
  139.         goto    $-1             ; va una posición para atrás
  140.         clrf    CONTADOR
  141.         btfss   FLAG,1
  142.         goto    ACTIVAR_D
  143.        
  144. DESACTIVAR_D   
  145.         bcf     FLAG,1          ; pone un 0 en el bit 1 de Flag.
  146.         bcf     LED_D           ; apaga led Dcho.
  147.         clrf    CONTADOR        ; pone a 0 el Contador.
  148.         btfsc   PUL_D           ; espera hasta que se suelte pulsador
  149.         goto    $-1             ; porque si retornara sin esperar volvería a secuencia
  150.         return                  ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
  151.  
  152. ACTIVAR_D
  153.         bsf     FLAG,1
  154.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  155.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia
  156.                                 ; se pulsa un botón empieza de nuevo
  157.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  158.         goto    IZQUIERDA
  159.        
  160. ENCIENDE_D
  161.         bsf     LED_D           ; enciende intermitente Dcho.  
  162.         call    DEMORA          ; está un tiempo encendido
  163.         btfsc   PUL_D
  164.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  165.         btfsc   PUL_I
  166.         goto    IZQUIERDA
  167. ;       incf    CONTADOR_1,1
  168. ;       movlw   .50             ; número de veces que se repite el retardo de 50ms
  169. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  170. ;       btfss   STATUS,Z
  171. ;       goto    ENCIENDE_D
  172.         clrf    CONTADOR_1      ; ponemos a 0 contador
  173.  
  174. APAGA_D
  175.         bcf     LED_D           ; apaga
  176.         call    DEMORA
  177.         btfsc   PUL_D
  178.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  179.         btfsc   PUL_I
  180.         goto    IZQUIERDA
  181.         incf    CONTADOR_1,1
  182.         movlw   .40             ; número de veces que se repite el retardo de 50ms
  183.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  184.         btfss   STATUS,Z
  185.         goto    APAGA_D
  186.         clrf    CONTADOR_1      ; ponemos a 0 contador
  187.        
  188.         incf    CONTADOR,1      ; para número de veces que encenderá
  189.         movlw   .10             ; le pongo 10 pero pueden ser las que tu quieras
  190.         subwf   CONTADOR,0
  191.         btfss   STATUS,Z        ; van 10 veces?
  192.         goto    ACTIVAR_D       ; no, vuelve a repetir secuencia
  193.         clrf    CONTADOR
  194.         goto    DESACTIVAR_D
  195.  
  196.  
  197. LOS_DOS
  198.         btfsc   PUL_I
  199.         goto    $-1
  200.         btfsc   PUL_D           ; miramos si están sin pulsar ambos botones
  201.         goto    $-3
  202.         btfss   FLAG,2          ; flag para saber si apagamos o encendemos
  203.         goto    ACTIVAR_LOSDOS
  204.  
  205. DESACTIVAR_LOSDOS
  206.         btfsc   PUL_I
  207.         goto    $-1
  208.         btfsc   PUL_D           ; miramos si están sin pulsar ambos botones
  209.         goto    $-3    
  210.         bcf     FLAG,2          ;apagamos intermitentes y borramos flag, ya que estaba a 1
  211.         clrf    PORTB           ; apagamos intermitentes
  212.         return
  213.  
  214. ACTIVAR_LOSDOS
  215.         bsf     FLAG,2          ; el flag estaba a 0 lo activamos
  216.         btfsc   PUL_I
  217.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  218.         btfsc   PUL_D
  219.         goto    DESACTIVAR_LOSDOS
  220.         movlw   0x18
  221.         movwf   PORTB           ; ponemos a 1 bits 3 y 4 del puerto B
  222.        
  223. ENCIENDE_LOSDOS
  224.         call    DEMORA          ; tiempo encendidos
  225.         btfsc   PUL_I
  226.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  227.         btfsc   PUL_D
  228.         goto    DESACTIVAR_LOSDOS
  229. ;       incf    CONTADOR_1,1
  230. ;       movlw   .50             ; número de veces que se repite el retardo de 50ms
  231. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  232. ;       btfss   STATUS,Z
  233. ;       goto    ENCIENDE_LOSDOS
  234.         clrf    CONTADOR_1      ; ponemos a 0 contador
  235.  
  236. APAGA_LOSDOS           
  237.         clrf    PORTB           ; lo hago así porque supongo que no tienes mas cosas coectadas en PORTB
  238.         call    DEMORA
  239.         btfsc   PUL_I
  240.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  241.         btfsc   PUL_D
  242.         goto    DESACTIVAR_LOSDOS
  243.         incf    CONTADOR_1,1
  244.         movlw   .40             ; número de veces que se repite el retardo de 50ms
  245.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  246.         btfss   STATUS,Z
  247.         goto    APAGA_LOSDOS
  248.         clrf    CONTADOR_1      ; ponemos a 0 contador
  249.         goto    ACTIVAR_LOSDOS
  250.  
  251.  
  252.  
  253. ANTIRREBOTES                
  254.                                 ; 300ms, aparte de servir de antirrebotes, también compensará                         ; si no se pulsan exactamente al mismo tiempo los dos botones
  255.         movlw   .117            ; 1 set número de repetición  (B)
  256.        movwf    PDel2           ; 1 |
  257. PLoop3  movlw   .213            ; 1 set número de repetición  (A)
  258.         movwf   PDel3           ; 1 |
  259. PLoop4  
  260. ;       clrwdt                  ; 1 clear watchdog
  261. PDelL8  goto    PDelL9          ; 2 ciclos delay
  262. PDelL9  goto    PDelL10         ; 2 ciclos delay
  263. PDelL10  
  264.         decfsz  PDel3,1         ; 1 + (1) es el tiempo 0  ? (A)
  265.         goto    PLoop4          ; 2 no, loop
  266.         decfsz  PDel2,1         ; 1 + (1) es el tiempo 0  ? (B)
  267.         goto    PLoop3          ; 2 no, loop
  268. PDelL11  goto   PDelL12                 ; 2 ciclos delay
  269. PDelL12  
  270. ;       clrwdt                  ; 1 ciclo delay
  271.         return                  ; 2+2 Fin.
  272. ;-----------------------------------------------
  273.  
  274.  
  275.  
  276. DEMORA                          ; retardo de 50ms que se repetirá las veces que sea necesario
  277.                                 ; para completar el tiempo adecuado para las intermitencias
  278.         movlw   .55             ; 1 set número de repetición  (B)
  279.         movwf   PDel0           ; 1 |
  280. PLoop1  movlw   .181            ; 1 set número de repetición  (A)
  281.         movwf   PDel1           ; 1 |
  282. PLoop2  
  283. ;       clrwdt                  ; 1 clear watchdog
  284. ;        clrwdt                 ; 1 ciclo delay
  285.         decfsz  PDel1, 1        ; 1 + (1) es el tiempo 0  ? (A)
  286.         goto    PLoop2          ; 2 no, loop
  287.         decfsz  PDel0,  1       ; 1 + (1) es el tiempo 0  ? (B)
  288.         goto    PLoop1          ; 2 no, loop
  289.         return                  ; 2+2 Fin.
  290.        
  291.        
  292.         END

Pero no creas que ya has terminado, jejejeje (que abusón soy   :oops:). Voy a intentar pasarlo a un pic de ocho patillas tipo 12F629 o 675, que llevan oscilador interno y ahorro bastante espacio. ¿Cual me aconsejas?  encuentro en ebay mas económico el 675 que el 629 a pesar de llevar convertidor a/d. O si crees que es mejor algún otro modelo soy todo oidos. Eso sí, he de poder grabarlo con el TE-20, no quiero liarme mas. Ya bastantes dolores de cabeza me ha dado éste.

También estoy investigando como hacer que la salida del pic me maneje los leds de la moto, porque mi intención es aprovechar el casquillo de la lámpara para poner el led entre masa y el punto central por donde se supone han de llegarle los +12v. Ya he comprobado que directamente con transistores no puedo, porque el pic maneja tensiones de 0 y 5v. con lo cual el transistor como máximo me deja 5v en el emisor y necesito los +12 (lleva un led ambar de 3w con un driver que le suministra los 700mA que necesita). Voy a probar con un optoacoplador mas un transitor de potencia. Ya te contaré.

De nuevo mi gratitud por tu interés en mi problema.
Ya la ronda es con gambas.
Un saludo
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 06 de Diciembre de 2010, 15:26:16
Me alegro mucho  :-/ :-/ :-/
Solo lo tienes encendido 50ms y apagago 2seg? sabia que los LEDs consumian poco pero tanto. Es el efecto optico, el ojo humano ve mas el tiempo de encendido que el de apagado.
Mira este hilo, el primer esquema, si en el sitio de la bobina del rele le pones los intermitentes, los dos en paralelo, casi lo tienes, no necesitas poner el diodo, no necesitas que sea un transistor de potencia, no necesitas optoacoplador, todas estas cosas son para cargas inductivas (motores) y para potencias grandes, tu solo vas a controlar unos LEDs de 3W. un transistor que soporte 20V de Vce y:

I=W/V=3/12=0.25A

Como son dos LED O.5A para que no este a tope 1A de Ic (intensidad de colector)

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

Aqui te dejo una pagina de un motero que de esto de electronica sabe la hostia, y tiene una buena explicacion de como se conectan los transistores:

http://picmania.garcia-cuervo.net/electronica_basica.php#TRANS1

En cuanto al PIC de 8 patas te lo iba a decir yo, es la mejor opcion, incluso tienes la serie 10f que es de 6 pines y tambien te valdria, te vale cualquiera de ellos, el programa, cualquiera de los que hice no llega a 200 BYTES, y el mas pequeño de estos tiene 256.
El programa hay que modificarlo un poco para la serie 12f y 10f, no mucho, pero algo si, pero bueno si tienes algun problema te ayudare en lo que pueda.

Saludos y me alegro mucho.
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 06 de Diciembre de 2010, 15:47:53
Hola, éste consume "mucho" (3w frente a los 21w de una lámpara incandescente) porque brilla mucho también, y quiero que se vea de lejos (cuando lo he mirado sin querer me ha dejado la vista chunga un rato), y la tulipa siempre se come algo de luz.

Concretamente es éste led el que he comprado, además de un 'driver' que le suministra la corriente justa a partir de 12 a 20v.

http://cgi.ebay.com/5p-3W-STAR-HIGH-POWER-AMBER-LED-LAMP-45lm-FREE-SHIPPING-/350084920256?pt=LH_DefaultDomain_0&hash=item5182aff3c0 (http://cgi.ebay.com/5p-3W-STAR-HIGH-POWER-AMBER-LED-LAMP-45lm-FREE-SHIPPING-/350084920256?pt=LH_DefaultDomain_0&hash=item5182aff3c0)

He estado viendo el enlace de los circuitos y tal como están sí funciona: alimenta a 12v el circuito que está en el colector del transistor, pero lo que yo necesito es por un solo cable enviar los +12 al led y que por el casquillo de la lámpara vaya a masa y conduzca, el esquema sería el siguiente (perdona por la chapuza pero he modificado el del compañero con el paint).

(http://)


Como ves en el esquema, cuando conduce el tr envía 12v al intermitente y de ahí a masa, como en todas las bombillas creo. Si lo pusiera en el colector necesitaría dos cables y aislar el portalámparas ya que ninguna pata iría a masa.

Otra cosa: esos pics 12F y 10F se programan con el TE-20?? Es un punto importante para no complicarme mas la vida.

Por cierto: el parpadeo es bastante 'natural', igual le acorto un poco el tiempo de apagado, pero se ve ya bastante 'legal'.

Voy a pasarme por el enlace del motero a ver que tal.
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 10 de Diciembre de 2010, 07:07:24
En esta pag. explica como grabar PICs DE 8 PINES con el TE-20, espero te aclare dudas.

http://www.tarribot.com/?id=23&idm=1

En el circuito no se si has avanzado mucho, ya sabes como vas a convertir los 12V a 5V para alimentar el PIC, y que transistores vas a usar etc.

Estoy optimizando el programa haciendolo con desborde de TIMER, estos dias lo pondre por aqui, despues usas el que quieras, tambien estara en torno a 200 BYTES asi que te servira cualquier PIC, el que mas barato te salga, mas facil de conseguir...

Saludos
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 10 de Diciembre de 2010, 18:28:07
Hola de nuevo.
La alimentación lo tengo claro: con un regulador 7805 o 78M05, uno cualquiera ya que el pic apenas va a consumir. Después miraré el consumo máximo que puedo tener y ya me decido.
Entrarán los +12v de la batería que alimentará al pic via 7805 y saldrán hacia los intermitentes donde instalaré en cada uno el driver de 700mA (que le da igual que hayan 12 que 15v) y el led de 3w que dará la luminosidad adecuada. Si es demasiado igual los cambio por otros de 1w y 100mA de consumo, el driver me serviría igualmente (es una fuente de corriente).

Acabo de conseguir una FA averiada de un PC y ya he visto que trae 3 optos para probar, mañana suelto uno y prueba a ver si consigo que me mande via un BD437 +12v al led.
Ya me he pedido por ebay 5 PIC12F629 ya que no encontré mucha diferencia de precio respecto al 10F200 o 220 no recuerdo bien, que son los que vi en la lista de 'programables' por el winpic800. Tardarán un mes en llegar (China).

Mientras voy a ver si adapto el programita último que te dije que iba muy, pero muy bien. Al final dejé tiempo On 50mS, Off 1.5seg. y el antirrebortes a 100mS. Ya te digo, va de fábula sobre mi plaquita de pruebas: detecta rápidamente la pulsación de cualquier botón y de ambos a la vez. Estoy muy contento con el resultado.
No sé si con el Timer tendría alguna ventaja, igual si se queda dormido (sleep) y arranca al pulsar algún botón podría ser, pero como este tinglado funciona con la moto en marcha no me preocupa mucho unos mA porque el PIC esté en un bucle esperando una pulsación. Mientras no se rompa por ello, no me quita el sueño.

Voy a echar un ojo al enlace que me has dejado. Me supongo que adaptando las patillas VDD, VSS, CLK y las que intervengan en la programación del 16F84A al 12F629 debería poder ser programado. Voy a mirar a ver que se cuece.
Ya te contaré si funciona todo y queda listo para montar en la moto. La tarea mas chunga.

Saludos

Edito: Ya funciona con el optoacoplador, el led se ilumina perfectamente. Voy a adjuntar el esquema para el PIC16F84A con el que me ha funcionado por si a alguien le viene bien.

Título: Re: Intermitentes moto.
Publicado por: tapi8 en 13 de Diciembre de 2010, 08:56:40
Pues muy bueno el esquema, ademas le has puesto unos transistores que deben de ir sobrados, aislados con optos, mucho mejor que lo que deben de traer los de fabrica.
Te pongo el programa con TIMER, no es absolutamente necesario en este caso, pero es la manera mas normal de hacerlo. admas como veo que entiendes bien los programas que te he puesto, ya que sabes hacerles modificaciones, pues asi tambien aprendes de esta manera, aqui repito que no es totalmente necesario porque son solo dos pulsadores que los activan humanos, y somos muy lentos, simplemente haciendo chequeos cada 50ms es suficiente, pero hay ocasiones en que hay que controlar sensores electronicos muy rapidos y a veces muchos sensores, entonces hacer bucles de tiempo de 50ms es un tiempo enorme que el PIC no se entera de nada, de esta manera chequea continuamente los sensores, como mucho cada 15 millonesimas de segundo, ahora ya le puedes dejar la moto a Valentino Rossi que ni el tiene cojones a pulsarlo sin que se entere  :lol: :lol:.
Le he puesto un antirrebotes pequeño de 20ms, porque en el anterior no tenia en cuenta que cuando esta encendido un lado y se pulsa el contrario iba directamente, ahora ahi es donde hace ese antirrebotes para asegurarse.

Código: [Seleccionar]
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>

__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; oscilador XT

ERRORLEVEL -302

CBLOCK 0x0C

CONTADOR
CONTADOR_1
REG_1
PDel0
PDel1
PDel2
PDel3
 

 ENDC


#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1


ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCIONES



ORG 0X05
INICIO
bsf STATUS,5 ; activa la pagina 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas aunque este puerto no se va a usar
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidaS)
movlw 0X07 ; TIMER con preedcaler de 256, para 50ms
movwf OPTION_REG
movlw 0X20 ; habilitamos desborde de TIMER. pero sin interrupcion
movwf INTCON ; cada 50ms nos seteara el flag TOIF de INTCON
bcf STATUS,5 ; volvemos a la pagina 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
; todos los LEDs apagados

clrf CONTADOR
clrf CONTADOR
clrf REG_1






ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS


MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA

CAMBIA_I ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
; y haga algo indeseado
call ANTIRREBOTES_1
btfss PUL_I ; comprueba que realmente se pulso
goto ENCIENDE_D ; falsa alarma va a donde estaba
btfsc PUL_D ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia


IZQUIERDA

btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto    ENCIENDE_I


DESACTIVAR_I

bcf     LED_I
clrf CONTADOR
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return            ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1



ENCIENDE_I
bsf    LED_I    ; enciende intermitente izquierda
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D  ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf    LED_I    ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D   ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_D
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ENCIENDE_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I


CAMBIA_D ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
; y haga algo indeseado
call ANTIRREBOTES_1
btfss PUL_D ; comprueba que realmente se pulso
goto ENCIENDE_I ; falsa alarma va a donde estaba
btfsc PUL_I ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia


DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DESACTIVAR_D


bcf LED_D
clrf CONTADOR
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return          ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
 


ENCIENDE_D

bsf LED_D      ; enciende intermitente
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D      ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2     ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z    ; van 10 veces?
goto ENCIENDE_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D


LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
clrf CONTADOR_1
bcf INTCON,2
goto   ENCIENDE_LOSDOS


DESACTIVAR_LOSDOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
clrf PORTB   ; apagamos intermitentes
return


ENCIENDE_LOSDOS

movlw  0x18
movwf PORTB  ; ponemos a 1 bits 3 y 4 del puerto B
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_I
goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2     ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf    PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc  PUL_I
goto  DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto    ENCIENDE_LOSDOS


ANTIRREBOTES               ;

DEMORA  movlw     .110      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 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  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


ANTIRREBOTES_1 ; antirrebotes de 20ms solo cuando esta funcionando un
; y se cambia para el otro, sin pasar por MAIN
movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        decfsz    PDel3, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


END


Por otro lado si te preocupa el consumo de los intermitentes cuando la moto esta parada y tiene los cuatro puestos, porque lleva dos delante y dos detras no? o solo los de atras?, bueno podriamos ponerlos en bajo consumo, haciendo PWM y haciendo que se apagaran y encendieran muy rapido, se verian encendidos con menos brillo pero consumirian menos, para ello no tendrias que cambiar nada en el esquema solo hariamos unos cambios en el programa y listo.
Se podria hacer que cuando la dejes aparcada durante los primeros minutos esten a tope, y al pasar ese tiempo se pongan en bajo consumo, o que si pulsas los dos una pulsacion corta enciendan a tope ( porque si vas andando y hay un accidente y paras, poder indicarles a los que vienen atras que paras ) y si es para aparcar y la vas a dejar bastante tiempo, le pulsas un poco mas de tiempo 2s, por ejemplo y enciendan en bajo consumo, bueno tu eres el que sabes de motos ya me diras si te parece que podria ser util.
Ya estoy mirando el datasheet de 12f629, no lo programe nunca pero creo que no habra mucho problema, solo tengo unas dudas con el clock interno pero creo que las dare resuelto.

Saludos Tapi
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 13 de Diciembre de 2010, 13:02:53
Hola Tapi8.
Vaya currada con los timer. Lo he probado y va muy bien, le he cambiado en antirrebotes_1 de 20ms a 30 ya que el cambio directo de un intermitente que está funcionando al otro parece que va un poco mejor. Al igual que en el programa anterior (sin timer) la mayoría de las veces no cambia si no que hay que pulsar dos veces (una para parar la intermitencia del que está en marcha y otra para arrancar el intermitente contrario), casi siempre cuesta mas el paso de parpadeo izquierdo al derecho que al revés. Pero vamos, que no es un problema que me quite el sueño, me da igual si tengo que pulsar dos veces, el único pequeño inconveniente que pueda tener circulando es que hay que echarle un ojo a ver si van o no.

El tema de bajar el consumo con ambos en marcha: no pierdas el tiempo, en mi caso en parado lo he usado poquísimas veces, en marcha mas veces cuando salgo con muchos colegas. Es una Harley y hay veces que vamos a alguna concentración, y ahí a veces los pongo. De todas formas los 4 leds funcionando a la vez a 700mA serían 2.8A x50mS cada segundo y medio aprox. Con las 4 bombillas de 21w--->1.75Ax4= 7Ax200mS aprox. es mucho mas consumo.

Mi moto con la de V.Rossi no tiene muchos puntos comunes  :lol: Nosotros vamos en otra onda, lo nuestro es el relax y la contemplación  :D

Una duda que me asalta (entre muchísimas otras) y no le veo lógica son estas líneas seguidas:

24.- ORG 0X00        ; VECTOR DE RESET
25.- goto INICIO     ; va a inicio
26.- ORG 0x04        ; VECTOR DE INTERRUPCIONES
.
.
30.- ORG 0X05

Entiendo que la primera línea decimos que arrancamos la memoria en 0x00, supongo que una vez se va a INICIO ya no vuelve, y aunque volviera le diría que apunte a la posición 0x04 y acto seguido a la 0x05. No sé son cosas que me cogen muy mayor y se me descuadran, para que le digo que vaya a la 4 si después le digo que no, que a la 5??

Pasando a otro tema. Probé a adaptar el programita que funcionaba (sin timer) al 12F629, lo simulé y no me dió error. Los leds se encendían y apagaban bien con el PIC Simulator Ide. Me copié la forma de programarlo de algunos compañeros del foro. Solo me falta, en cuanto me lleguen los pics, a programarlo tal como me dejaste en el enlace para poder programarlo con el TE20 (es lo que imaginaba, poner las patas adecuadas en los pines correctos del programador). Te lo dejo para que lo veas:

Código: ASM
  1. __CONFIG _CP_OFF& _WDT_OFF&_PWRTE_ON&_BODEN_OFF&_INTRC_OSC_NOCLKOUT&_MCLRE_OFF 
  2.                
  3.         LIST    P=12F629
  4.         INCLUDE <P12F629.INC>
  5.        
  6.         errorlevel  -302
  7.        
  8.         CBLOCK 0x20
  9.         CONTADOR
  10.         CONTADOR_1
  11.         PDel0
  12.         PDel1
  13.         PDel2
  14.         PDel3
  15.         PDel4
  16.         REG_1
  17.         FLAG
  18.          ENDC
  19.  
  20.  
  21. #DEFINE LED_I GPIO,4
  22. #DEFINE LED_D GPIO,1
  23. #DEFINE PUL_I GPIO,5
  24. #DEFINE PUL_D GPIO,0
  25.        
  26.         ORG     h'0000'         ; VECTOR DE RESET
  27.         goto    INICIO          ; va a inicio
  28.         ORG     h'0004'         ; VECTOR DE INTERRUPCIONES
  29.  
  30.  
  31.  
  32.         ORG     H'0005'
  33. INICIO
  34.         clrf    GPIO
  35.         movlw   07h
  36.         movwf   CMCON           ; todos los pines en modo digital.
  37.         bsf     STATUS,5        ; activa banco 1
  38.         movlw   b'11101101'     ; GP0, 2, 3 y 5 entradas, GP1 y 4 salidas.
  39.         movwf   GPIO            ; puerto A todos entradas aunque este puerto no se va a usar
  40.         call    CALIBRAOSC
  41.         movwf   OSCCAL
  42.         clrf    INTCON          ; deshabilitar interrupciones.
  43.         bcf     STATUS,5
  44.         clrf    GPIO            ; volver al banco 0.           
  45.                                
  46.         clrf    CONTADOR
  47.         clrf    FLAG
  48.  
  49. ESPERA                          ; Leemos los pulsadores.
  50.         btfss   PUL_I           ; si está pulsado Izq. va a ANTIRREBOTES, si no
  51.         goto    $+3             ; va tres posiciones para adelante
  52.         call    ANTIRREBOTES    ; al volver de Antirrebotes se va a MAIN
  53.         goto    MAIN
  54.         btfss   PUL_D           ; si está pulsado va a ANTIRREBOTES, si no
  55.         goto    ESPERA          ; vuelve a leer los pulsadores.
  56.         call    ANTIRREBOTES    ; al volver de Antirrebotes se va a MAIN
  57.         goto    MAIN
  58.  
  59. TABLA                           ;esta tabla nos dirá que hay que hacer
  60.         addwf   PCL,1
  61.         goto    ESPERA          ; aquí nunca vendrá, pero por si acaso....
  62.         goto    DERECHA
  63.         goto    IZQUIERDA
  64.         goto    LOS_DOS
  65.  
  66.  
  67. MAIN
  68.         btfss   PUL_D           ; miramos si en PUL_D hay un 1 o un 0
  69.         bcf     REG_1,0         ; y escribimos en un registro lo que haya
  70.         btfsc   PUL_D           ; en el bit 0
  71.         bsf     REG_1,0
  72.         btfss   PUL_I           ; hacemos lo mismo con el otro pulsador
  73.         bcf     REG_1,1         ; éste lo escribimos en el bit 1
  74.         btfsc   PUL_I
  75.         bsf     REG_1,1         ; aquí ya tenemos los dos pulsadores leidos y anotados en un registro
  76.         movf    REG_1,0         ; lo movemos a W
  77.         call    TABLA
  78.         goto    ESPERA
  79.  
  80.  
  81. IZQUIERDA
  82.         btfsc   PUL_I           ; Aquí espera hasta que se suelte pulsador
  83.         goto    $-1             ; va una posición para atrás
  84.         clrf    CONTADOR
  85.         btfss   FLAG,0          ; miramos si hay un 1 en el Flag,0
  86.         goto    ACTIVAR_I       ; si no lo hay nos vamos a activar parpadeo Izq.
  87.        
  88.  
  89. DESACTIVAR_I   
  90.         bcf     FLAG,0
  91.         bcf     LED_I
  92.         clrf    CONTADOR
  93.         btfsc   PUL_I           ; espera hasta que se suelte pulsador
  94.         goto    $-1             ; porque si retornara sin esperar volvería a secuencia
  95.         return                  ; apaga flag e intermitente y vuelve a MAIN, FLAG estaba a 1
  96.  
  97.  
  98. ACTIVAR_I
  99.         bsf     FLAG,0          ; ponemos un 1 en el Flag,0
  100.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  101.         goto    DESACTIVAR_I    ; si mientras está ejecutando una secuencia
  102.                                 ; se pulsa un botón empieza de nuevo
  103.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  104.         goto    DERECHA         ; si lo estuviese nos vamos a encender Dcho.
  105.  
  106. ENCIENDE_I
  107.         bsf     LED_I           ; enciende intermitente Izq.
  108.         call    DEMORA          ; está un tiempo encendido
  109.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  110.         goto    DESACTIVAR_I    ; si mientras esta ejecutando una secuencia
  111.                                 ; se pulsa un botón empieza de nuevo
  112.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  113.         goto    IZQUIERDA       ; si lo estuviese nos vamos a encender Izq.
  114. ;       incf    CONTADOR_1,1   
  115. ;       movlw   .5              ; número de veces que se repite el retardo de 50ms
  116. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  117. ;       btfss   STATUS,Z        ; salta si el bit Z de Status es 1.
  118. ;       goto    ENCIENDE_I
  119.         clrf    CONTADOR_1      ; ponemos a 0 contador y nos vamos a apagar el led.
  120.  
  121. APAGA_I
  122.         bcf     LED_I           ; apaga el led Izq.
  123.         call    DEMORA          ; lo mantiene apagado 50ms.
  124.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  125.         goto    DESACTIVAR_I    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  126.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  127.         goto    IZQUIERDA       ; si lo está nos vamos a
  128.         incf    CONTADOR_1,1
  129.         movlw   .30             ; número de veces que se repite el retardo de 50ms
  130.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  131.         btfss   STATUS,Z
  132.         goto    APAGA_I
  133.         clrf    CONTADOR_1      ; ponemos a 0 contador
  134.        
  135.         incf    CONTADOR,1      ; para número de veces que encenderá
  136.         movlw   .10             ; le pongo 10 pero pueden ser las que tu quieras
  137.         subwf   CONTADOR,0
  138.         btfss   STATUS,Z        ; van 10 veces?
  139.         goto    ACTIVAR_I       ; no, vuelve a repetir secuencia
  140.         clrf    CONTADOR       
  141.         goto    DESACTIVAR_I
  142.  
  143. DERECHA
  144.         btfsc   PUL_D           ; Aquí espera hasta que se suelte pulsador
  145.         goto    $-1             ; va una posición para atrás
  146.         clrf    CONTADOR
  147.         btfss   FLAG,1
  148.         goto    ACTIVAR_D
  149.        
  150. DESACTIVAR_D   
  151.         bcf     FLAG,1          ; pone un 0 en el bit 1 de Flag.
  152.         bcf     LED_D           ; apaga led Dcho.
  153.         clrf    CONTADOR        ; pone a 0 el Contador.
  154.         btfsc   PUL_D           ; espera hasta que se suelte pulsador
  155.         goto    $-1             ; porque si retornara sin esperar volvería a secuencia
  156.         return                  ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
  157.  
  158. ACTIVAR_D
  159.         bsf     FLAG,1
  160.         btfsc   PUL_D           ; salta si no está pulsado el Dcho.
  161.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia
  162.                                 ; se pulsa un botón empieza de nuevo
  163.         btfsc   PUL_I           ; salta si no está pulsado el Izq.
  164.         goto    IZQUIERDA
  165.        
  166. ENCIENDE_D
  167.         bsf     LED_D           ; enciende intermitente Dcho.  
  168.         call    DEMORA          ; está un tiempo encendido
  169.         btfsc   PUL_D
  170.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  171.         btfsc   PUL_I
  172.         goto    IZQUIERDA
  173. ;       incf    CONTADOR_1,1
  174. ;       movlw   .50             ; número de veces que se repite el retardo de 50ms
  175. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  176. ;       btfss   STATUS,Z
  177. ;       goto    ENCIENDE_D
  178.         clrf    CONTADOR_1      ; ponemos a 0 contador
  179.  
  180. APAGA_D
  181.         bcf     LED_D           ; apaga
  182.         call    DEMORA
  183.         btfsc   PUL_D
  184.         goto    DESACTIVAR_D    ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  185.         btfsc   PUL_I
  186.         goto    IZQUIERDA
  187.         incf    CONTADOR_1,1
  188.         movlw   .30             ; número de veces que se repite el retardo de 50ms
  189.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  190.         btfss   STATUS,Z
  191.         goto    APAGA_D
  192.         clrf    CONTADOR_1      ; ponemos a 0 contador
  193.        
  194.         incf    CONTADOR,1      ; para número de veces que encenderá
  195.         movlw   .10             ; le pongo 10 pero pueden ser las que tu quieras
  196.         subwf   CONTADOR,0
  197.         btfss   STATUS,Z        ; van 10 veces?
  198.         goto    ACTIVAR_D       ; no, vuelve a repetir secuencia
  199.         clrf    CONTADOR
  200.         goto    DESACTIVAR_D
  201.  
  202.  
  203. LOS_DOS
  204.         btfsc   PUL_I
  205.         goto    $-1
  206.         btfsc   PUL_D           ; miramos si están sin pulsar ambos botones
  207.         goto    $-3
  208.         btfss   FLAG,2          ; flag para saber si apagamos o encendemos
  209.         goto    ACTIVAR_LOSDOS
  210.  
  211. DESACTIVAR_LOSDOS
  212.         btfsc   PUL_I
  213.         goto    $-1
  214.         btfsc   PUL_D           ; miramos si están sin pulsar ambos botones
  215.         goto    $-3    
  216.         bcf     FLAG,2          ;apagamos intermitentes y borramos flag, ya que estaba a 1
  217.         clrf    GPIO            ; apagamos intermitentes
  218.        
  219.         return
  220.  
  221. ACTIVAR_LOSDOS
  222.         bsf     FLAG,2          ; el flag estaba a 0 lo activamos
  223.         btfsc   PUL_I
  224.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  225.         btfsc   PUL_D
  226.         goto    DESACTIVAR_LOSDOS
  227.         movlw   0x18
  228.         movwf   GPIO            ; ponemos a 1 bits 3 y 4 del puerto B
  229.        
  230. ENCIENDE_LOSDOS
  231.         call    DEMORA          ; tiempo encendidos
  232.         btfsc   PUL_I
  233.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  234.         btfsc   PUL_D
  235.         goto    DESACTIVAR_LOSDOS
  236. ;       incf    CONTADOR_1,1
  237. ;       movlw   .50             ; número de veces que se repite el retardo de 50ms
  238. ;       subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  239. ;       btfss   STATUS,Z
  240. ;       goto    ENCIENDE_LOSDOS
  241.         clrf    CONTADOR_1      ; ponemos a 0 contador
  242.  
  243. APAGA_LOSDOS           
  244.         clrf    GPIO            ; lo hago así porque supongo que no tienes mas cosas coectadas en PORTB
  245.         call    DEMORA
  246.         btfsc   PUL_I
  247.         goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un botón empieza de nuevo
  248.         btfsc   PUL_D
  249.         goto    DESACTIVAR_LOSDOS
  250.         incf    CONTADOR_1,1
  251.         movlw   .30             ; número de veces que se repite el retardo de 50ms
  252.         subwf   CONTADOR_1,0    ; modificando este número se aumentará o reducirá en 50ms el tiempo
  253.         btfss   STATUS,Z
  254.         goto    APAGA_LOSDOS
  255.         clrf    CONTADOR_1      ; ponemos a 0 contador
  256.         goto    ACTIVAR_LOSDOS
  257.  
  258.  
  259.  
  260. ANTIRREBOTES                
  261.                                 ; 100ms, aparte de servir de antirrebotes, también compensará                         ; si no se pulsan exactamente al mismo tiempo los dos botones
  262.         movlw   .110            ; 1 set número de repetición  (B)
  263.        movwf    PDel2           ; 1 |
  264. PLoop3  movlw   .181            ; 1 set número de repetición  (A)
  265.         movwf   PDel3           ; 1 |
  266. PLoop4  
  267. ;       clrwdt                  ; 1 clear watchdog
  268. PDelL8  goto    PDelL9          ; 2 ciclos delay
  269. PDelL9  goto    PDelL10         ; 2 ciclos delay
  270. PDelL10  
  271.         decfsz  PDel3,1         ; 1 + (1) es el tiempo 0  ? (A)
  272.         goto    PLoop4          ; 2 no, loop
  273.         decfsz  PDel2,1         ; 1 + (1) es el tiempo 0  ? (B)
  274.         goto    PLoop3          ; 2 no, loop
  275. PDelL11  goto   PDelL12                 ; 2 ciclos delay
  276. PDelL12  
  277. ;       clrwdt                  ; 1 ciclo delay
  278.         return                  ; 2+2 Fin.
  279. ;-----------------------------------------------
  280.  
  281.  
  282.  
  283. DEMORA                          ; retardo de 50ms que se repetirá las veces que sea necesario
  284.                                 ; para completar el tiempo adecuado para las intermitencias
  285.         movlw   .55             ; 1 set número de repetición  (B)
  286.         movwf   PDel0           ; 1 |
  287. PLoop1  movlw   .181            ; 1 set número de repetición  (A)
  288.         movwf   PDel1           ; 1 |
  289. PLoop2  
  290. ;       clrwdt                  ; 1 clear watchdog
  291. ;        clrwdt                 ; 1 ciclo delay
  292.         decfsz  PDel1, 1        ; 1 + (1) es el tiempo 0  ? (A)
  293.         goto    PLoop2          ; 2 no, loop
  294.         decfsz  PDel0,  1       ; 1 + (1) es el tiempo 0  ? (B)
  295.         goto    PLoop1          ; 2 no, loop
  296.         return                  ; 2+2 Fin.
  297.        
  298.         org     0x3FF
  299.        
  300. CALIBRAOSC      retlw   0x80    ;calibro oscilador a 4 mhz +- 2%        
  301.        
  302.        
  303.         END

De nuevo, muchas gracias Tapi8.
Voy a ver si 'capto' el funcionamiento del timer.
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 15 de Diciembre de 2010, 06:59:01
Bueno lo que comentas de:

24.- ORG 0X00        ; VECTOR DE RESET
25.- goto INICIO     ; va a inicio
26.- ORG 0x04        ; VECTOR DE INTERRUPCIONES
.
.
30.- ORG 0X05
       INICIO

0x00 es donde el PIC empieza a hacer andar el programa es una direccion que el tiene ahi y es a donde va por hardware cuando se produce un reset por baja tension, watch dog, etc. Despues tiene la 0x04 que es otra posiscion, aqui es a donde va cuando se produce una interrupcion, y bien se hace ahi la rutina de interrupcion o bien mediante un goto se envia a la etiqueta donde esta ubicada la interrupcion, el objeto de ese goto inicio es para saltar ese vector de interrupcion y que vaya a 0x05 que empieza el programa.

Yo penesando que estaba haciendo los intermitentes de un vespino y resulta que nada menos que una HARLEY, QUE BUENO :-/ :-/

Es cierto que tenia unos fallos en los cambios de una intermitencia a la otra, y mas en el cambio de izquierda a derecha, los he corregido, o eso creo, prueba este:


Código: [Seleccionar]
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>

__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; oscilador XT

ERRORLEVEL -302

CBLOCK 0x0C

CONTADOR
CONTADOR_1
REG_1
PDel0
PDel1
PDel2
PDel3
 

 ENDC


#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1


ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCIONES



ORG 0X05
INICIO
bsf STATUS,5 ; activa la pagina 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas aunque este puerto no se va a usar
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidaS)
movlw 0X07 ; TIMER con preedcaler de 256, para 50ms
movwf OPTION_REG
movlw 0X20 ; habilitamos desborde de TIMER. pero sin interrupcion
movwf INTCON ; cada 50ms nos seteara el flag TOIF de INTCON
bcf STATUS,5 ; volvemos a la pagina 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
; todos los LEDs apagados

clrf CONTADOR
clrf CONTADOR
clrf REG_1






ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS


MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA

CAMBIA_I ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_D
call ANTIRREBOTES_1
btfss PUL_I ; comprueba que realmente se pulso
goto ENCIENDE_D ; falsa alarma va a donde estaba
btfsc PUL_D ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia


IZQUIERDA

btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto    ENCIENDE_I


DESACTIVAR_I

bcf     LED_I
clrf CONTADOR
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return            ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1



ENCIENDE_I
bsf    LED_I    ; enciende intermitente izquierda
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D  ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf    LED_I    ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ENCIENDE_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I


CAMBIA_D ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_I ;
call ANTIRREBOTES_1
btfss PUL_D ; comprueba que realmente se pulso
goto ENCIENDE_I ; falsa alarma va a donde estaba
btfsc PUL_I ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia


DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DESACTIVAR_D


bcf LED_D
clrf CONTADOR
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
return          ; apaga flag e intermitente y vuelve a MAIN; FLAG estaba a 1
 


ENCIENDE_D

bsf LED_D      ; enciende intermitente
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D      ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z    ; van 10 veces?
goto ENCIENDE_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D


LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
clrf CONTADOR_1
bcf INTCON,2
goto    ENCIENDE_LOSDOS


DESACTIVAR_LOSDOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
clrf PORTB    ; apagamos intermitentes
return


ENCIENDE_LOSDOS

movlw  0x18
movwf PORTB  ; ponemos a 1 bits 3 y 4 del puerto B
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_I
goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf    PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc  PUL_I
goto  DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto    ENCIENDE_LOSDOS


ANTIRREBOTES               ;

DEMORA  movlw     .110      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 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  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


ANTIRREBOTES_1 ; antirrebotes de 20ms solo cuando esta funcionando un
; y se cambia para el otro, sin pasar por MAIN
movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        decfsz    PDel3,1   ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,1   ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


END

La duda que tenia con el 16f629 era la calibracion, pero ya he visto como va, en el datashheet en ingles no estaba totalmente seguro pero si ya es asi, listo.
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 17 de Diciembre de 2010, 13:59:53
Hola de nuevo, Tapi8.

Llevo unos días probando y modificando/quitando los tiempos de antirrebotes, añadiendo alguna línea para ver si consigo mejorar la respuesta al cambio de un pulsador al otro mientras parpadea.

Te cuento el fallo que le veo, que en última instancia paso del cambio mientras parpadea, es éste: mientras entá parpadeando cualquiera de los dos si hago el cambio al que está apagado, a veces (75%) no lo hace, se quedan ambos apagados; en esos casos (cuando he intentado pasar de uno al otro sin terminar el ciclo del que parpadeaba), para que arranque el que quería que funcionara he de pulsar 2, 3 o 4 veces porque no arranca. Sin embargo como va bien casi al 100% es apagando el que parpadea y arrancando el otro; digo 'casi' porque en un porcentaje muy pequeño no arranca y he de pulsar varias veces.

He revisado el programa y lo veo perfecto. Las llamadas a los cambios de intermitentes o a los apagados y todo parece estar bien. La parte que no domino nada es la de los timer's. No sé si alguno se queda funcionando al cambiar de intermitente y arranca otro y ahí se produce el bloqueo. O igual es mi pic que lleva tropecientos mil borrados y regrabados. Por aquí tengo también un PIC16F628A, que no sé si ponerme con él o esperar a que me lleguen los 12F629 para trabajar con los definitivos.

De todas formas como te digo, podría pasar del tema de los cambios directos del uno al otro y pasar a apagar uno y arrancar el otro. Es cuestión de acostumbrarse, y tampoco me suelo equivocar tanto cuando voy circulando.

Me alegro que te mole mi hierro, la tengo hace 15 años y está como nueva. En cuanto tenga todo listo haré unas fotos y las colgaré con un mini tutorial del montaje e instalación en el foro de motos en el que también participo para compartirlo con los compañeros. Te dejaré un enlace para que tú también lo veas. Y si puedo colgaré un video con el antes y después de la transformación. Pero eso tardará un poco, ya que no dispongo de local para trabajar con tiempo; he de hacerlo todo en el día y en la calle. Es lo que mas me cuesta.

Bueno, sigo con las pruebas. Gracias de nuevo por tu interés.

Un saludo.
Título: Re: Intermitentes moto.
Publicado por: juan47 en 17 de Diciembre de 2010, 15:18:57
Hola
Yo, como Tapi8, tambien pensaba que seria para un ciclomotor, no para tanbuen hierro  :-/
e intervine por que mi hijo tiene un ciclomotor y asi poder tambien montarselo   :oops:
Bueno al tema, no he tenido mucho tiempo para poder estar pendiente, y Tapi8 ha efectuado un trabajo genial
aunque en tu ultimo post comentas que la respuesta no es lo que esperabas
Pongo un codigo que he escrito pero no he podido probarlo fisicamente pues la falta de tiempo y el no poder concentrarse
me ha sido imposible construirlo. Pero si lo he provado con un proteus de un amigo y el funcionamiento es el correcto
pero para pasar de un led a otro es obvio que hay que pulsar dos veces el pulsador
uno para apagar el que ya esta encendido y otra para encender el que deseamos

Código: ASM
  1. LIST                    P=16F84A
  2.                                        
  3. W       EQU                     0x00
  4. F       EQU                     0x01
  5. TMR0    EQU                     0x01
  6. ESTADO  EQU                     0x03
  7. RP0     EQU                     0x05
  8. INTCON  EQU                     0x0B
  9. TOIF    EQU                     0x02
  10. GIE     EQU                     0x07
  11. RBIE    EQU                     0x03
  12. RBIF    EQU                     0x00
  13. PUERTAA EQU                     0x05
  14. PUERTAB EQU                     0x06
  15. OPTIO   EQU                     0X81
  16. TRISA   EQU                     0x85
  17. TRISB   EQU                     0x86
  18. REG_1   EQU                     0x0C
  19. REG_2   EQU                     0x0D
  20. CONT_1  EQU                     0x0E
  21. CONT_2  EQU                     0x0F
  22.  
  23.                                                 org             0x00                    ;Vector de inicio
  24.                                                 GOTO    INICIO                          ;Va a la etiqueta inicio                                               
  25.                                                 org             0x04                    ;Vector de interrupcion
  26.                                                 CALL    INT                             ;Llama a la subrutina de interrupcion
  27.                                                
  28.                                                 org             0x05
  29.  
  30.                                                
  31. INICIO                  bsf             INTCON,GIE                                      ;Permiso general de interrupciones
  32.                                 bsf             INTCON,RBIE                                     ;Permiso de interrupcion porRB4-RB7
  33.                                 bsf             ESTADO,RP0                                      ;Pasa al banco 1
  34.                                 movlw   b'10000111'                                     ;Preescaler para TMR0
  35.                                 movwf   OPTIO                                          
  36.                                 movlw   b'01100000'                                     ;RB6,RB5 entradas, resto salidas                               
  37.                                 movwf   TRISB
  38.                                 bcf             ESTADO,RP0                                      ;Pasa al banco 0
  39. DUERME                  clrf    PUERTAB                                         ;Pone a cero el puerto B
  40.                                 clrf    REG_1                                           ;Pone a cero el registro REG_1
  41.                                 sleep                                                           ;Duerme
  42.  
  43.                                
  44. INT                             btfsc   REG_1,1                                         ;¿Es cero el bit 1?
  45.                                 goto    DUERME                                          ;No.Resetea el registro REG_1
  46.                                 btfsc   REG_1,2                                         ;¿Es cero el bit 2?
  47.                                 goto    DUERME                                          ;No.Resetea el registro REG_1
  48.                                 goto    PRUEBA                                          ;Si
  49.                                                        
  50. PRUEBA                  bcf             INTCON,RBIF                                     ;Pone a 0 el flag de RB4-RB7
  51.                                 bsf             INTCON,GIE                                      ;Pone a 1 el permiso general de interrupcion
  52.                                 swapf   PUERTAB,F                                       ;Intercambio de los bits de mayor peso por los de menor peso
  53.                                 movf    PUERTAB,W                                       ;Efectua una mascara
  54.                                 andlw   b'00000110'                                     ;para borrar los bits de mas peso
  55.                                 subwf   REG_1,F                                         ;pasando al final al registro REG_1
  56.                                 movwf   REG_1
  57.  
  58. INTERMITENCIA   movlw   d'9'                                            ;Seran 9 las veces
  59.                                 movwf   CONT_2                                          ;que parpadee el led
  60. INTER                   movf    REG_1,W                                         ;Movemos los bits del regitro a W
  61.                                 movwf   PUERTAB                                         ;Movemos los bits de W al puerto B
  62.                                 call    ANTIRREBOTES                            ;Se llama al retardo
  63.                                 clrf    PUERTAB                                         ;Borramos el puerto B
  64.                                 call    ANTIRREBOTES                            ;Se llama al retardo
  65.                                 decfsz  CONT_2,F                                        ;Decrementamos el registro ¿y es 0?
  66.                                 call    INTER                                           ;No
  67.                                 goto    DUERME                                          ;Si.A dormir
  68.                                
  69.  
  70. ANTIRREBOTES    movlw   d'15'                                           ;Bucle externo que se repetira 15 veces
  71.                                 movwf   CONT_1
  72. BUCLE1                  movlw   0x00                                            ; Inicializacion del bucle interno
  73.                                 movwf   TMR0
  74. BUCLE2                  btfss   INTCON,TOIF                                     ;Ha terminado de contar?
  75.                                 goto    BUCLE2                                          ;No.Continua el bucle interno
  76.                                 bcf             INTCON,TOIF                                     ;Si.Baja bandera
  77.                                 decfsz  CONT_1,F                                        ;decrementar contador del bucle externo
  78.                                 goto    BUCLE1                                          ;Como no llega a 0, vlver a hacer el bucle interno
  79.                                 return                                                          ;Al llegar a 0 el contador externo volver a la rutina
  80.  
  81.  
  82.                                 END
Un saludo
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 17 de Diciembre de 2010, 15:33:26
Lo del video y las fotos molaria muchisimo, yo no ando en moto me acojonan mucho, pero soy un gran aficionado al motociclismo, pero verlo solamente, pero si alguna vez anduviera en una seria una Harley, me dan confianza.

Eso que te pasa es con este ultimo que te puse?, Poruqe si tenia unos fallos que le he corregido, con este que esta antes de tu ultimo post, he hecho muchas pruebas en MPLAB y no me falla nunca.

Puede que haya un problema con los rebotes al soltar el pulsador, porque no lo he contemplado y seguramente haya tantos rebotes al soltar como al pulsar, pero el porcentaje de fallos no deberia ser tan alto, o eso creo.

Lo solucionaremos no te preocupes, el fin de semana te cuelgo otro con los antirrebotes al soltar y vemos que pasa.
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 17 de Diciembre de 2010, 19:25:18
Hola.
   Tapi8: gracias, la verdad que sí es una buena máquina, y mas allá de la calidad del acabado, lo que mas me engancha son las vibraciones que transmite, es realmente difícil de explicar. Sobre todo la mía que es de carburación y con el motor anclado directamente al chasis, los pistonazos los sientes físicamente en el cuerpo, esto se ha perdido un poco con las leyes anticontaminación que ha obligado a H-D usar la inyección. No sé, es algo que hay que probar. Antes de ésta tenía una Kawa 900 y no tiene nada que ver. Es lo que tu dices: dan confianza, los coches te respetan un poco más por el sonido y lo que imponen 350 kg.
No te preocupes que cuando suba el montaje lo posteo.

   El tema: este funcionamiento errático al cambiar de un intermitente al otro sin que se haya detenido el parpadeo es mas o menos igual en todos lo programas, hay veces que está funcionando bien durante los primeros 3 o 4 cambios y después es como si entrara en conflicto algo que bloquea el pulsador último al que quería ir y hasta que no le doy unas 4 veces no recupera el funcionamiento normal. Pero como te dije, puedo pasar y hacer los cambios cancelando el parpadeo del que está en marcha antes de ir al otro.

   Juan47: normalmente (por lo menos en mi ex-Kawa) los intermitentes los controlaba con la mano izquierda. Tenía un conmutador de 3 posiciones izq/centro/der has de asegurarte que cables llegan y si envían 12v o masa. en cuyo caso a las entradas del pic le pueden llegar tensión o masa cuando lo pulses. No creo que te haga falta el cambio directo de un intermitente al otro porque siempre pasa por el centro. En mi caso tengo un pulsador en cada puño y envía 12v al pulsarlo a una 'unidad de intermitencias' que es la que se encarga de lanzar los +12v del parpadeo a cada pareja de intermitentes. Además, y como curiosidad, esta unidad tiene una entrada que viene del ctakm y que por lo visto mientras la rueda gire está recibiendo pulsos, mas rápidos cuanto más rápido vaya, y entonces la 'unidad de intermitencias' regula el tiempo que está parpadeando: si estoy parado (no hay pulsos) nunca deja de parpadear, por ejemplo en una caravana intentando tomar una salida; y cuanto mas rápido voy menos dura el tiempo que está parpadeando (dentro de un límite, claro, nunca es muy corto, por lo menos 7 u 8 da). Pero yo he estimado que entre 9 y 12 parpadeos está mas que bien y evito liar el tema y que sea mas susceptible de dar errores.
No te preocupes que voy a probar también tu programa a ver que tal.
Como le dije a Tapi8, igual mi pobre 16F84A está hasta el gorro de mí y está pidiendo clemencia.
En cuanto lo pruebe y haga las modificaciones si algo no rula bien, te digo algo.

Solo comentar que las pruebas las hago con una plaquita con el pic, el cuarzo con 2 cond., el regulador para 5v, etc, como en el esquema que puse mas arriba, y lo alimento con una pila de 9v, porque montar la fuente del PC para sacar los +12v. es mucho mas engorroso para mí, que reprogramo cada 5-10 minutos. No creo que falle por ello. No sé....me he quedado con la duda.

Bueno, de nuevo gracias a todos. Me alegra que el tema vaya gustando a los compañeros. La verdad que los leds tienen muchas ventajas, sobre todo fiabilidad, bajo consumo, y potencia (en mi caso).
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 20 de Diciembre de 2010, 07:51:35
Bueno pensaba poner el programa el fin de semana pero no tuve tiempo. Le he corregido alguna cosilla y sobre todo le he puesto antirrebotes para cuando se sueltan los pulsadores, te digo como va:
Cuando esta funcionando uno de los dos y se pulsa el contrario, en ese momento deja de funcionar el que estaba funcionando y AL SOLTAR EL PULSADOR, empieza a funcionar el contrario, el resto es igual que hasta ahora, cuando se pulsa uno de los dos o los dos a la vez hace la secuencia seleccionada al soltar el pulsador o los pulsadores.
Cuando estan los dos intermitentes puestos, basta con pulsar uno de los dos y al soltar apagan.
He probado muchisimas veces en el MPLAB y no falla nunca pero en la realidad a ver que pasa....
Ya tengo algun amigo por aqui motero que le pica la curiosidad por ver este invento. :lol: :lol:



Código: [Seleccionar]
LIST P=16F84A, ; usar PIC 16F84A
#include <p16f84A.inc>

__CONFIG _CP_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC ; code protec off
; power up timer on
; watchdog off
; oscilador XT

ERRORLEVEL -302

CBLOCK 0x20 ; ponemos 0x20 para que valga para todos
; incluido 12f629
CONTADOR
CONTADOR_1
REG_1
PDel0
PDel1
PDel2
PDel3
 

 ENDC


#DEFINE LED_I PORTB,3
#DEFINE LED_D PORTB,4
#DEFINE PUL_I PORTA,2
#DEFINE PUL_D PORTA,1


ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCION


INICIO
bsf STATUS,5 ; activa la pagina 1
movlw 0XFF ; carga FF en W
movwf TRISA ; puerto A todos entradas
movlw 0X00 ; carga 00000000 en W
movwf TRISB ; mueve W a puerto B (todos salidaS)
movlw 0X07 ; TIMER con preedcaler de 256, para 50ms
movwf OPTION_REG
movlw 0X20 ; habilitamos desborde de TIMER. pero sin interrupcion
movwf INTCON ; cada 50ms nos seteara el flag TOIF de INTCON
bcf STATUS,5 ; volvemos a la pagina 0
clrf PORTB ; ponemos a cero el puerto B para empezar con
;  los intermitentes apagados

clrf CONTADOR
clrf CONTADOR_1
clrf REG_1


ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS

MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA

CAMBIA_I ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_D
call ANTIRREBOTES_1
btfss PUL_I ; comprueba que realmente se pulso
goto ENCIENDE_D ; falsa alarma va a donde estaba
btfsc PUL_I ; se espera hasta que se suelte
goto $-1
call ANTIRREBOTES_1 ; llama antirrebotes para confirmar
btfsc PUL_I ; se mira si de verdad se solto
return ; paso algo raro vuelve a MAIN
btfsc PUL_D ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_I


IZQUIERDA

btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
call ANTIRREBOTES_1 ; para comprobar si hay rebotes al soltar
btfsc PUL_I ; se confirma que se solto pulsador
return ; falsa alarma va a MAIN
bcf INTCON,2 ; se solto y no hay rebotes
clrf CONTADOR ; pone contadores a 0 e inicia secuencia
clrf CONTADOR_1
goto    ENCIENDE_I


DESACTIVAR_I

bcf     LED_I
clrf CONTADOR
clrf CONTADOR_1
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
call ANTIRREBOTES_1
btfsc PUL_I ; despues de antirrebotes confirma se solto
goto $-4 ; fueron rebotes va a primer chequeo
return            ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1

ENCIENDE_I

bsf    LED_I    ; enciende intermitente izquierda
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D  ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf    LED_I    ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ENCIENDE_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I

CAMBIA_D ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_I ;
call ANTIRREBOTES_1
btfss PUL_D ; comprueba que realmente se pulso
goto ENCIENDE_I ; falsa alarma va a donde estaba
btfsc PUL_D ; se espera hasta que se suelte
goto $-1
call ANTIRREBOTES_1 ; llama antirrebotes para confirmar
btfsc PUL_D ; se mira si de verdad se solto
return ; paso algo raro vuelve a MAIN
btfsc PUL_I ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
call ANTIRREBOTES_1 ; para comprobar si hay rebotes al soltar
btfsc PUL_D ; se confirma que se solto pulsador
return ; falsa alarma va a MAIN
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DESACTIVAR_D

bcf LED_D
clrf CONTADOR
clrf CONTADOR_1
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
call ANTIRREBOTES_1
btfsc PUL_D ; despues de antirrebotes confirma se solto
goto $-4 ; fueron rebotes va a primer chequeo
return          ; apaga intermitente y vuelve a MAIN
 
ENCIENDE_D

bsf LED_D      ; enciende intermitente
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D      ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z    ; van 10 veces?
goto ENCIENDE_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D

LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
call ANTIRREBOTES_1
movf PORTA,0 ; movemos PORTA a W para comprobar que vale 0
btfss STATUS,Z ; encendio FLAG de 0?
goto LOS_DOS ; fueron rebotes vuelve a comprobar despulsacion
clrf CONTADOR
clrf CONTADOR_1
bcf INTCON,2
goto    ENCIENDE_LOSDOS

DESACTIVAR_LOSDOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
call ANTIRREBOTES_1
movf PORTA,0 ; para confirmar que se soltaron
btfss STATUS,Z ; comprobamos que el valor de PORTA es 0, no pulsados
goto ENCIENDE_LOSDOS ; no se soltaron, vuelve a encender los dos
clrf PORTB    ; apagamos intermitentes
clrf CONTADOR
clrf CONTADOR_1
return

ENCIENDE_LOSDOS

bcf INTCON,2
movlw  0x18
movwf PORTB  ; ponemos a 1 bits 3 y 4 del puerto B
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_I
goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf    PORTB  ; lo hago asi porque supongo que no tienes mas cosas coectadas en PORTB
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc  PUL_I
goto  DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto    ENCIENDE_LOSDOS


ANTIRREBOTES               ;

DEMORA  movlw     .110      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 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  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


ANTIRREBOTES_1 ; antirrebotes de 20ms solo cuando esta funcionando uno
; y se cambia para el otro, sin pasar por MAIN
movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        decfsz    PDel3,1   ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,1   ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


END
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 20 de Diciembre de 2010, 10:39:25
Hola Tapi8.

Me pasé el finde con los programas de Juan47 y el tuyo.
.-El de Juan no conseguí hacerlo funcionar intentando adecuar los pulsadores y los leds a las salidas donde tenía montado mi circuito, ya que los tengo en una plaquita soldado, no en una protoboard que supongo que es mas fácil cambiar la configuración de entradas/salidas.
.- El tuyo eliminando las partes que llamaban a cambia_i y cambia_d, sí iba bastante bien aunque a veces se quedaba pillado y no quería parpadear a la primera pulsación.

Acabo de probar el que me acabas de dejar hoy, y con un cambio va perfecto al 100%  :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/
responde a la primera, los cambios sin titubeos y las luces de emergencia, tras el 'arreglo' también van estupendamente.

Te explico el fallo (quizás mas que fallo fue un lapsus): al probarlo todo iba bien salvo las luces de emergenca (los 4 intermitentes a la vez) que no arrancaban. Comparé con el que me dejaste el día 15 y ví las líneas que añadiste. Les puse el ';' delante para saltarlas e iba bien, salvo que cuando pulsaba un botón para que saliera del estado de emergencia, según el botón con que lo hiciese ahí se iba a parpadear.
Pues dándole vueltas, probé a cambiar las dos líneas en las subrutinas 'LOS_DOS' y 'DESACTIVAR_LOSDOS' que dicen: btfss   STATUS,Z por btfsc  STATUS,Z   y ya va de PM.

Por tanto esto se queda finiquitado. Por cierto cabrá en el 12F629???

Tapi8 estás hecho un gurú de los micropics. Has dado en la diana sin ver los fallos, me quito la gorra..(http://www.en.kolobok.us/smiles/light_skin/hi.gif)
(http://www.en.kolobok.us/smiles/icq/drinks.gif)
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 21 de Diciembre de 2010, 13:39:56
Si fuera un guru hubiera funcionado a la primera :lol: :lol: La verdad es que a la primera nunca me funciono ninguno.

Le he estado dando vueltas a las luces de emegencia, porque en el MPLAB me van perfectas asi como las puse, y llego a la conclusion de que el primer antirrebotes el de 100ms es demasiado corto, por lo que ya te explique en otras ocasiones, a lo mejor es obsesion mia, porque soy torpe para esas cosas, pero apretar dos botones al mismo tiempo y que nunca haya una diferencia entre ambas pulsaciones de 100ms, yo estoy seguro que no lo haria, de 10 veces es posible que lo haga bien 3 o 4 pero el resto encenderia el de un lado o el del otro. He tratado de probar esto en el MPLAB y al hacer las dos pulsaciones con una diferencia de 100ms, se va a un lado y en cuanto enciende ese lado como el otro esta pulsado cambia y se hace de la picha un lio  :lol:.
Para solucionar esto te propongo o bien aumentar ese retardo a 300 o 400 o incluso 500ms, o si quieres hacemos que los 4 intermitentes enciandan pulsando un pulsador solo, el que mas te guste, durante un poco mas de tiempo, que porejemplo hasta 1.5s encienda ese intermitente y con una por encima de ese tiempo enciendan lo 4.

En cuanto a si el programa coge en el 16f629 no hay problema tiene 1KWORD (1024) de memoria de programa igual que el 16f84 y el programa aun con las ultimas modificaciones tiene 269 instrucciones, esto lo puedes mirar en el MPLAB vas a view, y en el desplegable te aparece Memory usage gauge la tercera del final pulsas y ya te dice lo que ocupa el programa.
Para que bajes si quieres el datasheet del 16f629, asi os vais conociendo :lol:

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010113

Has comprobado si se te calienta algo en el circuito? sobre todo los transistores y el 7805, teniendolo tiempo encendido y puteandolo un poco, le pones de encendido en vez de 50ms, 4 min. por ejemplo. Eso lo haces variando ese 1 que hay en el encendido de las tres secuencias y si tienes a mano un tester mide que tension te cae entre emisor-colector cuando conduce, no deberia pasar de 2V, lo ideal es que este sobre 1.2V o 1.5V. y mira si el 7805 se calienta despues de estar tiempo trabajando, no deberia ya que el consumo del pic es bajo pero se jala 4v ahora y despues en la moto se va a comer 7V. Si hubiera problemas con el, los hay mejores, pero si con ese va bien, pues listo.

Bueno todavia no te felicito las fiestas porque hablaremos antes de navidad.  :lol:
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 21 de Diciembre de 2010, 16:40:53
Vale, un gurú no....un crack.  :)
Pues tal como está va perfecto al 100%. No pienso tocar nada del antirrebotes  :D
Desde luego, en modo emergencia, lo he tenido un par de minutos en marcha, alimentando desde 9v., y todo está completamente frío. Lo veo lógico, porque el tiempo que está encendido es 50ms cada casi 2 segundos, el transistor soporta 4A cuando lo previsto es un consumo de 1.4A (700mA x 2) en modo pulsante (50ms cada casi 2 segundos). Por ese lado estoy bastante tranquilo.
Puedo probar a que se quede encendido mas tiempo para ver como se comporta el transistor, porque el regulador solo alimenta al PIC, y con el 7805 de 1A va mas que sobrado. El regulador soporta voltajes de entrada hasta 35v.
Veré con el tester que caida hay en el transistor (solo tengo un lado puesto con opto, transistor, driver y led de alta potencia, en el izquierdo tengo una resistencia y un led de toda la vida).
 Seguimos en contacto....
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 22 de Diciembre de 2010, 08:49:11
Citar
Si pulso ambos botones durante 1 segundo (o al mismo tiempo) parpadean los 4 indicadores sin fin (estado emergencia o avería) hasta que pulso los dos de nuevo.

Esto lo ponias tu en el primer post, los de Harley tambien ponen una temporizacion grande para distinguir entre pulsaciones.
Si a ti te gusta asi, listo la moto es tuya  :lol: :lol:
Si dentro de unos meses, andando ves que te falla esto ya sabes que el problema se soluciona asi, dandole un tiempo mas grande a antirrebotes, o si haces un circuito para un amigo que no sea tan rapido y preciso como tu  :lol: :lol:

Bueno felices fiestas por si ya no hablamos en una temporada.
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 22 de Diciembre de 2010, 10:38:23
Jejeje, rápido yo?  :D  en general nos gusta el sosiego y la tranquilidad. Pero como va tan bien no quiero de momento tocar nada hasta que lo instale y pruebe 'in situ'.
Efectivamente lo que puse en el primer post era eso porque es lo que recuerdo. Gracias a Dios las luces de emergencia las habré puesto desde que tengo la moto: por necesidad 0 veces, y por tonterías de salir en manada y hacer los burros por ahí unas 10 o 12 veces, la última hará 2 o 3 años. Es por lo que no recuerdo bien. Se que pulso los dos y -creo- que hay que tenerlos un momento pulsados.

Las motos que saca HD últimamente ya vienen muchos modelos con leds. En los intermitentes tienen las luces freno y posición incorporadas. Y las que no los traen ahí (la gama touring, como los policías americanos) traen mucha mas electrónica por el tema de la inyección. Esto que me quiero hacer yo servirá para las de 6 o 7 años para atrás. Que por cierto hay muchas y además muy bien cotizadas por tener carburador.

Desde luego, cuando haga el tuto, si algún compañero se anima estaré encantado de ayudarlo en lo que yo pueda. Me parece una mejora importante en el aspecto de consumo, fiabilidad y seguridad. Y quiero que se quede bien de forma que pueda pasar la ITV sin que se den cuenta, porque si lo hacen me obligan a desmontar y poner lo de siempre.

Bueno, yo también te deseo que lo pases muy bien con los tuyos, y que sigamos en contacto. Y a todos los compañeros de este foro que nos leen, también les felicito la Navidad.
Un abrazo.

Asencio
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 30 de Diciembre de 2010, 20:58:18
Bueno, primero de todo felicitaros la Navidad a todos.

Ya he recibido los pics 12F629, he modificado (como Dios me dió a entender) el programa ultimo que me funcionaba prefecto al 100% sobre el 16F84A y no furula nada. En esencia he cambiado las los puertos de entrada y salida de acuerdo al nuevo patillaje. Tengo mis dudas sobre como adaptar lo de PortA y PortB al este pic, porque no es lo mismo borrar portA que borrar las entradas de este pic.

Bueno, no me enrrollo mas, te dejo lo que yo he hecho a ver si ves alguna burrada y por eso no tira.
Por cierto, lo he grabado con el TE20. Le he soldado a las patillas 1, 4, 6, 7 y 8 unos hilos con el extremo limpio de una patilla de led y los he pinchado en su equivalente del zócalo del TE20. Lo detecta, borra y programa OK. Gracias por el enlace.

Yo sigo investigando, el problema es que cada vez que programo y pruebo me pego 10 minutos colocando las patillas. No es como con el 16F84A que era pinchar y despinchar en 0.5 segundos.

Ahí va:

Código: ASM
  1. __CONFIG        _CP_OFF& _WDT_ON&_PWRTE_OFF&_BODEN_OFF&_INTRC_OSC_NOCLKOUT&_MCLRE_OFF  
  2.                
  3.         LIST    P=12F629
  4.         #INCLUDE        <P12F629.INC>                                  
  5.        
  6.         ERRORLEVEL      -302
  7.  
  8.         CBLOCK 0x20                     ; ponemos 0x20 para que valga para todos
  9.                                         ; incluido 12f629
  10.         CONTADOR
  11.         CONTADOR_1
  12.         REG_1  
  13.         PDel0
  14.         PDel1
  15.         PDel2
  16.         PDel3
  17.         ENDC
  18.  
  19.  
  20.         #DEFINE LED_I GPIO,1
  21.         #DEFINE LED_D GPIO,0
  22.         #DEFINE PUL_I GPIO,4
  23.         #DEFINE PUL_D GPIO,5
  24.  
  25.  
  26.         ORG     h'0000'                 ; VECTOR DE RESET
  27.         goto    INICIO                  ; va a inicio
  28.         ORG     h'0004'                 ; VECTOR DE INTERRUPCIONES
  29.        
  30.        
  31.        
  32.  
  33. INICIO
  34.         clrf    GPIO
  35.         movlw   07h
  36.         movwf   CMCON                   ; todos los pines en modo digital.
  37.         bsf     STATUS,5                ; activa la página 1
  38.         movlw   b'111100'               ; GP0 y 1 salidas 2, 3, 4 y 5 entradas.
  39.         movwf   TRISIO                 
  40.         call    CALIBRAOSC
  41.         movwf   OSCCAL
  42.         clrf    INTCON                  ; deshabilitar interrupciones.
  43.         movlw   0X07                    ; TIMER con prescaler de 256, para 50ms
  44.         movwf   OPTION_REG
  45.         movlw   0X20                    ; habilitamos desborde de TIMER pero sin interrupción
  46.         movwf   INTCON                  ; cada 50ms nos seteara el flag TOIF de INTCON
  47.         bcf     STATUS,5                ; volvemos a la página 0
  48.         clrf    GP0                     ; apagamos led D
  49.         clrf    GP1                     ; y el led I           
  50.                        
  51.  
  52.         clrf    CONTADOR
  53.         clrf    CONTADOR_1
  54.         clrf    REG_1
  55.        
  56.  
  57. ESPERA
  58.         btfss   PUL_I  
  59.         goto    $+3                     ; va tres posiciones para adelante
  60.         call    ANTIRREBOTES
  61.         goto    MAIN
  62.         btfss   PUL_D
  63.         goto    ESPERA
  64.         call    ANTIRREBOTES
  65.         goto    MAIN
  66.  
  67. TABLA                                   ; esta tabla nos dirá que hay que hacer
  68.         addwf   PCL,1
  69.         goto    ESPERA                  ; aquí nunca vendrá, pero por si acaso....
  70.         goto    DERECHA
  71.         goto    IZQUIERDA
  72.         goto    LOS_DOS
  73.  
  74. MAIN
  75.         btfss   PUL_D                   ; miramos si en PUL_D hay un 1 o un 0
  76.         bcf     REG_1,0                 ; y escribimos en un registro lo que haya
  77.         btfsc   PUL_D                   ; en el bit 0
  78.         bsf     REG_1,0
  79.         btfss   PUL_I                   ; hacemos lo mismo con el otro pulsador
  80.         bcf     REG_1,1                 ; éste lo escribimos en el bit 1
  81.         btfsc   PUL_I
  82.         bsf     REG_1,1                 ; aquí ya tenemos los dos pulsadores leidos y anotados en un registro
  83.         movf    REG_1,0                 ; lo movemos a W
  84.         call    TABLA
  85.         goto    ESPERA
  86.  
  87. CAMBIA_I                                ; esta rutina se ejecutará solo cuando cambie de un intermitente al otro
  88.                                         ; y hará un antirrebotes de 20ms para asegurarse de que no fue un rebote
  89.         bcf     LED_D                                  
  90.         call    ANTIRREBOTES_1
  91.         btfss   PUL_I                   ; comprueba que realmente se pulsó
  92.         goto    ENCIENDE_D              ; falsa alarma va a donde estaba
  93.         btfsc   PUL_I                   ; se espera hasta que se suelte
  94.         goto    $-1
  95.         call    ANTIRREBOTES_1          ; llama antirrebotes para confirmar
  96.         btfsc   PUL_I                   ; se mira si de verdad se soltó
  97.         return                          ; pasó algo raro vuelve a MAIN
  98.         btfsc   PUL_D                   ; y que el otro botón esta desactivado
  99.         return                          ; se pulsaron los dos va a main a iniciar secuencia
  100.         bcf     INTCON,2
  101.         clrf    CONTADOR
  102.         clrf    CONTADOR_1
  103.         goto    ENCIENDE_I
  104.  
  105.  
  106. IZQUIERDA
  107.         btfsc   PUL_I                   ; Aquí espera hasta que se suelte pulsador
  108.         goto    $-1                     ; va una posición para atrás
  109.         call    ANTIRREBOTES_1          ; para comprobar si hay rebotes al soltar
  110.         btfsc   PUL_I                   ; se confirma que se soltó pulsador
  111.         return                          ; falsa alarma va a MAIN
  112.         bcf     INTCON,2                ; se soltó y no hay rebotes
  113.         clrf    CONTADOR                ; pone contadores a 0 e inicia secuencia
  114.         clrf    CONTADOR_1
  115.         goto    ENCIENDE_I
  116.        
  117.  
  118. DESACTIVAR_I
  119.         bcf     LED_I
  120.         clrf    CONTADOR
  121.         clrf    CONTADOR_1
  122.         btfsc   PUL_I                   ; espera hasta que se suelte pulsador
  123.         goto    $-1                     ; porque si retornara sin esperar volvería a secuencia
  124.         call    ANTIRREBOTES_1
  125.         btfsc   PUL_I                   ; después de antirrebotes confirma se soltó
  126.         goto    $-4                     ; fueron rebotes va a primer chequeo
  127.         return                          ; apaga flag e intermitente y vuelve a MAIN, FLAG estaba a 1
  128.  
  129. ENCIENDE_I
  130.         bsf     LED_I                   ; enciende intermitente izquierda
  131.         movlw   .61                     ; cargamos TIMER0 con 61 para que nos cuente 50ms
  132.         movwf   TMR0                    ; porque si empezara de 0 contaría 65536
  133.        
  134.         btfsc   PUL_D
  135.         goto    CAMBIA_D                ; si mientras esta ejecutando una secuencia
  136.                                         ; se pulsa un botón empieza de nuevo
  137.         btfsc   PUL_I
  138.         goto    DESACTIVAR_I
  139.         btfss   INTCON,2                ; pasaron 50ms? se desbordó TIMER?
  140.         goto    $-5                     ; no seguimos esperando y chequeando pulsadores
  141.         bcf     INTCON,2                ; se desbordó, borramos flag para la próxima vez
  142.         incf    CONTADOR_1,1
  143.         movlw   .1                      ; número de veces que se repite el retardo de 50ms
  144.         subwf   CONTADOR_1,0            ; modificando este número aumentará o reducirá en 50ms el tiempo
  145.         btfss   STATUS,Z
  146.         goto    ENCIENDE_I
  147.         clrf    CONTADOR_1              ; ponemos a 0 contador
  148.  
  149. APAGA_I
  150.         bcf     LED_I                   ; apaga
  151.         movlw   .61                     ; cargamos TIMER0 con 61 para que nos cuente 50ms
  152.         movwf   TMR0                    ; porque si empezara de 0 contaría 65536
  153.         btfsc   PUL_D
  154.         goto    CAMBIA_D                ; si mientras esta ejecutando una secuencia
  155.                                         ; se pulsa un botón empieza de nuevo
  156.         btfsc   PUL_I
  157.         goto    DESACTIVAR_I
  158.         btfss   INTCON,2                ; pasaron 50ms? se desbordó TIMER?
  159.         goto    $-5                     ; no seguimos esperando y chequeando pulsadores
  160.         bcf     INTCON,2                ; se desbordó, borramos flag para la próxima vez
  161.         incf    CONTADOR_1,1
  162.         movlw   .20                     ; número de veces que se repite el retardo de 50ms
  163.         subwf   CONTADOR_1,0            ; modificando este número aumentará o reducirá en 50ms el tiempo
  164.         btfss   STATUS,Z
  165.         goto    APAGA_I
  166.         clrf    CONTADOR_1              ; ponemos a 0 contador
  167.         incf    CONTADOR,1              ; para número de veces que encenderá
  168.         movlw   .10                     ; le pongo 10 pero pueden ser las que tu quieras
  169.         subwf   CONTADOR,0
  170.         btfss   STATUS,Z                ; van 10 veces?
  171.         goto    ENCIENDE_I              ; no, vuelve a repetir secuencia
  172.         clrf    CONTADOR
  173.         goto    DESACTIVAR_I
  174.  
  175. CAMBIA_D                                ; esta rutina se ejecutará solo cuando cambie de un intermitente al otro
  176.                                         ; y hará un antirrebotes de 20ms para asegurarse de que no fue un rebote
  177.         bcf     LED_I                   ;
  178.         call    ANTIRREBOTES_1
  179.         btfss   PUL_D                   ; comprueba que realmente se pulsó
  180.         goto    ENCIENDE_I              ; falsa alarma va a donde estaba
  181.         btfsc   PUL_D                   ; se espera hasta que se suelte
  182.         goto    $-1
  183.         call    ANTIRREBOTES_1          ; llama antirrebotes para confirmar
  184.         btfsc   PUL_D                   ; se mira si de verdad se soltó
  185.         return                          ; pasó algo raro vuelve a MAIN
  186.         btfsc   PUL_I                   ; y que el otro botón esta desactivado
  187.         return                          ; se pulsaron los dos va a main a iniciar secuencia
  188.         bcf     INTCON,2
  189.         clrf    CONTADOR
  190.         clrf    CONTADOR_1
  191.         goto    ENCIENDE_D
  192.  
  193. DERECHA
  194.         btfsc   PUL_D                   ; Aquí espera hasta que se suelte pulsador
  195.         goto    $-1                     ; va una posición para atrás
  196.         call    ANTIRREBOTES_1          ; para comprobar si hay rebotes al soltar
  197.         btfsc   PUL_D                   ; se confirma que se soltó pulsador
  198.         return                          ; falsa alarma va a MAIN
  199.         bcf     INTCON,2
  200.         clrf    CONTADOR
  201.         clrf    CONTADOR_1
  202.         goto    ENCIENDE_D
  203.        
  204. DESACTIVAR_D
  205.         bcf     LED_D
  206.         clrf    CONTADOR
  207.         clrf    CONTADOR_1
  208.         btfsc   PUL_D                   ; espera hasta que se suelte pulsador
  209.         goto    $-1                     ; porque si retornara sin esperar volvería a secuencia
  210.         call    ANTIRREBOTES_1
  211.         btfsc   PUL_D                   ; después de antirrebotes confirma se soltó
  212.         goto    $-4                     ; fueron rebotes va a primer chequeo
  213.         return                          ; apaga intermitente y vuelve a MAIN
  214.  
  215. ENCIENDE_D
  216.         bsf     LED_D                   ; enciende intermitente
  217.         movlw   .61                     ; cargamos TIMER0 con 61 para que nos cuente 50ms
  218.         movwf   TMR0                    ; porque si empezara de 0 contaría 65536
  219.         btfsc   PUL_D
  220.         goto    DESACTIVAR_D            ; si mientras esta ejecutando una secuencia
  221.                                         ; se pulsa un botón empieza de nuevo
  222.         btfsc   PUL_I
  223.         goto    CAMBIA_I
  224.         btfss   INTCON,2                ; pasaron 50ms? se desbordó TIMER?
  225.         goto    $-5                     ; no seguimos esperando y chequeando pulsadores
  226.         bcf     INTCON,2                ; se desbordó, borramos flag para la próxima vez
  227.         incf    CONTADOR_1,1
  228.         movlw   .1                      ; número de veces que se repite el retardo de 50ms
  229.         subwf   CONTADOR_1,0            ; modificando este número aumentará o reducirá en 50ms el tiempo
  230.         btfss   STATUS,Z
  231.         goto    ENCIENDE_D
  232.         clrf    CONTADOR_1              ; ponemos a 0 contador
  233.  
  234. APAGA_D
  235.         bcf     LED_D                   ; apaga
  236.         movlw   .61                     ; cargamos TIMER0 con 61 para que nos cuente 50ms
  237.         movwf   TMR0                    ; porque si empezara de 0 contaría 65536
  238.         btfsc   PUL_D
  239.         goto    DESACTIVAR_D            ; si mientras esta ejecutando una secuencia
  240.                                         ; se pulsa un botón empieza de nuevo
  241.         btfsc   PUL_I
  242.         goto    CAMBIA_I
  243.         btfss   INTCON,2                ; pasaron 50ms? se desbordó TIMER?
  244.         goto    $-5                     ; no seguimos esperando y chequeando pulsadores
  245.         bcf     INTCON,2                ; se desbordó, borramos flag para la próxima vez
  246.         incf    CONTADOR_1,1
  247.         movlw   .20                     ; número de veces que se repite el retardo de 50ms
  248.         subwf   CONTADOR_1,0            ; modificando este numero aumentará o reducirá en 50ms el tiempo
  249.         btfss   STATUS,Z
  250.         goto    APAGA_D
  251.         clrf    CONTADOR_1              ; ponemos a 0 contador
  252.         incf    CONTADOR,1              ; para número de veces que encenderá
  253.         movlw   .10                     ; le pongo 10 pero pueden ser las que tu quieras
  254.         subwf   CONTADOR,0
  255.         btfss   STATUS,Z                ; van 10 veces?
  256.         goto    ENCIENDE_D              ; no, vuelve a repetir secuencia
  257.         clrf    CONTADOR
  258.         goto    DESACTIVAR_D
  259.  
  260. LOS_DOS
  261.         btfsc   PUL_I
  262.         goto    $-1
  263.         btfsc   PUL_D                   ; miramos si están sin pulsar ambos botones
  264.         goto    $-3
  265.         call    ANTIRREBOTES_1
  266.         movf    GP4,0                   ; movemos estado pul I a W
  267.         andwf   GP5,0                   ; y le sumamos el estado del pul D para comprobar que vale 0
  268.         btfsc   STATUS,Z                ; encendió FLAG de 0?
  269.         goto    LOS_DOS                 ; fueron rebotes vuelve a comprobar despulsación
  270.         clrf    CONTADOR
  271.         clrf    CONTADOR_1
  272.         bcf     INTCON,2       
  273.         goto    ENCIENDE_LOSDOS
  274.  
  275. DESACTIVAR_LOSDOS
  276.         btfsc   PUL_I
  277.         goto    $-1
  278.         btfsc   PUL_D                   ; miramos si están sin pulsar ambos botones
  279.         goto    $-3                     ; para confirmar que se soltaron
  280.         call    ANTIRREBOTES_1         
  281.         movf    GP4,0                  
  282.         andwf   GP5,0
  283.         btfsc   STATUS,Z                ; comprobamos que el valor de GP4 y 5 es 0, no pulsados
  284.         goto    ENCIENDE_LOSDOS         ; no se soltaron, vuelve a encender los dos    
  285.         clrf    GP0                     ; apagamos intermitentes
  286.         clrf    GP1
  287.         clrf    CONTADOR
  288.         clrf    CONTADOR_1
  289.         return
  290.  
  291. ENCIENDE_LOSDOS
  292.         bcf     INTCON,2
  293.         bsf     GPIO,0                  ; encendemos led D
  294.         bsf     GPIO,1                  ; y led I
  295.         movlw   .61                     ; cargamos TIMER0 con 61 para que nos cuente 50ms
  296.         movwf   TMR0                    ; porque si empezara de 0 contaría 65536
  297.         btfsc   PUL_I
  298.         goto    DESACTIVAR_LOSDOS       ; si mientras esta ejecutando una secuencia
  299.                                         ; se pulsa un botón empieza de nuevo
  300.         btfsc   PUL_D
  301.         goto    DESACTIVAR_LOSDOS
  302.         btfss   INTCON,2                ; pasaron 50ms? se desbordó TIMER?
  303.         goto    $-5                     ; no seguimos esperando y chequeando pulsadores
  304.         bcf     INTCON,2                ; borramos flag para la próxima vez
  305.         incf    CONTADOR_1,1
  306.         movlw   .1                      ; número de veces que se repite el retardo de 50ms
  307.         subwf   CONTADOR_1,0            ; modificando este numero aumentará o reducirá en 50ms el tiempo
  308.         btfss   STATUS,Z
  309.         goto    ENCIENDE_LOSDOS
  310.         clrf    CONTADOR_1              ; ponemos a 0 contador
  311.  
  312. APAGA_LOSDOS   
  313.         bcf     GPIO,0                  ; apagamos led D
  314.         bcf     GPIO,1                  ; y led I
  315.         movlw   .61                     ; cargamos TIMER0 con 61 para que nos cuente 50ms
  316.         movwf   TMR0                    ; porque si empezara de 0 contaría 65536
  317.         btfsc   PUL_I
  318.         goto    DESACTIVAR_LOSDOS       ; si mientras esta ejecutando una secuencia
  319.                                         ; se pulsa un botón empieza de nuevo
  320.         btfsc   PUL_D
  321.         goto    DESACTIVAR_LOSDOS
  322.         btfss   INTCON,2                ; pasaron 50ms? se desbordó TIMER?
  323.         goto    $-5                     ; no seguimos esperando y chequeando pulsadores
  324.         bcf     INTCON,2                ; borramos flag para la próxima vez
  325.         incf    CONTADOR_1,1
  326.         movlw   .20                     ; número de veces que se repite el retardo de 50ms
  327.         subwf   CONTADOR_1,0            ; modificando este numero aumentará o reducirá en 50ms el tiempo
  328.         btfss   STATUS,Z
  329.         goto    APAGA_LOSDOS
  330.         clrf    CONTADOR_1              ; ponemos a 0 contador
  331.         goto    ENCIENDE_LOSDOS
  332.  
  333.  
  334. ANTIRREBOTES                            ;
  335.         movlw   .110                    ; 1 set número de repetición  (B)
  336.         movwf   PDel0                   ; 1 |
  337. PLoop1  
  338.         movlw   .181                    ; 1 set número de repetición  (A)
  339.         movwf   PDel1                   ; 1 |
  340. PLoop2  
  341.         clrwdt                          ; 1 clear watchdog
  342.         clrwdt                          ; 1 ciclo delay
  343.         decfsz  PDel1,1                 ; 1 + (1) es el tiempo 0  ? (A)
  344.         goto    PLoop2                  ; 2 no, loop
  345.         decfsz  PDel0,1                 ; 1 + (1) es el tiempo 0  ? (B)
  346.         goto    PLoop1                  ; 2 no, loop
  347. PDelL1  
  348.         goto    PDelL2                  ; 2 ciclos delay
  349. PDelL2  
  350.         goto    PDelL3                  ; 2 ciclos delay
  351. PDelL3  
  352.         clrwdt                          ; 1 ciclo delay
  353.         return                          ; 2+2 Fin.
  354.  
  355.  
  356. ANTIRREBOTES_1                          ; antirrebotes de 20ms solo cuando esta funcionando uno
  357.                                         ; y se cambia para el otro, sin pasar por MAIN
  358.         movlw   .21                     ; 1 set número de repetición  (B)
  359.         movwf   PDel2                   ; 1 |
  360. PLoop3  
  361.         movlw   .237                    ; 1 set número de repetición  (A)
  362.         movwf   PDel3                   ; 1 |
  363. PLoop4  
  364.         clrwdt                          ; 1 clear watchdog
  365.         decfsz  PDel3,1                 ; 1 + (1) es el tiempo 0  ? (A)
  366.         goto    PLoop4                  ; 2 no, loop
  367.         decfsz  PDel2,1                 ; 1 + (1) es el tiempo 0  ? (B)
  368.         goto    PLoop3                  ; 2 no, loop
  369. PDelL4  
  370.         goto    PDelL5                  ; 2 ciclos delay
  371. PDelL5  
  372.         clrwdt                          ; 1 ciclo delay
  373.         return                          ; 2+2 Fin.
  374.        
  375.        
  376.         org     0x3FF
  377.        
  378. CALIBRAOSC      retlw   0x80            ;calibro oscilador a 4 mhz +- 2%        
  379.        
  380.  
  381.         END


Bueno, que pasen un bonito fin de año, y que el 2011 sea mucho mejor que éste.
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 03 de Enero de 2011, 08:34:47
Bueno feliz año, tarde unos dias en contestar porque a medida que se tienen mas años las resacas tardan mas en pasar, y yo lo noto bastante :lol: :lol:
Creo que el problema esta en WDT_ON, ya te lo dije otra vez que lo habilitaste (te gustan los perros ehh)  :lol:
Tambien modifique algunas cosas en el tema de los puertos, en el MPLAB corre bien, en eso de la calibracion  el "call 3ffh" no va a ninguna posicion y en OSCCAL escribe un 00h siempre, te pongo aqui un documento de Microchip especifico para la programacion de este PIC, esta en ingles.

http://ww1.microchip.com/downloads/en/DeviceDoc/41191D.pdf


Código: [Seleccionar]
LIST P=12F629, ; usar PIC 12F629
#include <p12F629.inc>

__CONFIG _CP_OFF& _WDT_OFF&_PWRTE_ON&_BODEN_OFF&_INTRC_OSC_NOCLKOUT&_MCLRE_OFF

ERRORLEVEL -302

CBLOCK 0x20 ; ponemos 0x20 para que valga para todos
; incluido 12f629
CONTADOR
CONTADOR_1
REG_1
PDel0
PDel1
PDel2
PDel3
 

 ENDC


#DEFINE LED_I GPIO,1
#DEFINE LED_D GPIO,0
#DEFINE PUL_I GPIO,4
#DEFINE PUL_D GPIO,5

ORG 0X00 ; VECTOR DE RESET
goto INICIO ; va a inicio
ORG 0x04 ; VECTOR DE INTERRUPCION



INICIO
clrf GPIO
movlw 07h
movwf CMCON ; todos los pines en modo digital.
bsf STATUS,5 ; activa la página 1
movlw b'111100' ; GP0 y 1 salidas 2, 3, 4 y 5 entradas.
movwf TRISIO
call 0X3FF
movwf OSCCAL
clrf INTCON ; deshabilitar interrupciones.
movlw 0X07 ; TIMER con prescaler de 256, para 50ms
movwf OPTION_REG
movlw 0X20 ; habilitamos desborde de TIMER pero sin interrupción
movwf INTCON ; cada 50ms nos seteara el flag TOIF de INTCON
bcf STATUS,5 ; volvemos a la página 0
bcf GPIO,0 ; apagamos led D
bcf GPIO,1

clrf CONTADOR
clrf CONTADOR_1
clrf REG_1


ESPERA

btfss   PUL_I   
goto    $+3 ; va tres posiciones para delante
call      ANTIRREBOTES
goto     MAIN
btfss    PUL_D
goto     ESPERA
call      ANTIRREBOTES
goto    MAIN

TABLA          ;esta tabla nos dira que hay que hacer
addwf   PCL,1
goto     ESPERA  ; aqui nunc vendra, pero por si acaso....
goto     DERECHA
goto     IZQUIERDA
goto     LOS_DOS

MAIN

btfss   PUL_D    ; miramos si en PUL_D hay un 1 o un 0
bcf     REG_1,0  ; y escribimos en un registro lo que haya
btfsc   PUL_D    ; en el bit 0
bsf      REG_1,0
btfss   PUL_I     ; hacemos lo mismo con el otro pulsador
bcf      REG_1,1  ;este lo escribimos en el bit 1
btfsc   PUL_I
bsf      REG_1,1  ; aqui ya tenemos los dos pulsadores leidos y anotados en un registro
movf  REG_1,0    ; lo movemos a W
call    TABLA
goto   ESPERA

CAMBIA_I ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_D
call ANTIRREBOTES_1
btfss PUL_I ; comprueba que realmente se pulso
goto ENCIENDE_D ; falsa alarma va a donde estaba
btfsc PUL_I ; se espera hasta que se suelte
goto $-1
call ANTIRREBOTES_1 ; llama antirrebotes para confirmar
btfsc PUL_I ; se mira si de verdad se solto
return ; paso algo raro vuelve a MAIN
btfsc PUL_D ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_I


IZQUIERDA

btfsc PUL_I ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
call ANTIRREBOTES_1 ; para comprobar si hay rebotes al soltar
btfsc PUL_I ; se confirma que se solto pulsador
return ; falsa alarma va a MAIN
bcf INTCON,2 ; se solto y no hay rebotes
clrf CONTADOR ; pone contadores a 0 e inicia secuencia
clrf CONTADOR_1
goto    ENCIENDE_I


DESACTIVAR_I

bcf     LED_I
clrf CONTADOR
clrf CONTADOR_1
btfsc PUL_I    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
call ANTIRREBOTES_1
btfsc PUL_I ; despues de antirrebotes confirma se solto
goto $-4 ; fueron rebotes va a primer chequeo
return            ; apaga flag e intermitente y vueleve a MAIN, FLAG estaba a 1

ENCIENDE_I

bsf    LED_I    ; enciende intermitente izquierda
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D  ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_I
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_I

bcf    LED_I    ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto CAMBIA_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto DESACTIVAR_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_I
clrf CONTADOR_1 ; ponemos a 0 contador

incf  CONTADOR,1  ; para numero de veces que encendera
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf  CONTADOR,0
btfss  STATUS,Z  ; van 10 veces?
goto  ENCIENDE_I    ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_I

CAMBIA_D ; esta rutina se ejecutara solo cuando cambie de un intermitente
; y hara un antirrebotes de 20ms para asegurarse de que no fue un rebote
bcf LED_I ;
call ANTIRREBOTES_1
btfss PUL_D ; comprueba que realmente se pulso
goto ENCIENDE_I ; falsa alarma va a donde estaba
btfsc PUL_D ; se espera hasta que se suelte
goto $-1
call ANTIRREBOTES_1 ; llama antirrebotes para confirmar
btfsc PUL_D ; se mira si de verdad se solto
return ; paso algo raro vuelve a MAIN
btfsc PUL_I ; y que el otro boton esta desactivado
return ; se pulsaron los dos va a main a iniciar secuencia
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DERECHA

btfsc PUL_D ; Aqui espera hasta que se suelte pulsador
goto $-1 ; va una posicion para atras
call ANTIRREBOTES_1 ; para comprobar si hay rebotes al soltar
btfsc PUL_D ; se confirma que se solto pulsador
return ; falsa alarma va a MAIN
bcf INTCON,2
clrf CONTADOR
clrf CONTADOR_1
goto ENCIENDE_D

DESACTIVAR_D

bcf LED_D
clrf CONTADOR
clrf CONTADOR_1
btfsc PUL_D    ; espera hasta que se suelte pulsador
goto $-1 ; porque si retornara sin esperar volveria a secuencia
call ANTIRREBOTES_1
btfsc PUL_D ; despues de antirrebotes confirma se solto
goto $-4 ; fueron rebotes va a primer chequeo
return          ; apaga intermitente y vuelve a MAIN
 
ENCIENDE_D

bsf LED_D      ; enciende intermitente
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_D
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_D

bcf LED_D      ; apaga
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_D
goto DESACTIVAR_D    ; si mientras esta ejecutando una secuencia; se pulsa un boton empiezade nuevo
btfsc PUL_I
goto CAMBIA_I
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; se desbordo, borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_D
clrf CONTADOR_1 ; ponemos a 0 contador

incf CONTADOR,1  ; para número de veces que encenderá
movlw .10          ; le pongo 10 pero pueden ser las que tu quieras
subwf CONTADOR,0
btfss STATUS,Z    ; van 10 veces?
goto ENCIENDE_D ; no, vuelve a repetir secuencia
clrf  CONTADOR
goto DESACTIVAR_D

LOS_DOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
call ANTIRREBOTES_1
btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3

clrf CONTADOR
clrf CONTADOR_1
bcf INTCON,2
goto    ENCIENDE_LOSDOS

DESACTIVAR_LOSDOS

btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3
call ANTIRREBOTES_1
btfsc PUL_I
goto $-1
btfsc PUL_D ; miramos si estan sin pulsar ambos botones
goto $-3

clrf GPIO  ; apagamos intermitentes
clrf CONTADOR
clrf CONTADOR_1
return

ENCIENDE_LOSDOS

bcf INTCON,2
movlw  0x03
movwf GPIO  ; ponemos a 1 bits 0 y 1 del puerto
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc PUL_I
goto    DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .1 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto ENCIENDE_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador

APAGA_LOSDOS

clrf GPIO ; apagamos intermitentes
movlw .61 ; cargamos TIMER0 con 61 para que nos cuente 50ms
movwf TMR0 ; porque si empezara de 0 contaria 65536

btfsc  PUL_I
goto  DESACTIVAR_LOSDOS  ; si mientras esta ejecutando una secuencia se pulsa un boton empiezade nuevo
btfsc  PUL_D
goto DESACTIVAR_LOSDOS
btfss INTCON,2      ; pasaron 50ms? se desbordo TIMER?
goto $-5 ; no seguimos esperando y chequeando pulsadores
bcf INTCON,2 ; borramos flag para la proxima vez
incf CONTADOR_1,1
movlw .20 ; numero de veces que se repite el retardo de 50ms
subwf CONTADOR_1,0 ; modificando este numero se aumentara o reducira en 50ms el tiempo
btfss STATUS,Z
goto APAGA_LOSDOS
clrf CONTADOR_1 ; ponemos a 0 contador
goto    ENCIENDE_LOSDOS


ANTIRREBOTES               ;

DEMORA  movlw     .110      ; 1 set numero de repeticion  (B)
        movwf     PDel0     ; 1 |
PLoop1  movlw     .181      ; 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  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


ANTIRREBOTES_1 ; antirrebotes de 20ms solo cuando esta funcionando uno
; y se cambia para el otro, sin pasar por MAIN
movlw     .21       ; 1 set numero de repeticion  (B)
        movwf     PDel2     ; 1 |
PLoop3  movlw     .237      ; 1 set numero de repeticion  (A)
        movwf     PDel3     ; 1 |
PLoop4  clrwdt              ; 1 clear watchdog
        decfsz    PDel3,1   ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop4    ; 2 no, loop
        decfsz    PDel2,1   ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop3    ; 2 no, loop
PDelL4  goto PDelL5         ; 2 ciclos delay
PDelL5  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


END


Bueno ya me contaras.

Saludos
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 05 de Enero de 2011, 13:20:38
Funciona perfecto también con el 12F629, gracias Tapi8. Posiblemente entre el perro  :D y los portA y B me fastidiaron todo el programa. Está visto que esto de programar no es para mí.
Precisamente lo del OSCCAL para calibrarlo si no lo saqué del datasheet fue de algún programa de algún compañero, que después comprobé que en las hojas de microchip también venía.

Para los que vayan a grabar un chip de éstos: al programar el micro, primero lo leí para averiguar el valor de calibración situado en la última posición de memoria y lo anoté. Después al cargar el programa hay que ir a esa misma posición y editar lo que haya puesto el programa (normalmente 3FFF) y reponer el valor que puso Microchip.
Así lo he hecho y funciona correcto al 100%, como con el 16F84A.

Ya estoy diseñando la pcb para distribuir los componentes y pasar a probar con +12v. A ver si va todo bien. Todavía me falta por encontrar un par de casquillos para las lámparas. El del taller de coches donde llevo el mío me ha encontrado uno, mas otro que yo tenía, solo me faltan dos, si no me toca romper dos bombillas buenas  :5], cosa que no me hace gracia. Soy pejiguera con estas cosas.

Y también me falta coger los leds a algo que los deje en su sitio dentro del intermitente. Ya tengo un par de ideas, todas en plan chapuza total, pero efectivas, y como no se vé.....

Bueno, si hay alguna novedad, la dejo por aquí.

Muchísimas gracias. Seguimos en contacto.

Saludos

Título: Re: Intermitentes moto.
Publicado por: tapi8 en 06 de Enero de 2011, 09:49:19
Me alogro que te funcione con el 12F629, porque en este foro a los que llegamos a los 500 mensajes no se nos permite tener fallos, y ya me estaba viendo con una bronca encima   :lol: :lol:.
Cuando hagas pruebas con 12V debes controlar en los pulsadores que te lleguen menos de 5.5V, ya que van directos a los 12V, porque sino te puede cascar el PIC, y desde luego mas de 2V, a 4Mz con 2V le llega segun el datasheet, pero bueno mejor darle un poco mas, si le das en torno a 4V creo que estaria bien, estoy hablando en los pulsadores ya que la alimentacion va a traves del 7805 y no deberia haber problema.
Estoy impaciente por ver el video de demostracion  :-/ :-/

Saludos Tapi
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 17 de Marzo de 2011, 18:58:29
Como lo prometido es deuda, aquí está el tutorial con el montaje e instalación de esta historia.

Me ha llevado bastante tiempo adaptarlo a la moto, por eso la tardanza, pero no dispongo de un sitio adecuado para desmontar y trastear (la calle). El adaptarlo al hueco del intermitente es lo que mas dolores de cabeza me ha dado, el primer prototipo 'bailaba' mucho e incluso se oía afuera.

De nuevo muchas gracias por la ayuda prestada.

Espero que les guste.

Citar
http://www.foroharley.com/f44/
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 18 de Marzo de 2011, 15:00:20
Si señor han quedado muy bien, aunque creo que un poco mas de tiempo encendidas....porque es posible que te pongan problemas en la ITV, creo que ya sabes tu como hacerlo, sino pega un toque por aqui.
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 18 de Marzo de 2011, 16:09:06
Pues no sé la normativa en cuanto a duración encendida, lo intenté buscar por la red pero no encontré nada al respecto, lo que está claro es que así no se calienta en absoluto y me gusta como 'flashea'.

En cuanto al cambio de duración encendido, no te preocupes, ya estoy haciendo pruebas sobre otro prototipo para que en vez de subir +12v a cada intermitente, suba solo 2v (tensión de trabajo del led) y así eliminar el driver en los intermitentes y los dos optoacopladores en el circuito controlador. Para ello programé el pic de manera que se mantuviera encendido varios segundos y así poder medir y ajustar el voltaje en el led.

De momento las pruebas han ido bien. El led iría pegado al casquillo metálico y eliminaría toda la parafarnalia del bote de cerveza. Se queda mas compacto, fácil y rápido de abrir y cerrar el conjunto del intermitente.

Sí, me paso la vida dándole vueltas al coco..... :D

Un abrazo, amigo.
Título: Re: Intermitentes moto.
Publicado por: juan47 en 22 de Marzo de 2011, 16:57:36
Una estupenda realizacion Felicidades a los dos y gracias

Un saludo
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 25 de Marzo de 2011, 15:33:37
Asencio, estos LEDs directos al micro no los puedes poner mas pronto o mas tarde cascara el 16f629, ya que la intensidad de esos LED esta muy por encima de lo que puede dar el PIC (25mA maximo).
Por medio de una resistencia necesitarias una de 10W o mas, son grandisimas.
Hay un sistema que creo que daria resultado, haciendo que se enciendan y se apaguen muy rapido (PWM) lo que te habia comentado del bajo consumo, recuerdas?, tienes 12V y quieres 2, hacemos que los transistores conduzcan 1mS y esten 5mS apagados, como de cada 6 esta solamente 1 con tension seria el equivalente a 2V, aunque realmente le llegan 12, si aun asi hubiera problemas creo que con un pequeño condensador en serie con el LED y la resistencia bajariamos esa tension??? pongo las ???porque no estoy totalmente seguro pero creo que la solucion va por aqui.
Bueno tu diras.
Gracias por ponerme tan bien en el foro de las HARLEY.

Birras y suerte.  :lol: :lol:
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 17 de Abril de 2011, 17:46:13
@Juan47: gracias a vosotros por el programa, si me lo hubiera tenido que currar yo solo me habría salido una castaña. Funcionaría probablemente, pero ni comparación a como lo hace ahora.

@Tapi8: empezando por el final....te he puesto como te mereces, el programa es tuyo y va de fábula.
No pensaba atacar directamente los leds desde el pic. Pensaba pasar por un transistor que le proporcione la chicha que necesita. Además voy a sustituir el regulador por un transistor pequeñito y un zener.
Voy a ver si te puedo adjuntar el esquema. La zona del control de tensión +5 para el micro es la del Q3. Y las salidas a los leds son los transistores Q1 y Q2. Si te fijas tienen un zener en la base de 2.6v para que al restarles el medio voltio que se comen los transistores entre base y emisor me dejen en las salidas tensiones de 2v. aprox. que es justo lo que necesitan los leds. Y como los transistores se alimentan de +12v, no sobrecargo las salidas del PIC.
Igualmente el nuevo"regulador" de +5 es el Q3, en su base un zener de 5.6V que con el medio voltio entre base y emisor me deja en la salida (emisor) los 5v. exclusivamente para el PIC. El transistor aún siendo de los de pequeño tamaño soporta corriente de 1A, de sobra para el PIC.

Gracias a todos por los comentarios e interés mostrado. Por descontado que cualquier compañero que necesite algún tipo de información o ayuda por mi parte encantado.

Ronda birras frescas para todos. De cuando en cuando entro por aquí. :)

P.D.: me acabo de dar cuenta que hay un componente del esquema que no es correcto, se trata de C3. Figura como condensador pero en realidad es un fusible de 4A (no encontraba en la librería un fusible redondo del tamaño de un condensador electrolítico de raster 5.08mm y puse éste para que saliera al dibujar la placa).
También he modificado los valores de C1 y C2 a 100/25 ambos para que cupieran en la cajita donde va alojado el módulo.
Y C5 está pegadito a la entrada de alimentación del Pic.
Ya lo he probado (fuera de la moto) y funciona perfectamente. Le he dado un poco mas de tiempo encendido (100ms) y que parpadee 12 veces en lugar de 10.  :lol:
(http://)
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 14 de Mayo de 2011, 14:33:00
Esto que pones en el foro de harley tambien tendria solucion.

Citar
Intenté pasar la ITV con ella y me la tirarón 'patrás' porque no se notaba el cambio al frenar, apenas iluminaba un poco mas.
 

seria un circuito sencillo con un programa sencillo, incluso lo podrias integrar en el circuito de los intermitentes ya que tenias dos pines libres en el PIC, no?
Título: Re: Intermitentes moto.
Publicado por: ohsielos en 16 de Mayo de 2011, 19:11:20
Me refería a unas bombillas que compré a los chinos (al principio de los tiempos  :D)pensando que sería cambiar las incandescentes y funcionar sin mas complicaciones, incluso con vistas a cambiar las del coche. Pero al ponerlas el efecto fue muy lamentable, la luz de posición sí se veía bastante bien, pero al frenar apenas había un muy ligero incremento de luz (casi imperceptible).
No me pasaron la ITV y con razón. Son basura.
Todavía tengo algunas por aquí. Incluso una que la llevé un tiempo puesta, al desmontarla para aprovechar el casquillo para uno de mis primeros proyectos para la luz trasera con 50 u 80 leds (no recuerdo bien) me dí cuenta que una de las resistencias internas que lleva para limitar la corriente, no sé si de freno o de posición, estaba completamente quemada: negra, tiznaba e imposible ver los colores.
Resumiendo, no se os ocurra comprarlas, al menos las de doble luz. Imagino que para coches que tengan bombilla para posición separada e independiente de la del freno, igual sí sirve, estudiando bien la luminosidad que ha de proporcionar cada una.
No sé si en la página de harley puse la foto, pero es ésta:
(http://)

Saludos
Título: Re: Intermitentes moto.
Publicado por: tapi8 en 17 de Mayo de 2011, 05:37:11
Si encienden da igual que tengan la resistencia quemada, ya que lo que hariamos seria con un PIC, el que tuvieramos mas a mano, podria ser el 12f629 que ya lo conocemos, unas resiatencias para conectarle dos pulsadores uno de encendido y uno que venga del freno, activariamos un transistor, con este transistor activariamos la luz al 30% de su luminosidad para posicion y al 100% para frenado, la bombilla solo tiena que encender la regulacion se la haria el circuito.
Ya ves 4 resistencios un PIC un transistor y un programa tan sencillo que incluso lo harias tu, asi vas empezando con la programacion.
Si tienes varias bombillas y te costo 5€ cada una las vendes con el circuito a 20€ y aun ganas algo  :lol: :lol:.