Hola estoy trabajando en un proyecto para la facultad. Es la primera vez que doy esta asignatura y ando bastante perdido.
Os explico. Mi proyecto consiste en hacer como si los ocho leds fueran un control de encendido o apagado de calderas(por ejemplo).
El led de la posición cero siempre tiene que estar activo exceptuando cuando fijas un led que el sistema queda apagado dos segundos (tmr0)
El programa se enciende cuando pulsas el pulsador de RA4 y inmediatamente aparece el led cero que nos informa que ya se puede trabajar. A partir de ahí, si pulsamos otra vez RA4 sale una luz parpadeante en la posición uno, si pulsamos otra vez en la posición dos, apagando la anterior, es decir rotando.
Cuando queramos fijar una caldera encendida pulsamos rb0 y tras una interrupcion de dos segundos (mientras queda apagado) y se restablece con la luz 0 y la luz seleccionada encendida. Si queremos apagarlo el proceso inverso. La interrupción la hice de 50MS que contando 13 veces me da los 650MS que necesito.
Utilizo la misma subrutina para el parpadeo de la luz que va rotando que para la interrupción de los dos segundos.
No se si os habrá quedado claro.
Ahora tengo un problema, sobre todo con la instrucción iorlw y xorlw las cuales soy incapaz que me salgan bien en la simulación. Gracias de antemano porque estoy volviendome loco.
Os explico. Mi proyecto consiste en hacer como si los ocho leds fueran un control de encendido o apagado de calderas(por ejemplo).
El led de la posición cero siempre tiene que estar activo exceptuando cuando fijas un led que el sistema queda apagado dos segundos (tmr0)
El programa se enciende cuando pulsas el pulsador de RA4 y inmediatamente aparece el led cero que nos informa que ya se puede trabajar. A partir de ahí, si pulsamos otra vez RA4 sale una luz parpadeante en la posición uno, si pulsamos otra vez en la posición dos, apagando la anterior, es decir rotando.
Cuando queramos fijar una caldera encendida pulsamos rb0 y tras una interrupcion de dos segundos (mientras queda apagado) y se restablece con la luz 0 y la luz seleccionada encendida. Si queremos apagarlo el proceso inverso. La interrupción la hice de 50MS que contando 13 veces me da los 650MS que necesito.
Utilizo la misma subrutina para el parpadeo de la luz que va rotando que para la interrupción de los dos segundos.
No se si os habrá quedado claro.
Ahora tengo un problema, sobre todo con la instrucción iorlw y xorlw las cuales soy incapaz que me salgan bien en la simulación. Gracias de antemano porque estoy volviendome loco.
Código:
LIST P=16F877A
INCLUDE P16F877A.INC
__CONFIG _XT_OSC & _WDT_OFF & _LVP_OFF
CONTADOR1 EQU 20; contador que nos dice que bit está elegido. Solo rota
CONTADOR2 EQU 21; contador que nos dice las luces que están encendidas
CONTEMP1 EQU 22; registro para la temporización
ORG 0
GOTO INICIO
ORG 5
INICIO CLRF PORTD; limpiamos el puerto d
BSF STATUS,RP0; vamos al banco 1
CLRF TRISD
MOVLW b'10000110';metemos el divisor de frecuencia 256
MOVWF OPTION_REG
BCF STATUS, RP0; volvemos al banco 0
CLRF CONTADOR1; limpiamos por si acaso el contador
CLRF CONTEMP1
CLRF CONTADOR2
PULSA1 BTFSS PORTA,4; miramos si pulsamos el pulsador de arrancado (ra4)
GOTO PULSA1; bucle de espera
; El contador1 está cargado con 0x00. Si pulsamos metemos ya la luz de habilitación, pues el panel ya está operativo.
;Esta luz solo se apaga cuando seleccionamos una caldera durante la interrupción de dos segundos
MOVLW b'00000001'; metemos el bit de habilitación en el registro w
MOVWF CONTADOR1; sacamos w por el contador 1 pues ya pulsamos una vez
MOVWF PORTD; sacamos el bit de habilitación, posición cero
PULSADO MOVLW CONTADOR1
IORWF CONTADOR1,W; aquí ya no me funciona
MOVWF CONTADOR2; lo sacamos por el contador general
MOVWF PORTD; ahora por pantalla
CALL _650MS; instrucción de la interrupción para el parpadeo
MOVLW 0X00; hacemos ahora que el led que rote este apagado
IORLW CONTADOR2; puerta ior con el contador dos y guardando en w
MOVWF PORTD; y ahora por pantalla
CALL _650MS; otra interrupción. Esta parte del parpadeo la tengo mal seguro pues no lo entiendo muy bien
MOVLW CONTADOR1
IORLW CONTADOR2
MOVWF PORTD
BCF STATUS,C; ponemos ahora sí el acarreo a cero
RLF CONTADOR1; rotamos a la izquierda el ocntador1, que saldrá por pantalla al pulsar la siguiente vez
CUALQUIERA BTFSC PORTB, 0; si no se pulsa RBO, todo queda como estaba. Si se pulsa vamos a la subrutina parada para fijar la
;luz escogida o para apagarla
CALL PARADA; llamamos a la subrutina
BTFSC PORTA, 4;si no pulsamos rb0 miramos si si lo hicimos con el porta4
GOTO PULSADO; si lo pulsamos vamos de nuevo a pulsado
GOTO CUALQUIERA; si no volvemos de nuevo al bucle cualquiera
PARADA CLRF PORTD; limpiamos el portd
CLRF CONTEMP1
RRF CONTADOR1; rotamos a la derecha para obtener el bit que queremos fijar
CALL _650MS; llamamos a la interrupción
INCF CONTEMP1,F; incrementamos el contador de la temporización
MOVLW CONTEMP1
XORLW d'3'; 3*650=1.950 segundos, el tiempo que queremos pausar el sistema
BTFSS STATUS,Z; miramos status para saltar el bucle parada cuando la operación anterior acabe
GOTO PARADA
RLF CONTADOR1; rotamos a la izquierda el contador para que entre en pulsado adecuadamente
MOVLW CONTADOR1; movemos el contador 1 a w
XORLW CONTADOR2; con esta opción la luz del contador3 quedará fijada si la que ocupa esa posición en el contador1
MOVWF CONTADOR2; guardamos en el registro dos
MOVWF PORTD; movemos el registro w de nuevo al puerto d
MOVLW b'00000001'; al restablecer el sistema contador 1 debe empezar como al principio por ello le metemos..
MOVWF CONTADOR1;
RETFIE;devolvemos el valor
_650MS CLRF TMR0
MOVLW d'91'; metemos la precarga
MOVWF TMR0
BCF INTCON, T0IF
FLAG BTFSC INTCON, T0IF
GOTO FLAG
INCF CONTEMP1,F
MOVLW CONTEMP1
XORLW d'13'; aquí tambien me falla.
BTFSS STATUS, 2
GOTO _650MS
CLRF CONTEMP1
RETURN
END