Interrupción con PIC16F84A en el MPLAB

Hola Amigos
tengo que realizar una actividad con un PIC16F84A en el MPLAB; La actividad consiste en hacer un semáforo, donde el tiempo que se demoran los peatones se vea en un un display 7seg y ese tiempo es de 0-9 y ademas tiene que llevar una interrupción para cuando haya un carro y no hay peatones se active el semáforo sin importar en que número vaya el contador.
Esto es lo que he hecho me falta solo la interrupción:

Código:
#INCLUDE <P16F84A.INC>  
    radix    hex        
    estado    equ    0x03            
    reg1    equ    0x0C         
    reg2    equ    0x0D         
    reg3    equ    0x0E             
    reset    org    0x00       
inicio
    bsf    estado,5           
    movlw    b'00000001'    
    movwf    TRISB
    clrf    TRISA         
    bcf    estado,5  
    movlw    b'01111110'
    movwf    PORTB
    call    retardoP
    movlw    b'00001100'
    movwf    PORTB    
    call    retardoP
    movlw    b'10110110'
    movwf    PORTB
    call    retardoP
    movlw    b'10011110'
    movwf    PORTB
    call    retardoP
    movlw    b'11001100'
    movwf    PORTB    
    call    retardoP
    movlw    b'11011010'
    movwf    PORTB
    call    retardoP
    movlw    b'11111010'
    movwf    PORTB    
    call    retardoP
    movlw    b'00001110'
    movwf    PORTB
    call    retardoP
    movlw    b'11111110'
    movwf    PORTB
    call    retardoP
    movlw    b'11011110'
    movwf    PORTB    
    call    retardoP
    movlw    b'01111111'
    movwf    PORTB
    call    retardo
    movlw    b'00000001'
    movwf    PORTA
    CALL    retardo
    movlw    b'00000010'
    movwf    PORTA
    CALL    retardo
    movlw    b'00000100'
    movwf    PORTA
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardo
    movlw    b'00000010'
    movwf    PORTA
    CALL    retardo
    movlw    b'00000001'
    movwf    PORTA
    goto    inicio
retardoP
        movlw    50         
        movwf    reg1         
tres    movlw    40     
        movwf    reg2
dos        movlw    30
        movwf    reg3
uno        decfsz    reg3,1         
        goto    uno         
        decfsz    reg2,1        
        goto    dos        
        decfsz    reg1,1        
        goto    tres         
        retlw    00         
retardo    movlw    30         
        movwf    reg1         
tres1    movlw    20     
        movwf    reg2
dos1    movlw    10
        movwf    reg3
uno1    decfsz    reg3,1         
        goto    uno         
        decfsz    reg2,1        
        goto    dos        
        decfsz    reg1,1        
        goto    tres         
        retlw    00
    end
Gracias por su ayuda :)
 
Última edición por un moderador:
Un programa en ASM sin comentarios, es como buscar una aguja en un pajar, personalmente NUNCA hago un programa sin comentarios pues ni yo puedo entender despues que hace sin guiarme por ellos, ahora imagina nosotros que no lo hicimos que hacemos ah????? colocale comentarios y vemos, chauuuuuuuuuu
 
Claro, electromesa, fdesergio tiene razón. Además, pese a la sencillez del programa ya empiezan a aparecer "trampas psicológicas" :D cuando anidas tres bucles y a la variable reg1 le asignas el control del bucle que comienza en la dirección "tres" y viceversa. Bueno, no tiene mucha importancia, pero esas cosas dificultan la comprensión. Ya irás cogiendo práctica.

Creo que te falta todo lo referente al display, y lo de la cuenta regresiva, etc. ¿La interrupción es sólo para detectar la presencia del carro, o vas a hacer alguna otra cosa con interrupciones (control de tiempos, por ejemplo, o lo que sea)?
 
Código:
#INCLUDE <P16F84A.INC>  
    radix    hex        
    estado    equ    0x03            
    reg1    equ    0x0C         
    reg2    equ    0x0D         
    reg3    equ    0x0E             
    reset    org    0x00       
inicio
    bsf    estado,5           
    movlw    b'00000001'    ; Programo todos los bits como salidas menos el bit0
    movwf    TRISB        ; en el puerto B
    clrf    TRISA        ;limpio ek puerto A
    bcf    estado,5  
    movlw    b'01111110' ; empieza el programa con el semaforo en rojo y el contador en 0
    movwf    PORTB        ; que se vea en el puerto b 
    call    retardoP    ; llamamos el retardo 
    movlw    b'00001100'    ; contador en 1
    movwf    PORTB    
    call    retardoP
    movlw    b'10110110'    ; contador en 2
    movwf    PORTB
    call    retardoP
    movlw    b'10011110'    ; contador en 3
    movwf    PORTB
    call    retardoP
    movlw    b'11001100'    ; contador en 4
    movwf    PORTB    
    call    retardoP
    movlw    b'11011010'    ; contador en 5
    movwf    PORTB
    call    retardoP
    movlw    b'11111010'    ; contador en 6
    movwf    PORTB    
    call    retardoP
    movlw    b'00001110'    ; contador en 7
    movwf    PORTB
    call    retardoP
    movlw    b'11111110'    ; contador en 8
    movwf    PORTB
    call    retardoP
    movlw    b'11011110'    ; contador en 9
    movwf    PORTB    
    call    retardoP
    movlw    b'01111111'    ; y de nuevo a cero para que cambie el semaforo
    movwf    PORTB
    call    retardo
    movlw    b'00000010'    ;cambia el semaforo a amarillo
    movwf    PORTA        ; en el puertoA ya q el semaforo se encuentra en este puerto (A0-led rojo,A1-led amarillo,A2-led verde)
    CALL    retardo        ; llamamos el retardo q esta ves no demora tanto como los anteriores
    movlw    b'00000100'    ; cambia el semaforo a verde 
    movwf    PORTA
    CALL    retardoP    ;el retardo se repite tantas veces para que duere el mismo tiempo que dura el contador de ir de 0 a 9
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardoP
    CALL    retardo
    movlw    b'00000010'    ; semaforo a amarillo
    movwf    PORTA
    CALL    retardo
    movlw    b'00000001'    ; y semaforo a rojo
    movwf    PORTA
    goto    inicio        ; y de nuevo a inicio para q inicie el contador de nuevo 
retardoP
        movlw    50         
        movwf    reg1         
tres    movlw    40     
        movwf    reg2
dos        movlw    30
        movwf    reg3
uno        decfsz    reg3,1         
        goto    uno         
        decfsz    reg2,1        
        goto    dos        
        decfsz    reg1,1        
        goto    tres         
        retlw    00         
retardo    movlw    30         
        movwf    reg1         
tres1    movlw    20     
        movwf    reg2
dos1    movlw    10
        movwf    reg3
uno1    decfsz    reg3,1         
        goto    uno         
        decfsz    reg2,1        
        goto    dos        
        decfsz    reg1,1        
        goto    tres         
        retlw    00
        end


La interrupción solo es para detectar si hay carros y no hay peatones
Gracias ;)
 
Última edición por un moderador:
Aaaaaah, vale, ya entiendo. Así que el puerto B es para el display (pensaba que era para activar distintos semáforos de un cruce).

Bueno, yo personalmente habría programado esto mediante una tabla que contuviera todos los valores para el display, y metería en un bucle una única actualización del registro B y una única llamada al retardo. De esta forma, en ese mismo bucle podría meter una única comprobación de presencia de un carro.

Entonces, como no quiero hacer esa comprobación por polling sino por interrupción, yo haría que en la interrupción se activara una variable (por ejemplo un bit de un registro al que llamaría PresenciaCarro (en vez de llamarlo reg4 :D ). Entonces, en el bucle que comentaba, comprobaría el valor de ese bit y si está activo me salgo del bucle para abrir el semáforo a los coches (y cerrarlo a los peatones, por supuesto).

Bien, si prefieres hacerlo por tu sistema sin bucle (y con 10 trozos de código idénticos, como hasta ahora), podrías hacer la verificación en la misma subrutina de retardo: Si el bit de presencia de carro está activo, te saltas todos los bucles de retardo y retornas al programa principal. Podrías hacer una doble entrada al bucle de retardo: En la primera entrada se haría la comprobación del bit de presencia de carro; en la segunda entrada ya no se haría esa comprobación. Así que, en el trozo de programa correspondiente al tiempo de paso de carros, llamarías al retardo a su segunda entrada.

No sé si me he explicado...
 
Atrás
Arriba