# Encendido de luz (semáforo) PIC16F88



## Shirosekai (Dic 14, 2010)

Buenas aqui de nuevo veran estoy programando este PIC despues de varios años de no tocar uno como no recuerdo ensamblador pues decidi usar C por ello estoy usando el CCS ahora bien hasta ahora no e tenido un gran problema; ahora bien voy a explicar más o menos por ahora que hace este codigo
1) Al empezar todos los leds verdes estan encendidos (esto lo hace bien)
2) En este caso poseemos 3 casos donde al presionar por separado cada pulsador ocurre algo
-- Si se presiona P0 (entra un 1) el semaforo S2 pasa a rojo apagando el led verde de este se mantiene 5 seg asi y vuelve a verde
-- Si se presiona P1 (entra un 1) el semaforo S0 pasa a rojo apagando el led verde se mantiene por 5 segundos y vuelve a verde
-- si se presiona P2 (entra un 1) el semaforo S1 pasa a rojo apagando el led verde se mantiene por  5 seg y vuelve a verde

Hasta aqui el programa me esta sirviendo pero ahora entro en otro estado, que es cuando se presionan dos de los interruptores al mismo tiempo no se como asignar el codigo necesario para que tome que cuando por ejemplo se presionen P0 y P1 se pongan en rojo S2 y S1 (apagando sus leds verdesy manteniendo el led verde de S0)   por 5 segundo para luego poner en rojo S0 yS2 (apagando sus leds verdes y encendiendo el led verde de S1) se mantiene por 5 seg y luego todos los semaforos se ponen en verde, si ven la ultima parte del codigo veran lo que puse aunque no se si eso servira, me gustaria saber si alguien me puede ayudar con el codigo para que interprete dos valores al mismo tiempo ya que al usar lo que estoy usando por alguna razon me hace todo pero un semaforo se mantiene apagado sus dos luces cuando no deberia ser asi.
No estoy seguro si me entendieron pero les dejo la tabla de estados por si no me entendieron bien. 






Con que me digan cual codigo hace que lea las dos entradas juntas al mismo tiempo me vasta gracias de antemano y espero alguien me pueda ayudar



```
///semaforo 
//se poseen tres semaforos de dos lucez cada uno
//quienes son controlados por tres interruptores
//P0, P1, P2 son los pulsadores que actuan como "sensores"
//P0= RA0, P1=RA1, P2=RA2
//se asigno a semaforo S0 (RB1, RB2), S1 (Rb3, rb4) y a S2 (RB5, RB6)
// RB1, RB3, RB5 =leds rojos
//RB2, RB4, RB6 =leds verdes

#include <16F88.h>
#use delay (clock=1000000)
#fuses HS,NOWDT,NOPUT,NOPROTECT
#byte port_b=0x06 
 void main() {  
   set_tris_a(00111);
    set_tris_b(0x00); 
    disable_interrupts(GLOBAL);
  ///estado 3 semaforos en verde
   do{      
        output_low(PIN_B1);                  
        output_high(PIN_B2);
        output_low(PIN_B3);
        output_high(PIN_B4);
        output_low(PIN_B5);
        output_high(PIN_B6);
      
  ///fin del estado verde todos
  
  ///inicio control de los sensores
  ///P0, P1, P2
       
 //presionando P0    
   if (input(pin_a0)){  
      output_low(pin_b6);
      output_high(pin_b5);
      delay_ms(4500);
     }
   //presionando P1
      if (input (pin_a1)) {
     output_low(pin_b2);
     output_high(pin_b1);
     delay_ms(4500);
   }
// presionando P2
   if (input (pin_a2)) {
     output_low(pin_b4);
     output_high(pin_b3);
     delay_ms(4500);
   }
 
 ////caso dos activando dos pulsadores al mismo tiempo
 ///caso P0 P1 presionados
   if (input (pin_a0))
   if (input (pin_a1)){
     output_low(pin_b4);
     output_high(pin_b3);
     output_low(pin_b6);
     output_high(pin_b5);
     delay_ms(4500);
     
    
   }
   } while(true);//Bucle infinito
 }
```


----------



## cris3D (Dic 14, 2010)

que tal, apenas me iniciare con pic, ando armando un programador provisional para luego hacer el pickit2  clon, y ya tengo algunos tutos, pero lo que no se es precisamente lo de los compiladores, tengo que bajar MPLAB y luego CCS? 

MPLAB se puede bajar de la pagina pero CCS es de paga no? quiero programa de la familia PIC18 en especial el 2550 que es con el que se hace el pickit2 , alguna recomendación?

por otro lado, solo recomendaria para el bucle infinito un for(; y un switch para decirdir cual luz se prende..

saludos buen aporte


----------



## ByAxel (Dic 14, 2010)

> Con que me digan cual codigo hace que lea las dos entradas juntas al mismo tiempo me vasta gracias de antemano y espero alguien me pueda ayudar


Pon *#use fast_io(a)* e intenta enmascarando las entradas que quieres leer:

```
if((input_a() && 0x03) == 0x03){ // Revisa los pines RA0 y RA1
}

if((input_a() && 0x05) == 0x05){ // Revisa los pines RA0 y RA2
}
```

también se puede similar en un switch - case.

Veo que el PIC no hace nada por tiempos muy largos "*delay_ms(4500);*", se que no afecta pero para otras cosas toma en cuenta el debounce 'rebote' que provocan las partes mecánicas del pulsador.

saludos


----------



## Shirosekai (Dic 14, 2010)

ByAxel dijo:


> Pon *#use fast_io(a)* e intenta enmascarando las entradas que quieres leer:
> 
> ```
> if((input_a() && 0x03) == 0x03){ // Revisa los pines RA0 y RA1
> ...



gracias por tu respuesta, intentare con ello pero una pregunta en caso del rebote que tipo de cambios debo de colocar para evitarlo, curiosidad

-------------------------------------------------------------------------------------
Al colocar el #use fast_io(a), las entradas me cambian no es asi ahora la entrada A0 al pulsar el boton se mantiene en alto, eso es normal? si comparo ahora A0 con otra entrada este no hace sigue las instruciones pero mantiene las luces de S1 ambas apagadas....


----------



## ByAxel (Dic 14, 2010)

*#use fast_io(x)* hace que no se esté reescribiendo el TRISx cada vez que se consulta al puerto (reduce el código compilado), en este modo es necesario usar *set_tris_X();*, además este PIC comparte el módulo ADC con el PORTA y por defecto son entradas análogas... entonces debes de desactivar con:

```
setup_comparator(NC_NC_NC_NC);
SETUP_ADC_PORTS(NO_ANALOGS);
```
ya se que se tiene que escribir más, hazlo como más te guste... personalmente me gusta controlar todo del PIC y este PIC tiene varias cosas.



> en caso del rebote que tipo de cambios debo de colocar para evitarlo, curiosidad


luego de consultar un pin se acostumbra poner un delay de 15ms o 20ms (varia en la práctica) para evitar falsos disparos y entre otros truquitos de acuerdo al proceso que se quiera hacer.

salu2.


----------



## Shirosekai (Dic 14, 2010)

Ok bueno veamos meti el codigo que me dices hice unos cambios y bueno siguo teniendo el mismo problema el codigo seria asi

```
///semaforo proyecto taller 2
//se poseen tres semaforos de dos lucez cada uno
//estos deben de poseer 

#include <16F88.h>
#use delay (clock=1000000)
#fuses HS,NOWDT,NOPUT,NOPROTECT
#byte port_b=0x06 
#use fast_io(a)

 void main() {  
  setup_comparator(NC_NC_NC_NC);
  SETUP_ADC_PORTS(NO_ANALOGS);
  set_tris_a(0xff);
    set_tris_b(0x00); 
    
    disable_interrupts(GLOBAL);
    
  ///estado 3 semaforos en verde
   do{      
        output_low(PIN_B1);                  
        output_high(PIN_B2);
        output_low(PIN_B3);
        output_high(PIN_B4);
        output_low(PIN_B5);
        output_high(PIN_B6);
      
  ///fin del estado verde todos
  
  ///inicio control de los sensores
  ///S0, S1, S2
       
     
   if (input(pin_a0)){  
      output_low(pin_b6);
      output_high(pin_b5);
      delay_ms(4500);
     }
   
      if (input (pin_a1)) {
     output_low(pin_b2);
     output_high(pin_b1);
     delay_ms(4500);
   }
   if (input (pin_a2)) {
     output_low(pin_b4);
     output_high(pin_b3);
     delay_ms(4500);
   }
 
 ////caso dos activando dos pulsadores al mismo tiempo
 ///caso S0 S1
   if((input_a() && 0x03) == 0x03){
    output_low(pin_b4);
     output_high(pin_b3);
     output_low(pin_b6);
     output_high(pin_b5);
     output_high(pin_b2);
     delay_ms(4500);
}
    
     
   
   } while(true);//Bucle infinito
 }
```

Ahora bien voy a poner el circuito con el que estoy simulado a ver si es que esta mal tambien dejo el .hex que me deja el CCS

Aprovechando una vez tenga el codigo lo meto en el PIC cualquier quemador de pics me sirve? y tambien aparte de los leds y interruptores debo colocarle algo más al circuito del pic una vez lo ponga en la protoboard?


----------



## ByAxel (Dic 14, 2010)

En la mayoría de microcontroladores es necesario poner una resistencia pull-up (V+) o pull-down (GND) al usar un pulsador para ofrecerle un nivel lógico adecuado. En tu circuito mientras no esté accionado el pulsador, el pin de entrada se mantiene en incertidumbre -en la practica se verá que el PIC se vuelve loco porque no sabe si es un '1' o '0' lógico-.

Un ejemplo:

- Mientras no esté accionado, el nivel lógico es '0'.
- Al pulsar, el nivel lógico es '1'.
- La resistencia va desde 1K a 47K.
Agrega algo así en tu circuito.



> Aprovechando una vez tenga el codigo lo meto en el PIC cualquier quemador de pics me sirve?


Si, mientras el PIC que usas lo tenga en su lista de dispositivos soportados.


> tambien aparte de los leds y interruptores debo colocarle algo más al circuito del pic una vez lo ponga en la protoboard?


- Un LED no debe ir directamente al pin, agrega una resistencia de unos 330 Ohm para cada led.
- Para cada pulsador agrega una resistencia de unos 10K conectado a GND.
- Hace falta un cristal de 1Mhz según tu configuración, eso es importante ya que este PIC soporta oscilador externo e interno... eso lo ves en la configuración de fuses y no te olvides que la frecuencia del oscilador debe ser la misma que usaste para compilar.
- Según tu configuración te hace falta una resistencia de 10K entre la pata del MCLR y V+.

PD: En la simulación se pueden evitar varias cosas (eso confunde al principiante), revisa otros post y el mismo datasheet del PIC para que te cerciores de su funcionamiento.

Me avisas como va.
salu2


----------



## Shirosekai (Dic 14, 2010)

Veamos cristal puedo conseguir pero una cosa los capacitores que van a tierra de que valor me recomiendas que use? nunca e usado un cristal asi que no tengo idea de ello
-----------------------------------------------------------------------------------------------------------
A ver si coloco esta instrucción estoy configurando para que use el reloj interno a 1MZ para que no tenga que ponerle un cristal o no

```
setup_oscillator(OSC_1MHZ|OSC_INTRC);
```


----------



## ByAxel (Dic 14, 2010)

Si esta bien para usar el oscilador interno y también reemplaza
#FUSE HS... por #FUSE INTRC_IO...


----------



## Shirosekai (Dic 14, 2010)

Bueno por más que intento no logro hacer el estado de cuando dos pulsadores se presionen haga la instruccion, jajaja y como es para mañana la veo feo en todo caso seguire intentando a ver al usar 

```
if((input_a() && 0x03) == 0x03){ // Revisa los pines RA0 y RA1
}

if((input_a() && 0x05) == 0x05){ // Revisa los pines RA0 y RA2
}
```
lo que estoy haciendo es comparar ambas entradas y si son iguales realiza la instruccion dentro de los corchetes no es asi, si coloco eso al presionar ambos botones o me sigue la instruccion de cuando presiono solo un boton o otro mejor dicho no compara ambos valores y no realiza la instrucción sera que algo esta mal?


----------



## ByAxel (Dic 14, 2010)

Que tal así...
- Entra si se cumple que PIN_A0 = 1 y PIN_A1 = 1...

```
if(input_state(PIN_A0) & input_state(PIN_A1)){

}
```
Lee las dos entradas en la misma instrucción IF... solo se cumple si ambos pulsadores en RA0 y RA1 están presionados.


----------



## DanNeil (Dic 14, 2010)

Buenas tardes amigos,

Estoy tratando de trabajar funciones lógicas (lógica combinacional) que imite la operación de las compuertas not, and, or,nor, etc.
este es uno que trabaja como AND de tres entradas:

#include <16f877a.h>
#use delay (clock=4000000)
#use standard_io(b)
#fuses XT,NOWDT,NOPROTECT



 void main() {  

    set_tris_b(0x07); 
    disable_interrupts(GLOBAL);

   do{      

   if (input (pin_b0)) // entrada 1
   if (input (pin_b1))  // entrada 2
   if (input(pin_b2)){  //entrada 3
     output_high(pin_b3); //salida 1
     output_high(pin_b4); //salida 2


   }
   } while(true);//bucle 
 }


No me gusta que una vez que pongo las tres en alto, me dejan las salidas en alto, así vuelva a bajar las entradas.

¿Qué hago para esto? que testee cada algo y si no cumple, que baje a 0 las salidas? ¿cómo lo haría?

¿cómo puedo hacer que una salida se active cuando una está en alto y la otra en bajo?

Puede ser, como una OR, pero como una OR exclusiva, o mejor, una que me permita condicionar cuál debe estar en bajo y cual en alto para enviar la salida a 1. Deseo trabajar con una lógica que me permita combinar estados bajos y altos, para activar salidas pero ese if ((!pin_bx) & 8pin_bx) & (pin_bx)), no me ha servido mucho, no sé que he omitido.

Es para realizar funciones lógicas e implementar esta lógica combinacional en µC.

Gracias


----------



## Shirosekai (Dic 15, 2010)

ByAxel dijo:


> Que tal así...
> - Entra si se cumple que PIN_A0 = 1 y PIN_A1 = 1...
> 
> ```
> ...



Hola como vas veras cuando uso ese comando me esta apareciendo este error en el proteus tal vez sea esto lo que no deja trabajar las instrucciones






Bueno en realidad no entiendo que quiere decir el error, si alguien me pudiera ayudar con ello se lo agradeceria


----------



## ByAxel (Dic 15, 2010)

No se que versión uses pero esos mensajes no me aparecen; ahí te indican que un registro no está implementado en el modelo de simulación al igual que el registro OSCCON.

Adjunto con el que yo estaba probando y perdón con el código anterior que me falto un símbolo para
que se cumpla, seria &&:

```
input_state(PIN_A0) && input_state(PIN_A1)
```

--------------------------------------------------------
@danneil, nunca va a suceder lo que buscas... un AND se cumple cuando todas son 1 pero nunca pones a cero las salidas al no cumplir, además te sugiero que sea algo así, solo para evitar el anidado de IF:


```
if(input(PIN_B0) && input(PIN_B1) && input(PIN_B2)){ // Todas a '1' para cumplir AND
   output_high(PIN_B3);
   output_high(PIN_B4);
}else{ // De lo contrario, todas las salidas a cero.
   output_low(PIN_B3);
   output_low(PIN_B4);
}
```

salu2


----------



## Shirosekai (Dic 15, 2010)

ByAxel dijo:


> No se que versión uses pero esos mensajes no me aparecen; ahí te indican que un registro no está implementado en el modelo de simulación al igual que el registro OSCCON.
> 
> Adjunto con el que yo estaba probando y perdón con el código anterior que me falto un símbolo para
> que se cumpla, seria &&:
> ...



Ok bueno con tu codigo me salen dos errores





tengo la version 7.2 si no me equivoco, bueno con tu codigo me salio mejor ahora si me sigue las instrucciones que le pongo cuando presiono ambos pulsadores sin embargo experimentando me fije de una cosa por ejemplo si coloco

```
else if(input_state(PIN_A0) && input_state(PIN_A1)){
  
   output_high (pin_b5);
   output_low (pin_b6);
   
   delay_ms(4500);
   
      }
```

me reconoce la instrucción y lo hace pero en este caso lo que estoy haciendo es prender el led en B5 y apagar el de B6 si lo coloco asi apaga B6 pero no prende el B5 al ponerlo alrevez primero que apague B6 y luego prenda B5 si lo hace bien, ok por ese lado estoy bien sin embargo al meterle dentro que apague B4 y encienda B3 mejor dicho


```
else if(input_state(PIN_A0) && input_state(PIN_A1)){
   output_low (pin_b6);
   output_high (pin_b5);
   output_high (pin_b3);
   output_low (pin_b4);
```

Me apaga  B6 y B4 pero no prende B5 y B6. Pero si quito las dos primera lineas y dejo las otras dos si lo hace lo mismo al revez pero al juntarlas no prende B5 y B6
Mi version del proteus es la 7.2 si no me equivoco


----------



## ByAxel (Dic 15, 2010)

jeje raro... yo uso el 7.7 Sp2. intenta manipulando todo el puerto, es decir:

```
output_b(0b00101010); // Por ejemplo, cada vez que entre a un IF.
```


----------



## Shirosekai (Dic 15, 2010)

A ver por ejemplo en el caso de anterior coloque


```
else if(input_state(PIN_A0) && input_state(PIN_A1)){
   output_b(0b00110100);
   delay_ms(4500);
      }
```

Algo asi seria o estoy leyendo al revez?

----------------------------------------------------------------------------------------
Ok lo estaba leyendo al revez XD pero me funciono gracias por la ayuda con ese codigo si me funciono, solo una pregunta más en el caso de el que los tres se presionan se puede colocar un segundo && para comparar las tres verdad


----------



## Shirosekai (Dic 16, 2010)

Bueno ahora esta listo el codigo lo dejo aqui para ver que tal lo ven 

```
#include <16F88.h>
#device *=16
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES RESERVED                 //Used to set the reserved FUSE bits

#use delay(clock=1000000)
#use fast_io(a)
#use fast_io(b)

void main()
{
   setup_oscillator(OSC_1MHZ|OSC_INTRC);
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_tris_a(0x07);
   set_tris_b(0x00);
   output_b(0);
   
   do{
 ///Estado inicial todas las lucez en verde  
      output_low(PIN_B1);                  
      output_high(PIN_B2);
      output_low(PIN_B3);
      output_high(PIN_B4);
      output_low(PIN_B5);
      output_high(PIN_B6);
   
      if(input_state(PIN_A0)){
         output_low(PIN_B6);
         output_high(PIN_B5);
         delay_ms(4500);
      }
      
      else if(input_state(PIN_A1)){
         output_low(PIN_B2);
         output_high(PIN_B1);
         delay_ms(4500);
      }
      
      else if(input_state(PIN_A2)){
         output_low(pin_b4);
         output_high(pin_b3);
         delay_ms(4500);
      }
   ///Cuando se presionan dos botones a la vez
   
   //Cuando se presiona P0 y P1
      else if(input_state(PIN_A0) && input_state(PIN_A1)){
   output_b(0b00101100);
   delay_ms(4500);
   output_b(0b01001010);
   delay_ms(4500);
      }
    /// cuando se presiona P0 y P2
    else if(input_state(PIN_A0) && input_state(PIN_A2)){
    output_b(0b00101100);
    delay_ms(4500);
    output_b(0b01001010);
    delay_ms(4500);
     }
    // Cuando se presiona P1 y P2
     else if(input_state(PIN_A1) && input_state(PIN_A2)){
     output_b(0b00110010);
     delay_ms(4500);
     output_b(0b01010010);
     delay_ms(4500);
     }
     else if(input_state(PIN_A1) && input_state(PIN_A2)&& input_state(PIN_A0)){
     output_b(0b00101100);
     delay_ms(4500);
     output_b(0b00110010);
     delay_ms(4500);
     output_b(01001010);
     delay_ms(4500);
     
    } 
   }while(TRUE);
}
```

Muchas gracias a Byaxel por toda tu ayuda, si no te molesta que te moleste una ultima vez me podrias decir una cosa veras es que cuando presiono más de un boton si sigue la instruccion pero le cuesta ver ambas entradas hay veces en que no las ve y solo ve una pero si se presionan exactamente igual pues si lo hace no se eso me imagino que es algo del retardo asi que me gustaria saber si se te ocurre algo para solucionarlo, ya el circuito esta bien asi de hecho asi lo voy a entregar pero me gustaria saber de alguna forma si es que la sabes, gracias de nuevo por toda tu ayuda, saludos


----------



## ByAxel (Dic 16, 2010)

De echo si no fuera por los retardos seria casi imposible de usar las combinaciones de 2 o más teclas...
Se me ocurre dos formas pero tendrías que cambiar la lógica de tu programa...
1) - En un solo IF, se ejecuta si cualquiera de las 3 entradas se activa.
    - Lee todo el PORTA, enmascara los 3 bits (pulsadores) y lo guarda en una variable.
    - Delay de unos 100ms
    - Vuelve a leer el PORTA, enmascara 3 bits y el valor lo compara con la variable, entonces.
    - Si es igual usa el valor en un Switch-Case para decidir que evento va a realizar y si es distinto, repite
      el proceso desde delay 100ms.

Con eso me refiero a que el PIC debe estar seguro de lo que a obtenido al leer las entradas además pongo 100ms para que la señal de los pulsadores se estabilicen y junto con eso hay suficiente tiempo para que se pueda manipular 2 o más pulsadores.

Lo analizas:

```
do{
   
      if(input_state(PIN_A0) || input_state(PIN_A1) || input_state(PIN_A2)){
         tecla = input_a() & 0x07;
         delay_ms(100);
         if(tecla == (input_a() & 0x07)){
            switch(tecla){
               case 0b001:
                  output_b(0); break;
               case 0b010:
                  output_b(0); break;
               case 0b100:
                  output_b(0); break;
               case 0b011:
                  output_b(0); break;
            }
         }
      }
      
   }while(TRUE);
```

2) Similar al (1) pero verificando cada entrada individualmente con IF anidados, retardos de 100ms para luego voler a verificar la misma entrada y revisar si otra esta activa al mismo tiempo... creo que esto es mucho proceso.

salu2


----------



## Shirosekai (Dic 16, 2010)

ByAxel dijo:


> De echo si no fuera por los retardos seria casi imposible de usar las combinaciones de 2 o más teclas...
> Se me ocurre dos formas pero tendrías que cambiar la lógica de tu programa...
> 1) - En un solo IF, se ejecuta si cualquiera de las 3 entradas se activa.
> - Lee todo el PORTA, enmascara los 3 bits (pulsadores) y lo guarda en una variable.
> ...



Uhmm veamos si creo que funcionara aunque la verdad es que lo voy a dejar asi luego cuando lo halla entregado lo ire mejorando para que funcione mejor por ahora cumple lo que me piden asi que espero que el profesor no sea muy estricto con ello, de todos modos al parecer soy el unico que lo voy a entregar, gracias por tu ayuda, saludos


----------



## DanNeil (Dic 16, 2010)

Ok, gracias por la aclaración, ya mismo lo estoy implementando a ver qué passa con la AND :

if(input(PIN_B0) && input(PIN_B1) && input(PIN_B2)){ // Todas a '1' para cumplir AND
   output_high(PIN_B3);
   output_high(PIN_B4);
}else{ // De lo contrario, todas las salidas a cero.
   output_low(PIN_B3);
   output_low(PIN_B4);
}

pero también quiero hacer funciones lógicas que "si tienen en cuenta todos los niveles lógicos y activan salidas según las combinaciones de "0's" y "1's" por ejemplo : que tal si quiero que una salida se active a la combinación de las entradas A,B,Cy D con estas características:

A=0, B=1, C=1 ,D=0; 

Mis problemas eran respectivamente: con la AND, fácilmente me enciende después de que pongo a uno sus tres entradas:
///////////////////////////////////////////
void main() { 

set_tris_b(0x07); 
disable_interrupts(GLOBAL);

do{ 

if (input (pin_b0)) // entrada 1
if (input (pin_b1)) // entrada 2
if (input(pin_b2)){ //entrada 3
output_high(pin_b3); //salida 1
output_high(pin_b4); //salida 2


}
} while(true);//bucle 
}
///////////////////////////////////////

Pero no las baja cuando yo bajo alguna entrada.

Y la otra es, como implementar digamos una función lógica como esta, por ejemplo:

X(salida) = 1 cuando A(entrada)=0;B(entrada)=1;C(entrada)=1;D(entrada)=0; ó cuando 
a=0;B=0;C=1;D=0;
Es todo, gracias por su paciencia y ayuda que seguro me dará luces.


----------



## ByAxel (Dic 16, 2010)

> Pero no las baja cuando yo bajo alguna entrada, se queda activa esa salida, quiero una que siga cambios de la condición AND.


Pero pones esto en alguna parte de tu código??:

```
[B]output_low[/B](pin_b3); //salida 1
[B]output_low[/B](pin_b4); //salida 2
```
de otro modo esas salidas nunca van a bajar cuando bajas una entrada.



> Y la otra es, como implementar digamos una función lógica como esta, por ejemplo:
> 
> X(salida) = 1 cuando A(entrada)=0;B(entrada)=1;C(entrada)=1;D(entrada)= 0; ó cuando
> a=0;B=0;C=1;D=0;


Ahí mismo está la respuesta...
La condición es que todo se cumpla para poner X(salida) = 1...

```
if(A==0 && B==0 && C==1 && D==0){ // Si todo se cumple, entonces
   X = 1;  // X = 1.
}
```


----------



## DanNeil (Dic 16, 2010)

Pues, si eso creo tal cual me dijiste depues del 

else{
output_low(pin_b3); //salida 1
output_low(pin_b4); //salida 2
} ah, y ya pruebo a ver cómo me va con la "función lógica".

Pero ¿qué tal esto?:

cuando las dejo todas en uno, no hay cambio, ayer si, pero al detener simulación y ponerlas en alto, antes de simular, al oprimir play (con las entradas ya en 1 ó 0) si cambia salida.

ok, ya quedó.Es que le quité el Do{} while(1); de repetir bucle, se lo puse otra vez y quedó oki doki, gracias y ya sigo con la función lógica.

Qué estés bien!


----------



## Shirosekai (Dic 16, 2010)

Hola aqui en medio de una emergencia por favor al tratar de meter el codigo usando winpic800 me sale este error
de escritura 0x000000 escrito: 0x3000 leido 0x0000
espero alguien me ayude con este problema


----------



## Shirosekai (Dic 17, 2010)

Bueno ya solucione el problema era el programador que estaba usando que no me servia en todo caso me solicitaron arreglar el problema de que realice de inmediato las instrucciones de cuando se presione mas de un boton asi que aqui me encuentro de nuevo a ver esta vez me dieron tiempo de hasta el martes pero entre más rapido salga de esto mejor... asi que a ver que hago, seguire tu sugerencia ByAxel luego te cuento como me fue
------------------------------------------------------------------------------------------------------------
segun lo comprendo lo que me pides es poner A0, A1, A2 en una  misma variable llamada "tecla" segun tu codigo? o cada una de ellas la llamo distinto y repito el codigo


----------



## pettit11 (May 18, 2011)

hola un gran favor... alguien de ustedes podria paasarme el diagrama de conexion para este programa


----------



## wts (Jul 26, 2015)

Hola. Encontré estas rutinas, pero la verdad no sé si estarán bien.


```
#include <p16f88.inc>

__CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
                   
; Asignacion de variables utilizadas en demora   
CONT equ 0Ch
CONT2 equ 0Dh
CONT3 equ 0Eh
CONT4 equ 0Fh

ORG   0000h
bsf       STATUS,5         ; Cambiamos al banco 1Switch to Bank 1
            movlw     0000h              ; Ponemos los pines del puerto A ...
            movwf     TRISA            ; ...como salidas.
            bcf       STATUS,5         ; Volvemos al Banco 0.

LUZROJA    movlw     b'00000010'   ; Encendemos el LUZROJA poniendo primero el Valor, por 20 segundos.
            
movwf     PORTA
            call RETARDO
            

LUZAMARILLA    movlw     b'00000110'              ; Encendemos LUZROJA Y LUZ AMARILLA.
            movwf     PORTA
            call RETARDO1
            movlw b'00000000'
    

RETARDO ; Retardo de 20s
        movlw d'10'
        movwf CONT4;
CICLO4    movlw d'100'
        movwf CONT3
CICLO3    movlw d'98'
        movwf CONT2
CICLO2    movlw d'67'
        movwf CONT
CICLO    decfsz CONT,1
        goto CICLO
        decfsz CONT2,1
        goto CICLO2
        decfsz CONT3,1
        goto CICLO3
        decfsz CONT4,1
        goto CICLO4
        Return

RETARDO1; Reatardo de 5s
        movlw d'100'
        movwf CONT3
CICLO6    movlw d'100'
        movwf CONT2
CICLO5    movlw d'166'
        movwf CONT
CICL4    decfsz CONT,1
        goto CICLO4
        decfsz CONT2,1
        goto CICLO5
        decfsz CONT3,1
        goto CICLO6
        Return
END
```



Aquí está un diseño que estoy armando, pero la verdad no sé si estará bien.


----------



## D@rkbytes (Jul 27, 2015)

Esa no es la palabra de configuración correcta para ese PIC.
El PIC16F88 tiene dos secciones: 0x2007 y 0x2008
Estas dos direcciones corresponden respectivamente a; _CONFIG1 y _CONFIG2

Si quieres usar un cristal menor o igual a 4 MHz para el oscilador, puedes usar esta configuración:

```
__config    _CONFIG1, _XT_OSC & _LVP_OFF & _BOREN_OFF & _PWRTE_ON & _WDT_OFF
     __config    _CONFIG2, _IESO_OFF & _FCMEN_OFF
```
Para usar el oscilador interno:

```
__config    _CONFIG1, _FOSC_INTOSCIO & _LVP_OFF & _BOREN_OFF & _PWRTE_ON & _WDT_OFF
     __config    _CONFIG2, _IESO_OFF & _FCMEN_OFF
```
Y en el registro OSCCON estableces la frecuencia de operación.

También necesitas crear un bucle para realizar las rutinas del programa.
De otra forma, se ejecutarán consecutivamente todas las instrucciones hasta llegar a End, y ahí se detendrá el programa completamente.

Por ejemplo:

```
[COLOR=Purple]Inicio[/COLOR]
    [COLOR=Green]; Configuraciones[/COLOR]
[COLOR=Purple]Programa[/COLOR]
  [COLOR=Green] ; Rutinas[/COLOR]
   [COLOR=Blue]GoTo[/COLOR] Programa

[COLOR=Purple]Subrutinas[/COLOR]
   [COLOR=Green]; Código[/COLOR]
   [COLOR=Blue]Return[/COLOR]

    [COLOR=Blue]End[/COLOR]
```
Este PIC tiene conversores ADC y si quieres que funcione en modo digital, debes configurar el todo el registro ANSEL en 0.

Me parece que tienes que estudiar bastante antes de empezar a programar.
Lee la hoja de datos del PIC que vayas a usar y mira programas básicos de ejemplo.


----------



## rockoztar (Sep 29, 2015)

¿Qué tal? Estoy haciendo un programa en el cual por cada pulso que va a A0 cambie de estado.
Pero creo que lo estoy haciendo mal porque no sé qué deba agregar para que permanezca B0 (luz verde) prendido esperando el siguiente pulso para pasar al B1(ambar) y luego al B2 (rojo) y regresar a todos apagados. 

¿Alguna sugerencia? Aquí dejo mi código. Tengo muy poco en el lenguaje C.


```
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#define puerto_b
#define puerto_a
#use fast_io(a)
#use fast_io(b)
  
void main()
{

set_tris_b(0x00);
set_tris_a(0x07);
output_b(0);




do{
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);


if(input_state(PIN_A0)){
output_high(PIN_B0);
delay_ms(50);
}

if(input_state(PIN_A0)){
    output_low(PIN_B0);
    delay_ms(50);
    output_high(PIN_B1);
    delay_ms(50);
}

if(input_state(PIN_A0)){
    output_low(PIN_B1);
    delay_ms(50);
    output_high(PIN_B2);
    delay_ms(50);
}


}while(true);
}
```


----------



## D@rkbytes (Sep 29, 2015)

Hazlo con una selección "Instrucción Switch" y un contador.

Por ejemplo:

```
void semaforo (void)
{
    if(contador > x) contador = 0;
    contador++;
    switch (contador)
    {
        case 1: output_x(0b00000001);
        break;
        case 2: output_x(0b00000011);
        break;
        case 3: output_x(0b00000100);
    }
}
```


----------



## rockoztar (Sep 29, 2015)

¿Qué tal?
Puse esto de código pero creo que está mal porque no inicia nada.
Si se compila pero no funcionó en el protoboard.

```
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#define puerto_b
#define puerto_a

int contador=(PIN_A0);
int x;

void semaforo(void)
{

    if(contador > 3) contador = 0;
        contador++;
    switch (contador)
    {
        case 1: output_high(0b00000001);
        break;
        case 2: output_high(0b00000011);
        break;
        case 3: output_high(0b00000100);
    }
}

void main()
{

set_tris_b(0x00);
set_tris_a(0x03);
output_b(0);
semaforo();


}
```


----------



## TRILO-BYTE (Sep 29, 2015)

*deben usar la logica* 

void main()
{

//set_tris_b(0x00);
//set_tris_a(0x03);
//output_b(0);
while(true)
{
semaforo();

}
}


----------



## rockoztar (Oct 1, 2015)

Que tal... tengo un nuevo programa para el proyecto que estoy haciendo... pero tiene unos detalles... Podrian checarlo?

*Cuando quiero pasar al modo 2... solo me permite entrar si presiono el boton 2 antes de terminar la secuencia de automatico (Y eso es solo a veces)
*Cuando estoy en el modo 2 y quiero avanzar de luz en luz... como que me da rebotes.. porque cambia de luz pero se regresa a la anterior... Si necesitan fotos de como lo tengo en proto me dicen y las subo.

Creo que esos son los errores que me esta dando.
Anexo el codigo aqui abajo... Saludos!!




```
#include <16f628a.h>          //PIC a utilizar
#fuses INTRC_IO,NOWDT,NOPROTECT,NOPUT       //ordenes para el programador
#use delay (clock=4000000) //Se usaran retardos tomando en cuenta que la frecuencia del
//oscilador es de 4Mhz
#use fast_io(a)         //Rápida entrada y salida
 
  
int Modo=1, Temp=1, i=0;  //Declaración de variables del tipo entero
 
//Prototipo de la funcion que configurara los puertos
void Config_Puertos(void);
//Funciones de interrupciones
#INT_EXT     //Para la interrupción INT (RB0)
void EXT_isr(void)
{
Modo++;
if(Modo==3)
{
Modo=1;
Temp=1;
}
}
 
#INT_RB       //Para la interrupción RB (RB4)
 
void RB_isr(void)
{
if(input(PIN_B4))
{
    Temp++;
delay_ms(150);
}
if(Modo==1 && Temp==2)
{
   delay_ms(150);
Temp=1;
delay_ms(150);
}
if(Modo==2 && Temp==4)
{
    delay_ms(150);
Temp=1;
delay_ms(150);
}
}
///Programa principal
 
void main(void)
{
Config_Puertos();//Llamado a funcion
while(true)
{
if(Modo==1)//Modo automatico
{
output_low(PIN_A2); //led verde off
output_low(PIN_A1); //led amarillo off
output_low(PIN_A0); //led rojo off
if(Temp==1)//Temporizacion 1
{
output_high(PIN_A2); //led verde on
delay_ms(6000);
output_low(PIN_A2); //led rojo off
for(i=0;i<=3;i++)
{
output_high(PIN_A2); //DESTELLO led verde on
delay_ms(500);
output_low(PIN_A2); //led verde off
delay_ms(500);
}
output_high(PIN_A1); //led ambar on
delay_ms(2000);
output_low(PIN_A1); //led ambar off
output_high(PIN_A0);//led rojo on
delay_ms(4000);
output_low(PIN_A0); //led rojo off
}
}

if(Modo==2)//Modo manual
{
while(Temp==1)
{
    
output_high(PIN_A2); //led verde on
output_low(PIN_A1); //led amarillo off
output_low(PIN_A0); //led rojo off
}
while(Temp==2)
{
    
output_low(PIN_A2); //led verde off
output_high(PIN_A1); //led amarillo on
output_low(PIN_A0); //led rojo off
}
while(Temp==3)
{
    
output_low(PIN_A2); //led verde off
output_low(PIN_A1); //led amarillo off
output_high(PIN_A0); //led rojo on
}
}
} //bucle infinito
}
 
 void Config_Puertos(void)
{
set_tris_A(0xF8); //portA como salidas(RA0, RA1 y RA2 ,las demas desactivadas)
set_tris_B(0xFF);
enable_interrupts(GLOBAL); //todas las interrupciones activadas
enable_interrupts(INT_EXT);//Habilitando interrupcion externa (RB0)
enable_interrupts(INT_RB);//Habilitando interrupciones de cambio de nivel (RB4-RB7)
ext_int_edge(H_TO_L);//Seleccionando flanco de interrupcion externa
output_low(PIN_A2); //led verde off
output_low(PIN_A1); //led amarillo off
output_low(PIN_A0); //led rojo off
Modo=1;
Temp=1;
}
```


----------



## TRILO-BYTE (Oct 2, 2015)

Pues no me gusta nada el codigo

Yo lo empezaria desde 0 .
Hay maneras de quitar el rebote sin meter delay


----------



## rockoztar (Oct 3, 2015)

¿De qué forma podría quitar el rebote sin meterle los delays? 

Consideraré la opción de empezarlo de 0. 

Pero si tienen consejos que me puedan dar, serían de mucha ayuda.

Gracias.


----------



## TRILO-BYTE (Oct 3, 2015)

no todo esta peladito y en la boca

hay que buscar en el foro


----------



## ruben90 (Oct 3, 2015)

Jajajaja el trilo-byte.

Mejor usa interrupciones. Te ahorras el problema de 2 o mas botones presionado. Y lee mi amigo, este foro es ya un ultimo recurso.


----------



## TRILO-BYTE (Oct 3, 2015)

Pues sí, es que se le ayuda a quien tiene un código funcional o un hardware funcionando.

Pero este código está mal desde el inicio.


----------



## rockoztar (Oct 14, 2015)

Sí, mi código estaba mal desde el inicio.
Pensé en otro que aún no está al 100%, funciona pero tiene un detalle que tal vez es sencillo, pero no sé cómo corregir.
Cuando llega al case 4 se queda en ese, ya no sale cuando presiono el PIN_A1 (rutina)

El detalle de los rebotes lo adapte con un post que vi de D@arkbytes con una librería que él sugería.
Tengo poco en lenguaje C y entre lo que he leído y visto en esto foro, llegue a este código.

TRILO-BYTE: Éste código si funciona, hasta cierto punto. Jejeje.

```
#include <16f628a.h>
#include <button.c>              //libreria donde esta la funcion rand(); 
#include <STDLIB.H>
#fuses   INTRC_IO,NOWDT,NOPROTECT
#use     delay(internal = 4MHz)
void main (void)
{
    int8 A2,A3,i,rutina,subrutina,avance,avance2=0;

    
   while (true)
   {
      output_b(0xFF);
     
        
      if (button(pin_a1,0,255,10,A2,1))       
          {    
          delay_ms(250);
          if(rutina>3){rutina=0;};
          rutina++;  
          } 
      
      if (button(pin_a0,0,255,10,A3,1))     
         {
          delay_ms(250);
          if(subrutina>2){subrutina=0;};
          subrutina++;
         }
 
                  switch(rutina){
                            case 1:
                                                             switch(subrutina){
                                                                             case 1:
                                                                                   output_low(PIN_B2); //ENCENDIDO VERDE
                                                                                   break;

                                                                             case 2:
                                                                                   output_low(PIN_B1);   //ENCENDIDO AMBAR
                                                                                   break;

                                                                             case 3:
                                                                                   output_low(PIN_B0);   //ENCENDIDO ROJO
                                                                                   break;
                                                                              }                                 
                                   break;

                            case 2:
                                   output_low(PIN_B2); //
                                   output_low(PIN_B0); //
                                 
                                                            
                                   break;

                            case 3:
                                   output_low(PIN_B1);  //
                                   output_low(PIN_B0);   // 
                                   break;
                                
                            case 4:
                                
                           
                                output_low(PIN_B2); //
                                   delay_ms(3000);
                                   output_high(PIN_B2); //
                                   
                                   for (i=0;i<=3;i++)   
                                   {
                                   output_low(PIN_B2); //
                                   delay_ms(500);
                                   output_high(PIN_B2); //
                                   delay_ms(500);
                                   }
       
                                   output_low(PIN_B1); //
                                   delay_ms(1500);
                                   output_high(PIN_B1); //
       
                                   output_low(PIN_B0); //
                                   delay_ms(3000);
                                   output_high(PIN_B0); //
                                   break;
                  
                  
                  
                                 }          
               
    }
}
```


----------



## TRILO-BYTE (Oct 15, 2015)

*E*s que ese c*ó*digo est*á* *MAL.*

*L*o que pasa, es que la librer*í*a del bot*ó*n funciona, pero lo que est*á*s haciendo mal es meter DELAY, eso te atora el micro 10 segundos y medio en el caso 4.

*A*toras el micro sin hacer nada y obviamente no va a funcionar adecuadamente el c*ó*digo*.*


----------



## rockoztar (Oct 16, 2015)

Imagine que meter esos delays me generarian problemas  , pero era lo unico que conocia para realizar esa funcion. Entre las publicaciones que he checado encontre este tuyo, me recomiendas utilizar contadores para controlar el tiempo que ocuparé el encendido de cada LED? Espero que con algo asi ahora si pueda cambiar de caso. Estoy en toda la disposicion de seguir leyendo y buscar mas ejemplos aqui en el foro. Tengo como 2 semanas apenas con esto. 
Gracias por responder. 



Saludos!


----------



## TRILO-BYTE (Oct 16, 2015)

me conmueve tu honestidad y tu lucha por conocimiento 

te explicare:

el sistema Multitarea consiste en hacer una base de tiempo, esta base de tiempo parte de una unidad fija de reloj.

digamos 50us 

obteniendo esta base de reloj podemos sacar muchos multiplos de este reloj, puede ser mas pequeño

todo depende de los ticks del CPU

ejemplo

1 tick= 1/(fosc/4)

digamos que tenemos un cristal de 20Mhz

1 tick estaria dado en 20/4= 5Mhz ahora 1/5Mhz 
nos daria 0.2us como un tick

que significa que cada instruccion se ejecutaria a 0.2us asi que esa seria nuestra frecuencia limite para hacer un timer o base de tiempo.

pero por comodidad haremos un ejemplo con un* timer de 1ms*

en el CCS tenemos la estructura del timer de la siguiente manera:


```
#INT_TIMER0
void TIMER0_isr(void)
{
   //codigo
}
```

esta estructura nos permite hacer un desbordamiento de timer con la cual podemos hacer nuestra base de tiempo

hay calculadoras para hacer un calculo rapido para el desbordamiento de timer en lo particular me gusta el *Pic Timer Calculator 0.9.0*

hay que hacer unos calculillos para obtener la frecuencia de desbordamiento del timer.

en este caso busque el resultado del timer con un cristal de 20Mhz para timer 0

y me dio los siguientes resultados:

timer 0
preescaler 1:32
modo 8 bit
y el modo de interrupcion es 100

ahora el codigo quedaria del siguiente modo 



```
#INT_TIMER0
void TIMER0_isr(void)
{
   //codigo
   set_TIMER0(100);   //desborda cada 1ms
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}
```

y en el main quedaria asi:


```
void main()
{

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32|RTCC_8_bit); //preescaler a 32 y 8 bits
   enable_interrupts(global);
while(1)
{
//codigo
}

}
```



ahora ya que tenemos toda la base de la estructura del programa nos falta hacer nuestra base de tiempo que es la que nos importa como dije 

esta interrupcion se dara cada 1ms

podemos generar tiempos de 1,2,3 segundos o 50ms, 500ms ,etc.
siempre y cuando no sean menores a 1ms

ahora lo que falta es hacer uso de variables globales para hacer las cuentas tanto en la interrupcion como usarlas en el main


eso se hace asi:


```
#include<blabla.h>
#include <etc.c>
y asi ...


int16 contador; //lo usaremos para contar 1000milisegundos que forman 1 segundo
char segundo1,segundo2,segundo3; //seran nuestros segundos


#INT_TIMER0
void TIMER0_isr(void)
{
   contador++;
   if(contador>=1000)
   {
      contador=0; //reiniciamos la cuenta
       segundo1++;
       segundo2++;
       segundo3++;
   }

   set_TIMER0(100);   //desborda cada 1ms
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}




void main()
{

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32|RTCC_8_bit); //preescaler a 32 y 8 bits
   enable_interrupts(global);
   while(1)
   {
     if(segundo1>=3) //si son 3 segundos prende led
     {
        segundo1=0;
        //prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              //apagamos o hacemos otra cosa  
           }

      if(segundo2>=1) //si son 1 segundos prende led
     {
        segundo2=0;
        //prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              //apagamos o hacemos otra cosa  
           }


     if(segundo3>=60) //si son 60 segundos prende led
     {
        segundo3=0;
        //prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              //apagamos o hacemos otra cosa  
           }


   }//fin de while

}// fin del main
```



*y asi bajita la mano hisimos un proseso multitarea en el prendido de 3 leds con 3 tiempos diferentes*

los 3 son totalmente independientes , estudia el codigo, piensalo, juega con el

y seguimos con el proseso de 

*LECTURA DE BOTONES*

sin rebotes con multitarea


----------



## rockoztar (Oct 16, 2015)

Ya quedo! Deja le doy una buena leida porque son varias cosas, lo estudio y escribo mis dudas. Neta muchas gracias por responder a mi post. 

Saludos!


----------



## rockoztar (Oct 19, 2015)

¿Qué tal, TRILO-BYTE? Ya estuve leyendo tu programa.
Este fin de semana no pude trabajar en el, hasta ahorita, pero creo que estoy haciendo algo mal, no sé si en los fuses o si tengo que agregar alguna librería.
Si puedo compilar el código, pero no hace nada el micro.

Este es el código que puse. (NOTA: puse 4000000 porque es el cristal que tengo.)
Te anexo la imagen del Timer Calculator, el dato de 131 fue el que agregué en el código.

Saludos!


```
#include <16f628a.h>
            //libreria donde esta la funcion rand(); 

#fuses   INTRC_IO,NOWDT,NOPROTECT
#use delay(clock=4000000)




  int16 contador; //lo usaremos para contar 1000milisegundos que forman 1 segundo
char segundo1,segundo2,segundo3; //seran nuestros segundos


#INT_TIMER0
void TIMER0_isr(void)
{
   contador++;
   if(contador>=1000)
   {
      contador=0; //reiniciamos la cuenta
       segundo1++;
       segundo2++;
       segundo3++;
   }

   set_TIMER0(131);   //desborda cada 1ms
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}




void main()
{

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_32|RTCC_8_bit); //preescaler a 32 y 8 bits
   enable_interrupts(global);
   while(1)
   {
     if(segundo1>=3) //si son 3 segundos prende led
     {
        segundo1=0;
        output_high(PIN_B0);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
             output_low(PIN_B0); //apagamos o hacemos otra cosa  
           }

      if(segundo2>=1) //si son 1 segundos prende led
     {
        segundo2=0;
        output_high(PIN_B1);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              output_low(PIN_B1);//apagamos o hacemos otra cosa  
           }


     if(segundo3>=60) //si son 60 segundos prende led
     {
        segundo3=0;
        output_high(PIN_B2);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              output_low(PIN_B2);//apagamos o hacemos otra cosa  
           }


   }//fin de while

}// fin del main
```



Aquí está la imagen, no se había subido.


----------



## TRILO-BYTE (Oct 19, 2015)

no se aver prueba asi:

```
#include <16f628a.h>
            //libreria donde esta la funcion rand(); 

#fuses   XT,NOWDT,NOPROTECT //con cristal 
#use delay(clock=4M) // 4 Mhz




  int16 contador; //lo usaremos para contar 1000milisegundos que forman 1 segundo
char segundo1,segundo2,segundo3; //seran nuestros segundos


#INT_TIMER0
void TIMER0_isr(void)
{
   contador++;
   if(contador>=1000)
   {
      contador=0; //reiniciamos la cuenta
       segundo1++;
       segundo2++;
       segundo3++;
   }

   set_TIMER0(6);   //desborda cada 1ms
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}




void main()
{

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4|RTCC_8_bit); //preescaler a 4 y 8 bits
   enable_interrupts(global);
   while(1)
   {
     if(segundo1>=3) //si son 3 segundos prende led
     {
        segundo1=0;
        output_high(PIN_B0);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
             output_low(PIN_B0); //apagamos o hacemos otra cosa  
           }

      if(segundo2>=1) //si son 1 segundos prende led
     {
        segundo2=0;
        output_high(PIN_B1);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              output_low(PIN_B1);//apagamos o hacemos otra cosa  
           }


     if(segundo3>=60) //si son 60 segundos prende led
     {
        segundo3=0;
        output_high(PIN_B2);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     else{ 
              output_low(PIN_B2);//apagamos o hacemos otra cosa  
           }


   }//fin de while

}// fin del main
```


----------



## rockoztar (Oct 20, 2015)

Anexo fotos de como lo tengo conectado... sigue sin funcionar... Espero que solo sea algo sencillo.    Solo tengo esos jumpers :S asi que por eso se ve todo feo.


----------



## rockoztar (Oct 22, 2015)

Encuentras algo raro en la conexión? Lo volvi a programar en otro micro y nada :/


----------



## TRILO-BYTE (Oct 22, 2015)

¿El pin de MCRL tiene una resistencia de 10 KΩ a VCC?



A ver, creo que planteé mal el programa, porque sólo un instante de tiempo se mantiene encendido y lo demás está apagado.



Prueba lo siguiente:

*El programa lo ando planteando mal desde hace años*, pero ya está corregido. 


```
#include <16f628a.h>
            //libreria donde esta la funcion rand(); 

#fuses   XT,NOWDT,NOPROTECT //con cristal 
#use delay(clock=4M) // 4 Mhz




  int16 contador; //lo usaremos para contar 1000milisegundos que forman 1 segundo
char segundo1,segundo2,segundo3; //seran nuestros segundos


#INT_TIMER0
void TIMER0_isr(void)
{
   contador++;
   if(contador>=1000)
   {
      contador=0; //reiniciamos la cuenta
       segundo1++;
       segundo2++;
       segundo3++;
   }

   set_TIMER0(6);   //desborda cada 1ms
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto
}




void main()
{

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4|RTCC_8_bit); //preescaler a 4 y 8 bits
   enable_interrupts(INT_TIMER0);  //ME FALTO ESTA INSTRUCCION MUY IMPORTANTE!!!
   enable_interrupts(global);
   while(1)
   {


//corregido andaba planteando mal el programa, lo planteaba para hacer PWM y no para 
//una señal cuadrada, para que una señal sea cuadrada deben durar los 2 periodos
//el mismo tiempo por eso la segunda sentencia va al doble de la primera


     if(segundo1>=3) //si son 3 segundos prende led
     {
      output_high(PIN_B0);//prendemos led eso depende del pin que uses o hacer otra cosa
     }
     if(segundo1>=6)
     {
      segundo1=0;
      output_low(PIN_B0);
     }

      
      
     if(segundo2>=1) //si son 1 segundos prende led
     { 
      output_high(PIN_B1);//prendemos led eso depende del pin que uses o hacer otra cosa 
     }
     if(segundo2>=2)
     {
      segundo2=0;
      output_low(PIN_B1);
     }
     


     if(segundo3>=5) //si son 5 segundos prende led
     {
      output_high(PIN_B2);//prendemos led eso depende del pin que uses o hacer otra cosa
     }     
     if(segundo3>=10)
     {
      segundo3=0;
      output_low(PIN_B2);
     }



   }//fin de while

}// fin
```


----------



## rockoztar (Oct 22, 2015)

Dame unos segundos mientras cargo el nuevo codigo... ahorita te digo que paso. Gracias TRILO



Listo, los contadores estan funcionando!


----------



## TRILO-BYTE (Oct 22, 2015)

Ahora debes empezar a plantear por ti mismo la escritura de una LCD.

Digamos, encender un led cada 0.5 segundos, generar un tren de pulsos a unos cuantos Kilohertz y escribir en la LCD una palabra cada 2 segundos y al mismo tiempo leer un ADC y mostrarlo en la LCD.

Todo eso es posible, gracias al TIMER.


----------



## rockoztar (Oct 22, 2015)

Voy a escribir un programa con eso que pides.
Creo que tengo un LCD por aquí, pero también voy a ir metiendo el Timer 0 en mi programa con el que estaba teniendo problemas. (El del semáforo)
Aunque aún falta ver lo de los botones con multitarea.

De verdad muchas gracias por la paciencia y por enseñarme como funciona el Timer. 
Seguiré publicando los avances.


----------



## rockoztar (Nov 11, 2015)

Que tal, estoy de regreso para seguir con el aprendizaje... estuve fuera de esto por motivos de trabajo :/ pero les dejo un semáforo con tiempo fijo realizado con timer0, lo que realmente necesito hacer es un semaforo con 4 funciones... Tiempo fijo, Luces aleatorias(random), Avanzar luz por luz (Manual) y Avanzar luz por luz (Random).  Necesito utilizar 2 push.

TRILO-BYTE, seguia lectura de botones sin rebotes con timer0  de verdad gracias... dejo el programa aqui.



```
#include <16f628a.h> 
         

#fuses   XT,NOWDT,NOPROTECT //con cristal  
#use delay(clock=4M) // 4 Mhz 




  int16 contador; //lo usaremos para contar 1000milisegundos que forman 1 segundo 
char segundo1,segundo2,segundo3; //seran nuestros segundos 


#INT_TIMER0 
void TIMER0_isr(void) 
{ 
   contador++; 
   if(contador>=1000) 
   { 
      contador=0; //reiniciamos la cuenta 
       segundo1++; 
       segundo2++; 
       segundo3++;
   } 

   set_TIMER0(6);   //desborda cada 1ms 
   clear_interrupt(INT_TIMER0);      // limpia la bandera de interrupcion CCS lo hace por defecto 
} 




void main() 
{ 

   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4|RTCC_8_bit); //preescaler a 4 y 8 bits 
   enable_interrupts(INT_TIMER0);  //IMPORTANTE 
   enable_interrupts(global); 
   while(1) 
   { 


//corregido andaba planteando mal el programa, lo planteaba para hacer PWM y no para  
//una señal cuadrada, para que una señal sea cuadrada deben durar los 2 periodos 
//el mismo tiempo por eso la segunda sentencia va al doble de la primera 


       
//ENCENDIDO DE VERDE Y DESTELLO DE VERDE//
//ESTOY USANDO TRANSISTORES 3906 POR ESO EL ENCENDIDO LO TENGO EN LOW//     
     
       
       if(segundo1<=3)
       {
           output_low(PIN_B0); //PRENDE VERDE
       }
       
                              //DESTELLO DE VERDE//
       
                             if(segundo1>=4)
                             {
                                        if(contador<=500)
                                           {
                                            output_high(PIN_B0);
                                           }
                                        if(contador>=500)
                                           {
                                            output_low(PIN_B0);
                                           }
                              }
      
          
                                
                     if(segundo1>=6)
                        {
                         output_high(PIN_B0);    
                        }
     
       
                    if(segundo1>=10)   //REGRESO A 0 EL CONTADOR SEGUNDOS1
                    {
                     segundo1=0;
                    }
     
       
       
         //ENCENDIDO DE AMBAR//
       
       
             if(segundo2<=5)
             {
              output_high(PIN_B1);
              }
       
                      if(segundo2>=6)
                       {
                       output_low(PIN_B1);
                       }
       
                           if(segundo2>=7)
                             {
                             output_high(PIN_B1);
                              }
       
                                  if(segundo2>=10)
                                  {
                                   segundo2=0;
                                   }
       
       
       
          //ENCENDIDO DE ROJO//
       
                   if(segundo3<=6)
                    {
                     output_high(PIN_B2);
                     }
       
                             if(segundo3>=7)
                                {
                                 output_low(PIN_B2);
                                   }
       
                                        if(segundo3>=10)
                                        {
                                          output_high(PIN_B2);
                                          segundo3=0;
                                         }
       
       
       
       
    }   //CIERRO WHILE
} //CIERRO MAIN
```


----------



## TRILO-BYTE (Nov 11, 2015)

muy bien muy bien 

felicidades hay compañeros que por mas que se les explica siguen usando delay 

ya quitaste delay de tu sistema es muy buen avance.

por ahi creo que dario puso una libreria para usar botones 
no la he revisado pero supongo que su codigo es mas eficiente que el mio.
creo que esta dentro de este mismo tema


----------



## rockoztar (Nov 11, 2015)

Dario es D@arkbytes? Porque si es el mismo, yo utilice la libreria que el subio (botton) y viene en mi programa anterior. 

Entonces lo que puedo hacer es juntar la libreria del Push y el timer0? 
Crees que con eso pueda hacer lo que dije en el mensaje anterior? 


Saludos
Y gracias por responder a mis mensajes y explicarme lo del timer0 (Y)


----------



## D@rkbytes (Nov 11, 2015)

rockoztar dijo:


> ¿Dario es D@rkbytes? Porque si es el mismo, yo utilicé la librería que él subió (button) y viene en mi programa anterior.


@Dario, antes D@rio, y yo, D@rkbytes, somos personas diferentes.
Tal vez te cause confusión porque Dario antes tenía el @ en su nick, pero pidió un cambio de nick y ahora es  Dario.


----------



## Dr. Zoidberg (Nov 11, 2015)

Doble personalidad virtual...
Interesante tema para una tesis de psicología.


----------



## TRILO-BYTE (Nov 12, 2015)

hay muchos darios asi como davits digo trilo-bytes es la misma gata pero revolcada

lo que digo SI puedes usar la libreria

¿hay conflictos con timer?

no se no he revisado la libreria pero pues el pic deberia traer otro TIMER si hay algun conflicto
digamos ya estoy usando timer 1 en XY cosa especifica usamos otro


----------



## rockoztar (Nov 12, 2015)

Gracias por la aclaración y por la ayuda. Ya busqué quien es Dario, buscaré la librería que publicó y comento como me fue con eso.

*Como no cumplo las Políticas del Foro, me editaron el mensaje.*


*Normas del Foro 2.9* Los usuarios no pueden publicar, solicitar ni difundir información que promueva el plagio, la piratería, la divulgación de números de serie, crack o similares, o copias no autorizadas de material protegido por derechos de autor.​


----------



## D@rkbytes (Nov 12, 2015)

rockoztar dijo:


> Gracias por la aclaración y por la ayuda.
> Ya busqué quien es Dario, buscaré la librería que publicó y comento cómo me fue con eso.


Si te refieres a la librería "Button.c", yo la publiqué aquí en el Foro, comentando que no es de mi autoría.


D@rkbytes dijo:


> Hace algún tiempo, buscando una buena solución  para el problema de los rebotes en los pulsadores, encontré una librería  escrita en C para PIC C Compiler.
> Esta librería surge de una instrucción de PICBasic "*BUTTON* _Pin_*,*_Down_*,*_Delay_*,*_Rate_*,*_BVar_*,*_Action_*,*_Label" _que  sirve muy bien para este propósito y lo que hace esta librería es muy  similar, pues fue realizada para imitar a la instrucción de PICBasic,  pero sin el salto a otra subrutina "_Label"_.
> El autor, del cual ya no recuerdo su nombre ni el sitio, describe detalladamente las funciones que usó para crear la rutina *button*, y también los parámetros a usar.
> 
> ...


Descarga: Librería Button.c


----------



## rockoztar (Nov 12, 2015)

Yo ya use esa libreria y da 0 rebotes... lo unico que no se es si esa es la libreria a la que se refiere TRILO. 

Esa ya la tengo descargada.  Gracias D@rkbytes.... lo que hare es probar esa libreria con mi codigo de TIMER0.


----------



## TRILO-BYTE (Nov 12, 2015)

es que segun yo 
puede que este mal 

hay rebotes cuando se trabaja con botones ligeramente en mal estado.

paso 1 

quitar rebotes haciendo un decremento en el timer y preguntar cuando se pisa el boton la secuencia es mas o menos asi:
¿boton pisado?
¿llego a 0?
si no es 0 volver a cargar X cuenta

pero que pasa si soltamos el boton y lo apretamos rapidamente es decir empezamos a joder el sistema para ver que pasa

debe haber una funcion Extra para revisar si el boton ya se solto o no se ha soltado.

void soltar()
{
¿boton 1 suelto?
{
suelta=0
}
}


en el main se haria la siguiente pregunta

¿boton1 pisado && suelta != 0?
{
¿decremento igual o menor a 0?
{
//hacer lo que tenemos que hacer
}

}

else

{
cargamos con X valor la cuenta regresiva
}


parece complicado pero juro que es un efectivo antirebote


----------



## rockoztar (Nov 12, 2015)

Dame chance de checarlo y te digo como me va. Ahorita vengó en el metro y no pude leerlo bien. Gracias!


----------

