Autor Tema: ayuda para semaforo peatonal con pic 876a  (Leído 1218 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado benjamontero

  • PIC10
  • *
  • Mensajes: 1
ayuda para semaforo peatonal con pic 876a
« en: 20 de Junio de 2016, 01:48:37 »
hola muchachos, soy nuevo en el foro. estoy aprendiendo sobre pic y en el lenguaje C. soy medio un queso aun con estas cosas pero estoy con muchas ganas. les explico a continuación lo que tengo que hacer basicamente es un semaforo peatonal, mejor dicho 4 semáforos peatonales. mas o menos un grafico seria asi:


                 R R
                 B B
                 5 4
                 -  -
                 0 0
RB6---0               0---RB3
RB7---0               0---RB2
                  0 0
                  -  -
                  R R
                  B B
                  0 1

Mas facil era un grafico XD jaja pero en fin esos serian los semaforos de una intersección, 2 colores como se vera. entonces el objetivo del ejercicio es el siguiente :

4 semáforos podríamos llamarlos , sur este, oeste y norte.
Obviamente cuando se prende el semaforo sur en verde, todos los otros semáforos están en rojo. genial! ahi empieza la secuencia, antes de cambiar parpadea 3 veces y cambia asi el otro semaforo. hasta creo haberme explicado. AQUI viene el problema muchachos. el Semaforo sur tiene un pulsador, que cuando se lo presione tiene q reiniciar toda la secuencia. (osea es un boton para darle el verde al semaforo sur.). el problema es que no entiendo como hacer funcion.
adjunto el cod:
Código: [Seleccionar]
#INCLUDE <16F876A.H>
#INCLUDE <MATH.H>
#FUSES XT, NOPUT, NOPROTECT, NOWDT
#use delay(clock=4000000)
//Defines------------------------------------------
#BYTE PORTA = 0x05
#BYTE PORTB = 0x06
#BYTE PORTA_TRIS = 0x85
#BYTE PORTB_TRIS = 0x86
#DEFINE LED PIN_A3
#DEFINE RDD_CLOCK PIN_A4





Int Tiempo = 500;
Void SemaforoSur (Void);
Void SemaforoEste (Void);
Void SemaforoNorte (Void);
Void SemaforoOeste (Void);
Void Retardo (Void);
void fConfigurar_puertos(void);

void main(void)
{

fConfigurar_puertos();

   while(true)
   {
      SemaforoSur();
      SemaforoEste();
      SemaforoNorte();
      SemaforoOeste();
   }

}

Void SemaforoSur (Void)
{
      output_b(0b10101001);
      Retardo ();
      output_b(0b10101000);
      delay_MS(Tiempo);
      output_b(0b10101001);
      delay_MS(Tiempo);
      output_b(0b10101000);
      delay_MS(Tiempo);
      output_b(0b10101001);
      delay_MS(Tiempo);
      output_b(0b10101000);
      delay_MS(Tiempo);
      output_b(0b10101001);
      delay_MS(Tiempo);
}
Void SemaforoEste (Void)
{
      if(input(pin_A0)==0) break;
      output_b(0b10100110);
      Retardo ();
      output_b(0b10100010);
      delay_MS(Tiempo);
      output_b(0b10100110);
      delay_MS(Tiempo);
      output_b(0b10100010);
      delay_MS(Tiempo);
      output_b(0b10100110);
      delay_MS(Tiempo);
      output_b(0b10100010);
      delay_MS(Tiempo);
      output_b(0b10100110);
      delay_MS(Tiempo);
}
Void SemaforoNorte (Void)
{
      if(input(pin_A0)==0) break;
      output_b(0b10011010);
        Retardo ();
      output_b(0b10001010);
      delay_MS(Tiempo);
      output_b(0b10011010);
      delay_MS(Tiempo);
      output_b(0b10001010);
      delay_MS(Tiempo);
      output_b(0b10011010);
      delay_MS(Tiempo);
      output_b(0b10001010);
      delay_MS(Tiempo);
      output_b(0b10011010);
      delay_MS(Tiempo);
}
Void SemaforoOeste (Void)
{
      output_b(0b01101010);
      Retardo ();
      output_b(0b00101010);
      delay_MS(Tiempo);
      output_b(0b01101010);
      delay_MS(Tiempo);
      output_b(0b00101010);
      delay_MS(Tiempo);
      output_b(0b01101010);
      delay_MS(Tiempo);
      output_b(0b00101010);
      delay_MS(Tiempo);
      output_b(0b01101010);
      delay_MS(Tiempo);
}


Void Retardo (Void)
{
 Delay_ms(Tiempo);
  Delay_ms(Tiempo);
   Delay_ms(Tiempo);
    Delay_ms(Tiempo);
     Delay_ms(Tiempo);
      Delay_ms(Tiempo);
       Delay_ms(Tiempo);
    Delay_ms(Tiempo);
     Delay_ms(Tiempo);
      Delay_ms(Tiempo);
}



void fConfigurar_puertos(void)
{
  PORTA_TRIS = 0b11000001; //1=ENTRADA, 0=SALIDA
  PORTB_TRIS = 0b00000000; //1=ENTRADA, 0=SALIDA
}

Muchachos estoy perdido. mi pulsador esta en RA0. trate de ponerlo en el while, mediante if (input (PIN_A0)==1) y un else cuando se lo presione, me reinicie el sistema, pero nose como hacer eso. espero puedan ayudarme. tal vez para ustedes no sea tan complicado, yo aun estoy medio lento con el tema este. espero sepan comprenderme.
PD: el codigo hasta donde esta me hace funcionar infinitamente la secuencia que necesito, mi problema es la interrupcion que no se como hacerla, y el retorno para q reinicie toda la secuencia de vuelta al semaforo sur
Gracias!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:ayuda para semaforo peatonal con pic 876a
« Respuesta #1 en: 20 de Junio de 2016, 11:16:56 »
Solo para probar si se podria hacer de esta forma lo hice :3

Código: C
  1. #define Todos_Rojos  0b10101010
  2. #use fast_io(b)
  3.  
  4.  
  5. uint8_t Semaforos[4][2] = {
  6.                                 {00111111,01000000},
  7.                                 {11001111,00010000},
  8.                                 {11110011,00000100},
  9.                                 {11111100,00000001},
  10.                           };
  11.  
  12. void main(void)
  13. {
  14.  
  15.         uint8_t i=0,j;
  16.  
  17.         set_tris_b(0);
  18.  
  19.         while(1)
  20.         {
  21.                 output_b((Todos_Rojos & Semaforos[i][0]) | Semaforos[i][1]);
  22.                 Retardo();
  23.                 for(j=0;j<6;j++)
  24.                 {
  25.                         output_b(input_b() ^ Semaforos[i][1]);
  26.                         delay_ms(Tiempo);
  27.                 }
  28.                 i++;
  29.                 if(i>3) i=0;
  30.         }
  31. }


Ahora con respecto al boton de reiniciar la secuencia te quedan 2 opciones:

- Si usas delays, deberias usar la interrupcion de RB0 es decir por flanco, de esa forma al detectarse que proceda a resetear el micro. Digo por flanco por que solo se tomaria una sola ves si es que se mantiene presionado.

- La otra es NO usar delays, y usar un timer en ves de un delay. Entonces lo que traba a tu micro que eran los delays, dejan de molestar, ya que lo unico que vas a esperar es que se active una flag desde la interrupcion ( cuando pasaron la cantidad correspondientes para ese segundo), en la misma interrupcion podrias detectar si se presiono el boton. Y activar una flag para eso.


Código: C
  1. #define Todos_Rojos  0b10101010
  2. #use fast_io(b)
  3.  
  4.  
  5. uint8_t Semaforos[4][2] = {
  6.                                 {00111111,01000000},
  7.                                 {11001111,00010000},
  8.                                 {11110011,00000100},
  9.                                 {11111100,00000001},
  10.                           };
  11.  
  12. void main(void)
  13. {
  14.  
  15.         uint8_t i=0,j;
  16.  
  17.         set_tris_b(0);
  18.  
  19.  
  20.         while(1)
  21.         {
  22.                 i=0;
  23.                 Boton_detectado=0
  24.                 while(1)
  25.                 {
  26.                         output_b((Todos_Rojos & Semaforos[i][0]) | Semaforos[i][1]);
  27.                         while(!Flag_Retardo)
  28.                         {
  29.                                 if(Boton_detectado) break;
  30.                         }
  31.  
  32.                                 if(Boton_detectado) break;
  33.        
  34.                         for(j=0;j<6;j++)
  35.                         {
  36.                                 output_b(input_b() ^ Semaforos[i][1]);
  37.                                 while(!Flag_Tiempo)
  38.                                 {
  39.                                         if(Boton_detectado) break;
  40.                                 }
  41.                         }
  42.                         if(Boton_detectado) break;
  43.                         i++;
  44.                         if(i>3) i=0;
  45.                 }
  46.         }
  47. }

Aunque lo genial seria usar un goto, siempre y cuando tengas el cuidado de no llamar a ninguna funcion. Sino vas a tener la posibilidad si no sos cuidadoso de llenar la pila

Código: C
  1. #define Todos_Rojos  0b10101010
  2. #use fast_io(b)
  3.  
  4.  
  5. uint8_t Semaforos[4][2] = {
  6.                                 {00111111,01000000},
  7.                                 {11001111,00010000},
  8.                                 {11110011,00000100},
  9.                                 {11111100,00000001},
  10.                           };
  11.  
  12. void main(void)
  13. {
  14.  
  15.         uint8_t i=0,j;
  16.  
  17.         set_tris_b(0);
  18.  
  19.  
  20.         while(1)
  21.         {
  22. BotonPresionado:
  23.                 i=0;
  24.                 Boton_detectado=0
  25.                 while(1)
  26.                 {
  27.                         output_b((Todos_Rojos & Semaforos[i][0]) | Semaforos[i][1]);
  28.                         while(!Flag_Retardo)
  29.                         {
  30.                                 if(Boton_detectado) goto BotonPresionado;
  31.                         }
  32.  
  33.                         for(j=0;j<6;j++)
  34.                         {
  35.                                 output_b(input_b() ^ Semaforos[i][1]);
  36.                                 while(!Flag_Tiempo)
  37.                                 {
  38.                                         if(Boton_detectado) goto BotonPresionado;
  39.                                 }
  40.                         }
  41.  
  42.                         i++;
  43.                         if(i>3) i=0;
  44.                 }
  45.         }
  46. }