# Encender leds en C



## J.D.R. (Oct 20, 2007)

como están quiero hacer un programa que cuando toque un pulsador se prendan varios led, alguien tiene algún modelo o me puede dar una idea de como se hace en lenguaje C


----------



## pic-man (Oct 20, 2007)

Hola, aqui te paso un ejemplo sencillo para encender un led al presionar un push button y un diagrama de como conectarlo, es un ejemplo muy básico (apenas voy empezando en esto de la programación C) pero te puede servir.


----------



## J.D.R. (Oct 21, 2007)

como esta amigo pic-man ese ejemplo me ayudo un poco pero lo que necesito es que cuando yo precione el push button el led se quede encendido hasta que yo lo precione de nuevo, osea que funcione como un interructor


----------



## maunix (Oct 23, 2007)

J.D.R. dijo:
			
		

> como esta amigo pic-man ese ejemplo me ayudo un poco pero lo que necesito es que cuando yo precione el push button el led se quede encendido hasta que yo lo precione de nuevo, osea que funcione como un interructor



Podes usar una variable auxiliar y que el LED siga a la variable auxiliar.

El punto es que tengas  en cuenta el rebote del pulsador así como solamente tomar el cambio cuando el usuario pulse el boton pero no salir de la rutina hasta que no lo suelte, todo esto es  para que no esté permanentemente cambiando el LED.

La salida puedes usar una XOR, si tienes tu pin definido puedes hacer algo asi como

PIN ^= 1;

Saludos


----------



## pic-man (Oct 23, 2007)

maunix yo intenté hacer lo que dijiste en el CCS pero el compilador me marcaba algunos errores, el problema es que no se programar en C y aunque ya estoy documentandome y leyendo un libro de C quisiera, si tuvieras tiempo, que me dijeras como se podría modificar el programa que yo hice para que el led se mantuviera encendido hasta que se volviera a presionar el botón, quiero aprender y ya estoy en ello pero muchas veces los ejemplos son buenos maestros


----------



## maunix (Oct 23, 2007)

pic-man dijo:
			
		

> maunix yo intenté hacer lo que dijiste en el CCS pero el compilador me marcaba algunos errores, el problema es que no se programar en C y aunque ya estoy documentandome y leyendo un libro de C quisiera, si tuvieras tiempo, que me dijeras como se podría modificar el programa que yo hice para que el led se mantuviera encendido hasta que se volviera a presionar el botón, quiero aprender y ya estoy en ello pero muchas veces los ejemplos son buenos maestros



pic-man, no uso CCS por ello no puedo compilar el proyecto pero si me dices qué errores te tira tal vez te pueda dar una mano.


----------



## pic-man (Oct 23, 2007)

El error ahora no lo recuerdo, pero ya logré solucionar el problema que planteó J.D.R. utilizando la función OUTPUT_TOGGLE() del compilador CCS, resultó ser muy sencillo, ahora al pulsar el botón se enciende el led y permanece encendido hasta que se vuelve a pulsar, este es el código:

```
void main()
{

set_tris_b( 0x01 );           // RB0 como entrada y lo demás del puerto B como salida
puerto_b = 0;                 // Limpia puerto B

DO{

   IF (INPUT(PIN_B0)){        // Si se presiona RB0
      output_toggle(PIN_B1);  // cambia el estado del pin RB1
      WHILE (INPUT(PIN_B0));  // Espera a que se suelte el botón
      }
   }
WHILE(TRUE);
}
```

Adjunto de nuevo un archivo comprimido con el código y el esquemático para este proyecto.

maunix, qué compilador usas tú? Yo soy nuevo en esto y el CCS fue el primero que instalé pero me gustaría tambien probar otros para poder ver cual me funcionaría mejor, me puedes recomendar alguno?


----------



## maunix (Oct 25, 2007)

A mi me gusta le C18 para los 18F, y el Hi.tech para los 16F aunque no lo he usado mucho , en los 16f programo todo en assembly porque hace años lo hago y tengo muchas cosas ya desarrolladas, probadas y que sé que funcionan.

El defecto que le veo a tu soft es que si hay rebotes puede que se la pase titilando un buen rato solo.  Yo que después de verificar el input, hago un retardo de tiempo y lo vuelvo a verificar, no se 5 veces y si en las 5 veces estuvo desactivado entonces es porque realmente se soltó la tecla.


----------



## J.D.R. (Oct 27, 2007)

comos les va probé ese programa en un protoboards y no me funciona lo hice con el 628A y el 84A y no me funciona y ya lo e armado y desarmado unas cuantas veces incluso lo cambie de protoboards  y sigue igual no me da ninguna respuesta sera por el rebote del pulsador o que


----------



## xupisoft (Oct 28, 2007)

yo tambien soy un novatillo en esto, pero he estado practicando, hice un pequeño programa para encender y apagar un led cuando pulsas el pulsador, pero tuve en cuenta un pequeño rebote, lo pongo aqui, en la simulación lo probé y funciona, supongo que a la hora de la verdad también funcionara. El microcontrolador es el pic16f84

```
//// Programa para encender y apagar un led pulsando un pulsador ////

#include <16f84a.h>                 // incluimos la libreria para este pic
#fuses XT,NOWDT,NOPROTECT           // configuramos los fusibles de programacion
                                    // XT - cristal de cuarzo
                                    // NOWDWT - no perro guardian
                                    // NOPROTECT - no protegido
#use delay(clock=4000000)           // velocidad de reloj en HZ



//// Declaración de variables ////

#byte pb = 6   // puerto B
#byte pa = 5   // puerto A

//// Configuramos salidas y entradas ////


void main (void)
{
pb = 0;
set_tris_b (0x00);                  // Declaramos puerto B como salida
set_tris_a (0x1F);                  // Declaramos puerto A como entrada

   DO
   {
      If (!input (PIN_A0))          // Si la entrada es 0
      {  delay_ms (10);             // esperamos 10 ms
         If (!input (PIN_A0))       // comprobamos otra vez la entrada sea 0, por temas de rebote
         {  do { } while (!input (PIN_A0));  // esperar a soltar el boton
            pb = ~pb;               // el puerto b cambia al complementario.
         }
         
      }
   } WHILE (TRUE);                  // Bucle infinito 
}
```


----------



## Jose 8 (Ene 28, 2011)

Aguno de ustedes me podria ayudar a hacer esto mismo pero con Pic Basic Pro, estoy aprendiendo apenas a utlizar este compilador y me gustaria tambien poder implementarlo. O si en PBP existe alguna instruccion como la que comenta en el programa para que cambie al complementario.

 pb = ~pb;               // el puerto b cambia al complementario.


----------



## gzaloprgm (Ene 28, 2011)

No deberías haber respondido en el mismo thread, pero en PBP es bastante sencillo hacerlo:


```
LED VAR PORTB.0 'Declaramos la dirección de LED

Toggle LED 'Invertimos el estado de led
Led = 0 'Apagamos led
Led = 1 'Prendemos led
```
Un saludo,
Gonzalo


----------



## jjavivi (Sep 28, 2011)

Buenas a todos, pues yo siempre me complico mucho y me salio este codigo, estoy empezando como todos vosotros, eso si, yo lo que hago es contar las pulsaciones para apagarlo y encenderlo:

#include <16F628A.h>
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#use delay(clock=4000000,RESTART_WDT)
#byte puerto_a = 5
#byte puerto_b = 6

void main()
{  int a;
   SET_TRIS_A ( 0b01100 );
   SET_TRIS_B ( 0b00000011 );
   puerto_a=0;  //reincio puerto a 0
   puerto_b=0 ; //reincio puerto a 0            

   while ( TRUE ){

   if (input(pin_b1)==1){ 
   delay_ms(400);    //antirebote
   a=a+1;}

   if (a==1){
   output_high(PIN_B2);}


   if (a==2){   
   output_low(PIN_B2);
   a=0;}
   } 
 }


----------



## Aldous (Oct 17, 2012)

Saludos colegas,

Voy empezando a trabajar con los microcontroladores y en este caso me hice de un PIC16F877a porque lo necesito para la escuela.

En fin, estoy usando el PCW para programar y necesito ayuda porque he estado viendo algunos tutoriales pero son únicamente para simulaciones en proteus, que al implementarlos no funcionan. En base a los tutoriales vistos yo realice el programa que más abajo les anexo y que no funciona implementado porque me faltan declarar muchas cosas como entradas y salidas, por ejemplo. Quisiera saber si alguien me puede ayudar con el programa, este consiste en que si la entrada RB0 recibe una señal a través de un push button, la salida RC0 nos de una señal que encienda un LED, si la entrada RB1 recibe una señal, el RC1 encienda un LED y así sucesivamente hasta completar del RB0 al RB7 y del RC0 al REC7 y de esta forma si presionamos el push buttom 1 se prende el LED 1, pero que solo se encienda mientras lo mantengamos oprimido, si lo soltamos que se apague y así con los demás push buttoms y LED's.


```
void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //Todos estos setup yo no los declare,
   setup_timer_1(T1_DISABLED);                         al utilizar el wizard me los arrojo
   setup_timer_2(T2_DISABLED,0,1);                    por default.
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

while (true) {

if (input (pin_b0)) {
output_high(pin_c0);
}
if (!input (pin_b0)) {
output_low(pin_c0);
}

if (input (pin_b1)) {
output_high(pin_c1);
}
if (!input (pin_b1)) {
output_low(pin_c1);
}
if (input (pin_b2)) {
output_high(pin_c2);
}
if (!input (pin_b2)) {
output_low(pin_c2);
}
if (input (pin_b3)) {
output_high(pin_c3);
}
if (!input (pin_b3)) {
output_low(pin_c3);
}
if (input (pin_b4)) {
output_high(pin_c4);
}
if (!input (pin_b4)) {
output_low(pin_c4);
}
if (input (pin_b5)) {
output_high(pin_c5);
}
if (!input (pin_b5)) {
output_low(pin_c5);
}
if (input (pin_b6)) {
output_high(pin_c6);
}
if (!input (pin_b6)) {
output_low(pin_c6);
}
if (input (pin_b7)) {
output_high(pin_c7);
}
if (!input (pin_b7)) {
output_low(pin_c7);
}

}
}
```
De antemano, gracias.

Saludos.


----------



## karo001 (Dic 16, 2012)

Disculpen también soy nuevo en el tema y *qu*iero saber si me pueden ayudar tengo 4 button en el RB0-RB3 y 4  leds en los puerto RC0-RC3 mientras yo presione un button se encienda un leds y presiono ese mismo button se debe de apagar así sucesivamente con todos los buton ah*í* les dejo el programa a mi solamente me sale 2 buton y el tercero no me sale espero *que* lo revisen 

```
char pul1, pul2, pul3, pul4;
void main(){
trisb=0xff;
option_reg.F7=0;
trisc=0;
portc=0;
pul1=0;
pul2=0;
pul3=0;
pul4=0;
x1:
if(button(&portb,0,1,0))
pul1=1;
if(button(&portb,0,1,1)&&pul1)
{ portc=portc^0b000000001;
pul1=0;
}
if (button (&portb,1,1,0))
pul2=1;
if (button(&portb,1,1,1)&&pul2)
{portc=portc^0b00000010;
pul2=0;
}
goto x1;
}
```


----------



## D@rkbytes (Dic 16, 2012)

karo001 dijo:


> tengo 4 button en el RB0-RB3 y 4  leds en los puerto RC0-RC3 mientras yo presione un button se encienda un leds y presiono ese mismo button se debe de apagar así sucesivamente con todos los buton


Saludos.
Me parece que este programa responde al post anterior y al tuyo.
Es para un 16F84A, pero el programa principal sirve para otro tipo de PIC.

Suerte.


----------



## stiventronic (Ene 20, 2013)

xupisoft dijo:


> yo tambien soy un novatillo en esto, pero he estado practicando, hice un pequeño programa para encender y apagar un led cuando pulsas el pulsador, pero tuve en cuenta un pequeño rebote, lo pongo aqui, en la simulación lo probé y funciona, supongo que a la hora de la verdad también funcionara. El microcontrolador es el pic16f84
> 
> ```
> //// Programa para encender y apagar un led pulsando un pulsador ////
> ...



Miembro del foro , este código me funciono en un circuito físico, esta bien , la vista no alcanza a percibir tipos de parpadeo en el destello del LED, cumple totalmente al soltar el switche o botón estando presionado en mi caso durante un tiempo de 20s, gracias por este aporte me ayudo muy bien.


----------



## luis1234567890 (Nov 24, 2013)

¿Tendrán una programación en lenguaje C que cuando el pulsador este presionado, no haga nada todavía, pero a la hora de soltarlo realiza una función como  prender un led?
En lenguaje ensamblador me sale pero en C no sé como hacerlo.

Acá un ejemplo de ensamblador para los que no entendieron lo dicho anteriormente.


Presionar un pulsador para prender led.


```
pulsador          ;etiqueta para el goto
btfss portb,0 ;cuando pin rb0 sea 1 salta una instrucción sino sigue ala siguiente instrucción
goto pulsador  ;regresa ala etiqueta pulsador
btfsc portb,0 ;cuando pin rrb0 sea 0 salta una instrucción sino sigue ala siguiente instrucción
goto $-1 ;  retrocede una introducción
milisegundo 100; tiempo rebote para el pulsador
bsf portc,1 ;prender led
goto$
end
```


¿Alguien que sepa como pasarlo a lenguaje c?


----------



## alinew75 (Nov 26, 2013)

Acá te dejo este ejercicio sencillo, con el podrás practicar y sacar lo que necesitas, espero te sirva: 


```
list p=16f84a            ;directiva que define el procesador
    #include <p16f84a.inc>    ;definicion de variables especificas del procesador
    __CONFIG _CP_OFF &_WDT_OFF &_PWRTE_ON &_XT_OSC

    ORG 0X000                ;vector reset de procesador
INTCOM
    CLRF INTCOM                ;desabilito interrupciones
    BSF STATUS,RP0            ;para acceder al banco1 de registro(se escribe rp0 no rpo)osea con cero
    MOVLW 1F
    MOVWF TRISA                ;porta como entrada
    CLRF TRISB                ;portb como salida
    BCF STATUS,RP0            ;para acceder al banco de registros

REP MOVF PORTA,W            ;leo porta en w
    MOVWF PORTB                ;copio en w en potrb
    CLRF 0C                    ;borro la primera posicion de ram
DLY DECFSZ 0C,F                ;decremento la primera posicion de ram
    GOTO DLY                ;genero retardo de apox 767 ciclos
    GOTO REP                ;repito el ciclo

    END.
```


Solo compílalo en mplab y pruébalo.


----------



## carferper (Nov 27, 2013)

intenta el siguiente algoritmo escrito para XC8, lo unico que falta es la configuracion inicial del PIC.


```
#define PRESIONADO 0b0
#define NO_PRESIONADO (!PRESIONADO)
#define DB_TIME 20

#define LED_1 RB0
#define PB_1  RB1

enum flag {ACTIVO, INACTIVO} estado_PB_1 = INACTIVO;

void main(void)
{
    inicializar_puerto();

    while (1)
    {
        if (PB_1 == PRESIONADO){
            __delay_ms(DB_TIME);
            if ((PB_1 == PRESIONADO) && (estado_PB_1 == INACTIVO))
                estado_PB_1 = ACTIVO;
            }

        if ((PB_1 == NO_PRESIONADO) && (estado_PB_1 == ACTIVO)){
            __delay_ms(DB_TIME);
            if (PB_1 == NO_PRESIONADO){
                LED_1 = ~LED_1;
                estado_PB_1 = INACTIVO;
                }
            }
    }
}
```

saludos


----------



## phillipo (Mar 31, 2016)

Buen día. Quiero  encender dos LEDs con el mismo botón pero cada LED está en un puerto diferente.
El PIC es el 16F877A y el lenguje es C, uso PIC C Compiler.


Esta es la parte del código que me falla, todo lo demás está bien.

```
if(input(pin_a2)==1) {
   output_low(pin_d0);      //led verde
   delay_ms(200);
   output_low(pin_c0);       // led rojo
   delay_ms(200);

 if (input(pin_a2)==1)
     output_high(pin_d0);   //led verde
     delay_ms(200);
     output_high(pin_c0);  //led rojo
     delay_ms(200); }
    
  }
}
```

Los problemas que se presentan al simularlo en isis y en la vida real, son: 

1) cuando oprimo el botón (pin_a2) ==1  se apagan los dos leds, el verde y el rojo pero el rojo se enciende de nuevo; cuando vuelvo a presionarlo el botón (pin_a2)== 1 debo hacerlo varias veces para que el led verde se prenda
El rojo si, con cada pulso apaga y enciende al momento.

En pocas palabras y espero no confundirlos, deseo que ambos se apaguen y prendan a la vez.


----------



## yorsk2004 (Mar 31, 2016)

Prueba con esto y me comentas:


```
int1 flag; 						//Bandera
while (true) 						//Hacer siempre
{
	if(input(pin_a2)) 				//Si pin_a2 es presionado...
	{
		output_high(pin_c0);			//Encender pin_c0 
		output_high(pin_d0);			//Encender pin_d0
		flag=1;					//Bandera es 1
		while(flag==1)				//Hacer mientras bandera sea 1
		{
			if(input(pin_a2))		//Si pin_a2 es presionado...
			{
				output_low(pin_c0);	//Apagar pin_c0
				output_low(pin_d0);	//Apagar pin_d0
				flag=0;			//Bandera es 0, para que vuelva a empezar todo
			}
		}
	}
}
```


----------



## miglo (Mar 31, 2016)

yo creo que lo que buscas es algo parecido a esto

```
void main(void)
  {
output_low(pin_C0); // Pones a 0 la salida C0
output_low(pin_D0); // Pones a 0 la salida D0
 
while(true) // Bucle infinito
     {
 
   if(input(pin_A2))
     {
   delay_ms(250); 
  output_toggle(pin_C0);
  output_toggle(pin_D0);
    }
   }
 }
```
Cada vez que pulses cambiaran las salidas


----------



## D@rkbytes (Mar 31, 2016)

Está bien así como el código de miglo, pero falta poner un bucle de retención.
De otra forma, siempre estarán cambiando de estado los pines mientras se mantenga RA2 en 1

Poner: while(input(pin_a2)); antes de salir del bloque "if"
Esto simplificaría el código de yorsk2004 evitando la bandera.


----------



## OliMarch (Abr 30, 2016)

D@rkbytes disculpael código que sibiste hecho en C como lo prías para Microcode Studio ?.... me podrias ayudar? .... esque necesito hacer un Tres en línea con el Pic16F887 o 16F877A pero para eso necesito enviar datos fijos con pulsadores...Gracias... Feliz tarde


----------



## D@rkbytes (Abr 30, 2016)

OliMarch dijo:


> D@rkbytes disculpa. El código que subiste hecho en C, ¿cómo lo pasarías para Microcode Studio ?


Cambiando la sintaxis y las instrucciones, por las que se usan en Basic de MCS.

Por ejemplo:
If PORTA.2 = 0 Then
Toggle PORTB.7
While PORTA.2 = 0 Wend
EndIf


----------



## AJ ROBIN (Jul 13, 2020)

¿Por qué el LED no se apaga al oprimir el pulsador por tercera vez?

```
#include <xc.h>
#define _XTAL_FREQ 4000000
#define LED RB4
#define PULSADOR RA1


void main(void) {
    TRISA=0b11111111;
    TRISB=0b00000000;
    PORTB=0;
    
    int x=0;

    while(1){
        if(PULSADOR==1&&x<3){
            x++;
            __delay_ms(500);
        }

        if(PULSADOR==1&&x==3){
            x=0;
            __delay_ms(500);
        }

        switch (x){
            case 0:
                LED=0;
                break;
            case 1:
                LED=1;
                break;
            case 2:
                LED=1;
                __delay_ms(500);
                LED=0;
                __delay_ms(500);
                break;
        }
    }
    return;
}
```
Me ayudarían mucho respondiéndome, apenas soy nuevo en esto. Gracias.


----------



## D@rkbytes (Jul 13, 2020)

AJ ROBIN dijo:


> ¿Por qué el LED no se apaga al oprimir el pulsador por tercera vez?


Se debe apagar, pero como en el caso 2 tienes 2 retardos de 500 mS debes dejar presionado el pulsador 1 segundo para que x regrese a 0.
O sea que el programa no responderá durante los 1000 mS del caso 2


----------

