void alarma (){
lcd_gotoxy(1,1); //esta es la posición para que el mensaje
printf(lcd_putc, "ALARMA"); //funcione en el LCD correctamente
do{ //Haz las sigueintes rutinas
output_high(PIN_C6);
output_high(PIN_C7);
delay_ms(10);
output_low(PIN_C7);
delay_ms(10);
}
while(PORTC!=0b00001000); // mientras PORTC no sea igual a 0b00001000 while ((PORTC & 0x0f)!=0x05);Me ha funcionado, pero si utilizo la directiva fast_io no funciona, por lo que he dejado la directiva standard_io.
/*
A0 = 1º zona de control
A1 = 2º Zona de control
C0 = Interruptor para código
C1 = Interruptor para código
C2 = Interruptor para código
C3 = Interruptor para código
C5 = led verde
C6 = led rojo
C7 = zumbador, salida PWM
*/
#include <16f876.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock = 4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#use standard_io (A)
#use standard_io (B)
#use standard_io (C)
#BYTE TRISC = 0x87
#BYTE PORTC = 0x07
//----------------------------------Rutina de alarma-----------------------------
void alarma(){
lcd_gotoxy(1,1); //esta es la posición para que el mensaje
printf(lcd_putc, " ALARMA"); //funcione en el LCD correctamente
do{ //Haz las siguientes rutinas
output_high(PIN_C6); //Apagamos el led rojo
output_high(PIN_C7); //empieza la rutina de la señal PWM
delay_ms(10);
output_low(PIN_C7);
delay_ms(10); //Finaliza la rutina de la señal PWM
}
while((PORTC & 0x0f)!=0b00001000); // sigue con el bucle mientras PORTC no sea igual a 0b00001000
}
//-------------------------------Rutina de desactivación-----------------------------------
void desarmado(){
lcd_gotoxy(1,1); //Seleccionamos la posición del mensaje
printf(lcd_putc, " DESARMADO"); //Mensaje a desplegar en el LCD
do{ //Haz la siguiente rutina
output_high(PIN_C5); //Enciende el led verde
output_low(PIN_C6); //Apaga el led Rojo
output_low(PIN_C7); //Desactiva el zumbador
}
while((PORTC & 0x0f)!=0b00000110); //sigue con el bucle Mientras PORTC no sea = a 0x06
}
//-----------------------------Programa principal-------------------------------
void main(){
lcd_init(); //Funcion necesaria para que funcione el LCD
while(TRUE){ //Mientras sea verdad
lcd_gotoxy(1,1); //Seleccionamos la posición del mensaje
printf(lcd_putc, "\f ARMADO"); //Mensaje a desplegar en el LCD
output_low(PIN_C5); //apaga el led verde (si estubiera encendido)
output_low(PIN_C7); //apaga el led amarillo (si estuviera encendido)
if (input(PIN_A0)||input(PIN_A1)==1) // Si A0 o A1 se pone a 1
alarma(); //Se salta la alarma
if ((PORTC & 0x0f)==0b00000111) //si por el nible mas bajo de puerto C, se activa el código 0x07
desarmado(); //Se desactiva el sistema
else output_low(PIN_C6); //Rutina de parpadeo del led rojo
delay_ms(600);
output_high(PIN_C6);
delay_ms(70); //termina la rutina del led rojo
}
}
Supongamos que configuro del PORTB el nibble alto como salida y el bajo como entrada (TRISB = 0x0F). Y que todas las salida están en 1. Al leer el PORTB obtengo 0b1111xxxx (siendo x el valor que haya en cada entrada). Es decir que el nibble alto del valor leído está relacionado con como se encuentran las salidas. Al menos así ocurre con HiTech C
En la forma ....while (PORTC != 0b00001000); -que era como lo tenías originalmente- tenías que estar seguro que todas las salidas estaban en 0.
En cambio al hacer PORTC & 0x0F me aseguro de hacer todo el nibble alto 0 y el nibble bajo quedará lo leído. Tené en cuenta que hacer una AND con 0 implica hacer 0 todos los bits donde esté el 0. Hacer una and con 1 no afecta, ya que el que era 1 seguirá siendo 1 y el que era 0 seguirá siendo 0.
/*
A0 = 1º zona de control
A1 = 2º Zona de control
C0 = Interruptor para código
C1 = Interruptor para código
C2 = Interruptor para código
C3 = Interruptor para código
C5 = led verde
C6 = led rojo
C7 = zumbador, salida PWM
*/
#include <16f876.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock = 4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#use standard_io (A)
#use standard_io (B)
#use standard_io (C)
#BYTE TRISC = 0x87
#BYTE PORTC = 0x07
//----------------------------------Rutina de alarma-----------------------------
void alarma1(){
lcd_gotoxy(1,1); //esta es la posición para que el mensaje
printf(lcd_putc,"\fFALLO SEGURIDAD\nEn la Zona 1"); //funcione en el LCD correctamente
do{ //Haz las siguientes rutinas
output_high(PIN_C6); //Apagamos el led rojo
output_high(PIN_C7); //empieza la rutina de la señal PWM
delay_ms(10);
output_low(PIN_C7);
delay_ms(10); //Finaliza la rutina de la señal PWM
}
while((PORTC & 0x0f)!=0b00001000); // sigue con el bucle mientras PORTC no sea igual a 0b00001000
lcd_gotoxy(1,1);
printf(lcd_putc, "\fSistema Activado\nZona1 y Zona2");
}
//----------------------------------ZONA-2---------------------------------------------------
void alarma2(){
lcd_gotoxy(1,1); //esta es la posición para que el mensaje
printf(lcd_putc,"\fFALLO SEGURIDAD\nEn la Zona 2"); //funcione en el LCD correctamente
do{ //Haz las siguientes rutinas
output_high(PIN_C6); //Apagamos el led rojo
output_high(PIN_C7); //empieza la rutina de la señal PWM
delay_ms(10);
output_low(PIN_C7);
delay_ms(10); //Finaliza la rutina de la señal PWM
}
while((PORTC & 0x0f)!=0b00001000); // sigue con el bucle mientras PORTC no sea igual a 0b00001000
lcd_gotoxy(1,1); //Mensaje al salir del bucle
printf(lcd_putc, "\fSistema Activado\nZona1 y Zona2"); //para que no parpadee el LCD
}
//-------------------------------Rutina de desactivación-----------------------------------
void desarmado(){
lcd_gotoxy(1,1); //Seleccionamos la posición del mensaje
printf(lcd_putc, "\f Sistema \n Desactivado"); //Mensaje a desplegar en el LCD
do{ //Haz la siguiente rutina
output_high(PIN_C5); //Enciende el led verde
output_low(PIN_C6); //Apaga el led Rojo
output_low(PIN_C7); //Desactiva el zumbador
}
while((PORTC & 0x0f)!=0b00000110); //sigue con el bucle Mientras PORTC no sea = a 0x06
lcd_gotoxy(1,1); //Mensaje al salir del bucle
printf(lcd_putc, "\fSistema Activado\nZona1 y Zona2"); //de esta manera no parpadea el LCD
}
//-----------------------------Programa principal-------------------------------
void main(){
lcd_init(); //Funcion necesaria para que funcione el LCD
lcd_gotoxy(1,1); //Seleccionamos la posición del mensaje
printf(lcd_putc, "Sistema Activado\n Zona1 y Zona2"); //Mensaje a desplegar en el LCD
while(TRUE){
output_low(PIN_C5); //apaga el led verde (si estubiera encendido)
output_low(PIN_C7); //apaga el led amarillo (si estuviera encendido)
if (input(PIN_A0)==1) //Si A0 se pone a 1
alarma1(); //Salta a alarma1
if (input(PIN_A1)==1) //Si A1 se pone a 1
alarma2(); //Salta a alarma2
if ((PORTC & 0x0f)==0b00000111)//si por el nible mas bajo de puerto C, se activa el código 0x07
desarmado(); //Se desactiva el sistema
else output_low(PIN_C6); //Rutina de parpadeo del led rojo
delay_ms(600);
output_high(PIN_C6);
delay_ms(70); //termina la rutina del led rojo
}
}
A ver si me explico con claridad.
¿Lo que me quieres decir, si no te entiendo mal, es que le haces un AND a cada bit del puerto? con lo cual cómo has puesto 0x0f, en binario para verlo mejor:0b00001111 significa que como la AND es:
A B | S
0 0 | 0
0 1 | 0
1 0 | 0
1 1 | 1
Por consiguiente los bits que están a 0 siempre estarán a 0 y los que están a 1 con solo poner un 1 en la entrada tenemos 1 | 1 = 1
Lo mismo sucedería en el caso de poner una OR (|) o OR EXCLUSIVA (^) pero con su resultado correspondiente.
¿Me equivoco?