# Problema con pic 16F877A



## leyenda (Sep 22, 2010)

Estoy realizando este proyecto como podran ver en la siguiente imagen:







El problema parte en la programacion de los switches por que  nunca e programado con eso y mas en ccs compiler si alguien me puede guiar en esa parte 


```
#include <16f877A.h>
#use delay (clock=4000000)
#fuses XT,NOWDT,NOPROTECT,NOPUT
#byte port_b=6

main() {
byte cnt,value;
set_tris_b(0);
port_b =0;
value=0x01;

while (true)
{
cnt = 0;
value = 0x01;

 while (cnt<8)
 {
  port_b= value;
   DELAY_MS(300);
    value = value << 1;
     cnt++;
  }
 }
}
```
le agradesco su colaboracion


----------



## lubeck (Sep 22, 2010)

Porque no suben el archivo DSN de proteus, no creen que da flojera copiar el esquema para revizarlo????

no todos dominamos el C pero queremos practicar


----------



## leyenda (Sep 22, 2010)

ahy esta el arcuhivo de proteus


----------



## lubeck (Sep 22, 2010)

Mira este codigo...


```
#include <16F877A.h>  
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT  
#use delay(clock=4000000)  
#use standard_io(b)  
//mirar sin usar tris  
void main() {  
  set_tris_b(011011);          //porta como entrada  
  set_tris_d(0x00);  
  do{  
  output_b(0x00);  
  if (input(pin_d0)){  
     output_high(pin_b0);  
   }  
  if (input(pin_d1)){  
     output_high(pin_b1);  
   }  
  if (input(pin_d3)){  
     output_high(pin_b3);  
   }  
  if (input(pin_d4)){  
     output_high(pin_b4);  
   }  
  }while(true);//Bucle infinito  
}
```

las resisttencias de los leds ponlas de 330 ohms no de 1k, y las de los pulsadores ponlas de 4.7k
te estas equivocando en los puertos el A no se ocupa...
ahora si explica que quieres que haga???


----------



## leyenda (Sep 22, 2010)

cuando oprima un pulsador haga una secuencia, cuando oprima otro pulsador me haga una secuencia diferente a la anterior


----------



## Trev (Sep 22, 2010)

Hola, asi como tienes tu codigo los 4 leds del portb siempre estaran encendidos salvo durante el corto tiempo que oprimas un pulsador, ¿queres dar solo un pulso o usas esos switch que se quedan en un estado? si en ves de apretar el pulsador le das click en el puntito rojo de al lado queda oprimido hasta un nuevo click supongo que esto quieres hacer, si es eso esta bien lo que haces, si quieres que queden apagados debes poner asi
if (!input(PIN_D0))
output_high(PIN_B0); 
etc


----------



## leyenda (Sep 22, 2010)

mira cuando oprima el pulsador los led prenda y apaguen (seria el primer pulsador) esa seria un secuencia 
la otra secuancia seria que los led prendan de abajo hacia arriva(vendria en el segundo pulsador)

modifique el programa por uno mas resumido pero sigo en la duda para programar cada pulsador para que me haga un secuancia diferente






asi es como lo busco hacer


----------



## Trev (Sep 22, 2010)

Hola leyenda..eso es ya mas complicado lo que dices..
Yo haria lo siguiente: usaria la interrupcion por cambio de estado del portb,hay que modificar todo de lugar..y me crearia varias funciones de secuencias de luces diferentes,dentro de la interrupcion determinaria q pin de los 4 q pueden disparar esta interrupcion se ha pulsado y en base a eso se ejecutaria la funcion que hace una secuencia de luces determinada, burdamente seria algo asi: (estoy con los motores paso a paso desde bastante asique ando medio alejado del ccs je)


```
#include <pic16f877a>
#fuses XT,PUT,BROWNOUT,NOPROTECT
#use delay(clock=4000000)
//Declaracion de funciones.
int8 secuencia=0;

void secuencia_luces1(void);          //Declaracion de funcion no devuelve parametros ni los recibe
void secuencia_luces2(void);

void secuencia_lucesx(void);

//Variables globales
//Aqui declaras y/o inicializas tus variables globales

//Rutina de interrupcion por cambio de estado PORTB
#int_rb
RSI_RB()
{
if(!input(PIN_B4))
{
secuencia=1;
}

if (!input(PIN_B5))
{
secuencia=2;
}

if (!input(PIN_B6))
{
secuencia=3;
}

if (!input (PIN_B7))
{
secuencia=4;
}
delay_ms(20); //Esto es un retardo antirrebotes del pulsador
}


void main ()
{
set_tris_x(xxxx);
enable_interrupts(GLOBAL);  //Habilitas interrupciones
enable_interrupts(INT_RB);  //Habilitas especificamente interrupcion por cambio de estado
port_b_pull_ups(TRUE);       //Aqui le "dices" al pic que use sus R de pull-up internas

             while(1)
            {
                  switch (secuencia)         //Aqui segun el pulsador que hayas oprimido invoca la funcion
                                                    //de luces deseada...y no sale de ella hasta no se oprima un
                                                    // pulsador diferente...
                  {        
                  case 1:
                  {
                  secuencia_luces1();
                  break;
                  }
                  case 2:
                  {
                  secuencia_luces2();
                  break;
                  }
                  
                  
                  
                  case x:
                  {
                  secuencia_lucesx();
                  break;
                  }
                  }
             }
}

//Aqui pones el cuerpo de las funciones de secuencias de luces

secuencia_luces1()
{
bla
bla 
bla
}

secuencia_lucesx()
{
bla
bla
bla
}
```
Bueno espero averte sido de ayuda..esta seria mas o menos (hay q pulirla) la estructura del programa que yo haria segun lo que vos queres


----------



## Trev (Sep 24, 2010)

Hola leyenda, veo que te estas iniciando a lo mejor no entendes el concepto de funciones todavia o el de las interrupciones..



> no se como insertar esas tres secuencias en una sola programación


Estan bien las secuencias que haz hecho pero tienes 3 programas, ¿usas assembler? bueno una función es algo asi como una subrutina, es un procedimiento al que tu puedes invocar en cualquier punto de un programa, como un call, te explique en el otro mensaje como es la estructura básica de un programa en C para micros,debes acostumbrarte a respetar esa estructura..
Bueno entonces tu tienes por ejemplo la secuencia


```
{
   signed char i;      //variable indice 
   int leds[8]={0b10000000,0b01000000,0b00100000,0b00010000,0b00001000,0b00000100,0b00000010,0b00000001}; //led"s      
                  
   
   
   do{                        //bucle...
      
      for(i=8;i>-1;i--){         //led"s on dentro-fuera
         output_b(leds[ i ]);      //ilumino led"s correspondientes
         delay_ms(100);
         }      
  }while(TRUE);            //...infinito
```
la llamas asi por ej:

void secuencia_arriba_abajo (void):asi la función es una función vacia:ni recibe ni devuelve ningún parametro ,bien lo que esta arriba seria el cuerpo de tu función (o sea lo que hace) ,para que el procedimiento se pueda ejecutar en tu programa primero se debe declarar la función tambien llamada cabecera de la funcion antes de donde va el main de la siguiente forma:

void secuencia_arriba_abajo (void);
despues del main pones el cuerpo de la funcion tal cual como te puse arriba.. y en el main que es el programa principal puedes invocar a la función en cualquier punto...de la siguiente manera

secuencia_arriba_abajo();
bla 
bla
bla

Bien..ahora entiendes lo que es una interrupción?, una interrupcion es una función fuera del main que se dispara eventualmente como por ej. ante la pulsación de un switch y su proposito es "liberar" al programa principal de estar constantemente escaneando si se pulso o no un switch ya que el programa principal atiende ese asunto cuando ocurre el evento solamente,si tienes un switch no es tanto problema si tienes 5 ya si y debes haces otras cosas el programa se vuelve engorroso,asique bueno la idea con la interrupción es liberar al programa principal de escanear los switch para que pueda hacer otra cosa,el dia de mañana que le quieras agregar mas complejidad a tu programa, bueno el pic16f877 tiene 14 posibles eventos que pueden disparar una interrupción entre ellas esta la llamada "interrupcion por cambio de estado del portb",este puerto trae de las patitas B4 a B7 resistencia de pull-ups internas que debes activar o sea que tienen un 1 permanente (o 5 V si mides con un tester) salvo que mandes a masa cualquiera de esas patitas,ahi es donde pones tus switch,si cualquiera de esas patitas se manda a masa o se presiona cualquier pulsador se dispara la interrupción,ahi una vez dentro determinas cual ha sido el pulsador que se ha oprimido y se sale rapido (es recomendable hacer las interrupciones cortas y rapidas) y en base a eso se decide que función de luces se ejecuta, esta es la estructura:

```
#include <pic16f877a>
#fuses XT,PUT,BROWNOUT,NOPROTECT
#use delay(clock=4000000)
//Declaracion de funciones.
int8 secuencia=0;

void secuencia_arriba_abajo(void); //Declaracion o cabecera de funcion no devuelve parametros ni los recibe
void secuencia_luces2(void);

void secuencia_lucesx(void);

//Variables globales
//Aqui declaras y/o inicializas tus variables globales

//Rutina de interrupcion por cambio de estado PORTB
#int_rb
RSI_RB()
{
if(!input(PIN_B4))
{
secuencia=1;
}

if (!input(PIN_B5))
{
secuencia=2;
}

if (!input(PIN_B6))
{
secuencia=3;
}

if (!input (PIN_B7))
{
secuencia=4;
}
delay_ms(20); //Esto es un retardo antirrebotes del pulsador
}


void main ()
{
set_tris_x(xxxx);
enable_interrupts(GLOBAL); //Habilitas interrupciones
enable_interrupts(INT_RB); //Habilitas especificamente interrupcion por cambio de estado
port_b_pull_ups(TRUE); //Aqui le "dices" al pic que use sus R de pull-up internas

while(1)
{
switch (secuencia) //Aqui segun el pulsador que hayas oprimido invoca la funcion
//de luces deseada...y no sale de ella hasta no se oprima un
// pulsador diferente...
{ 
case 1:
{
secuencia_arriba_abajo();   //aqui ejecutas tu secuencia de luces arriba/abajo
break;
}
case 2:
{
secuencia_luces2();
break;
}

case x:
{
secuencia_lucesx();
break;
}
}
}
}

//Aqui pones el cuerpo de las funciones de secuencias de luces

secuencia_arriba_abajo()
{
do{                        //bucle...
      
      for(i=8;i>-1;i--){         //led"s on dentro-fuera
         output_b(leds[ i ]);      //ilumino led"s correspondientes
         delay_ms(100);
         }      
  }while(TRUE);            //...infinito
}

secuencia_lucesx()
{
bla
bla
bla
}
```

Bue..espero hayas entendido,si entendiste sabrás agregar lo que falta un saludo!!

Hola por si no te quede claro te voy a subir el DSN que yo hice y el archivo cof. para que lo veas..


----------



## gerson luis (Ago 5, 2012)

alguien save si aprate de las interrupciones de cambio de estado en rb existen otras en rc, ra tambien de cambio de estado con el 16f876 o con el  877


----------

