Autor Tema: como configurar adecuadamente 2 puertos serie virtuales?  (Leído 2250 veces)

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

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
como configurar adecuadamente 2 puertos serie virtuales?
« en: 29 de Julio de 2021, 11:42:36 »
cordial saludo, tan amables ...
tengo un 16f676 que no trae puerto serie , en ccs he logrado configurar un puerto serie pero al tratar de configurar 2 si me lee 1, no me lee el otro.
ademas quisiera poder identificar cuando esta llegando un dato por por alguno de ellos. anexo lo que he realizado.
Gracias de antemano...

Código: C
  1. #include <16f676.h>
  2.  
  3.  
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7. #use delay (internal=4000000)
  8.  
  9. #fuses PROTECT,NOWDT,nobrownout,nomclr
  10.  
  11.  
  12. #use rs232(baud=9600,rcv=PIN_C2,bits=8,parity=N,stream=RF2,errors)
  13. #use rs232(baud=9600,rcv=PIN_C3,bits=8,parity=N,stream=RF1,errors)
  14.  
  15.  
  16. #USE fast_io (A)      // Optimizamos E/S del PORTB ( muy importante para ahorrar memoria )
  17. #USE fast_io (C)
  18. #BYTE porta= 0X05
  19. #BYTE portc= 0X07
  20. #define rele1 PIN_A1
  21. #define rele2 PIN_C0
  22. #define rele3 PIN_C1
  23. #define acc PIN_C4
  24. #define led PIN_A0
  25.  
  26.  int32  Password1=9462401;
  27.  int32  Password2=9477245;
  28.  int32  Password3=9476881;
  29.  int32  Password4=9476831;
  30.  
  31. ///////////////////////////////////////
  32. // RAM
  33. ///////////////////////////////////////
  34.  
  35.  
  36.  
  37.  
  38.    //***********************************
  39.    
  40.    // ******* funciones ********
  41.  
  42.  
  43.    //*****************************************
  44.    
  45.  
  46.    // INTERRUPCIONES :
  47.  
  48.    
  49. // ***************************************
  50.  
  51.    void main()
  52.    {
  53.    setup_adc_ports(NO_ANALOGS); // todos digitales
  54.    set_tris_A(0b00001000);
  55.    set_tris_C(0b00011100);
  56.    portc=(0x00);
  57.    porta=(0x00);
  58.  
  59.  
  60.    //printf("transmito");
  61.      
  62.    int32 Num=0;
  63.    char caracter=0;;
  64.    char cadena[14];
  65.    int index = 0;
  66.    int flag =0;
  67.    int bascula=0;
  68.  
  69.    output_LOW(rele1);
  70.    output_LOW(rele2);
  71.    output_LOW(rele3);
  72.    output_low(led);
  73.    delay_ms(100);
  74.    
  75.    while(true)
  76.    {
  77.        //cadena=0;
  78.        
  79.        
  80.  
  81.        
  82.        
  83.         if (flag==0)
  84.         {
  85.            caracter=0;
  86.            if (kbhit(RF1))
  87.            {
  88.            caracter = getc();
  89.              if(caracter == 0x02) //inicio de tag
  90.              {
  91.              index = 0;
  92.              flag=0;
  93.              }
  94.                 else if(caracter == 0x03) // fin del tag
  95.                 {
  96.                  cadena[index] = '\0'; // finalizo la cadena
  97.                  flag =1;
  98.                   //fprintf(bt, "%s",&cadena);
  99.                 }
  100.                    else
  101.                    {
  102.                      cadena[index++]=caracter;
  103.                    }
  104.            }
  105.          
  106.  
  107.        
  108.        }
  109.      
  110.        
  111.        
  112.        
  113.         if (flag==1)
  114.         {
  115.  
  116.             for(int i=4;i<10;i++)//
  117.             {
  118.                Num<<=4;    //
  119.                if(cadena[i]>64)
  120.                {
  121.                Num+=((cadena[i])-55);//
  122.                }
  123.                else
  124.                {
  125.                Num+=((cadena[i])-48);//
  126.                }
  127.                 //printf("%lu\r\n",Num);
  128.             }  
  129.        
  130.                    // printf("%lu\r\n",Num);
  131.               if ((Num==Password1)||(Num==Password2)||(Num==Password3)||(Num==Password4))// 4 TARJETAS
  132.                {
  133.  
  134.              
  135.                   if (INPUT(acc))   // SI ACCESORIOS =1
  136.                  {
  137.                  bascula++;
  138.                      if(bascula==1)
  139.                      {              
  140.                      output_high(rele2);// ABRE
  141.                      //output_high(led);
  142.                      delay_ms(1000);
  143.                      output_low(rele2);                    
  144.                      }
  145.                    
  146.                      if(bascula==2) // CIERRA
  147.                      {
  148.                      output_high(rele1);
  149.                      //output_low(led);
  150.                      delay_ms(1000);
  151.                      output_low(rele1);
  152.                      bascula=0;
  153.                      }
  154.                  
  155.                   }
  156.            
  157.               }
  158.                 else
  159.                 {
  160.                     Num=0;
  161.                     for (i=0;i<15;i++ ) // vaciar el buffer
  162.                     {
  163.                     cadena[i]=0x00;
  164.                     }
  165.                 }
  166.           Num=0;
  167.           flag=0;
  168.        
  169.                }
  170.        
  171.   }  // while true  
  172.                                
  173.   }  //void main
Si algo parece complicado... es por que esta mal explicado.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:como configurar adecuadamente 2 puertos serie virtuales?
« Respuesta #1 en: 29 de Julio de 2021, 12:12:49 »
Cuando se trata de puertos emulados, kbhit devuelve 1 cuando detecta el start bit y tienes que andarte rápido para inmediatamente empezar a recibir el carácter.

 No es lo mismo que un puerto hardware donde kbhit devuelve 1 cuando se ha recibido un carácter y se ha almacenado en el fifo.

  En tu caso en vez de poner un if (kbhit);   Lo que haría sería: while(!kbhit);

  Esto hará que el programa quede en espera del carácter.

  Si no quieres dejar el programa ahí congelado esperando el carácter, pues acelerar un poco el barrido cambiando el if (flag == 0) por un while(flag == 0), de ese modo barrera  solamente el bloque de arriba.

  El de abajo no tienes por que estar comprobándolo constantemente por que está claro que flag nunca va a valer 1 a no ser que arriba se haya recibido una cadena completa.

  Con un while, en cuanto flag valga 1 se corta el bucle y se continúa.

   Lo de que si lee uno puerto, pero no el otro puede ser por que no le estás dando el stream al getc(); ,  si estás recibiendo por RF1, pon getc(RF1) de lo contrario por defecto se recibe del último puerto usado, y kbhit no hace uso del puerto, menos aún emulado.

  Saludos.

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:como configurar adecuadamente 2 puertos serie virtuales?
« Respuesta #2 en: 29 de Julio de 2021, 15:30:06 »
Cuando se trata de puertos emulados, kbhit devuelve 1 cuando detecta el start bit y tienes que andarte rápido para inmediatamente empezar a recibir el carácter.

 No es lo mismo que un puerto hardware donde kbhit devuelve 1 cuando se ha recibido un carácter y se ha almacenado en el fifo.

  En tu caso en vez de poner un if (kbhit);   Lo que haría sería: while(!kbhit);

gracias por tus aclaraciones,,, como tal vez te diste cuenta estoy leyendo una tarjeta rfid, entonces busco montar  2 lectores y que actúen en cerraduras diferentes, pero me dices que si no hay dato en el primer puerto entonces por defecto leerá el segundo, que debería hacer entonces para que por error no abra la cerradura que no le corresponde?
debería implementar 2 "kbhit" ?
Si algo parece complicado... es por que esta mal explicado.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:como configurar adecuadamente 2 puertos serie virtuales?
« Respuesta #3 en: 29 de Julio de 2021, 16:34:15 »
Por ejemplo hacer un bucle con un escaneo a los dos puertos:

Código: C
  1. while(1) {
  2.     if (kbhit(RF1)) {caracter = getc(RF1); break;}
  3.     if (kbhit(RF2)) {caracter = getc(RF2); break;}
  4. }

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:como configurar adecuadamente 2 puertos serie virtuales?
« Respuesta #4 en: 30 de Julio de 2021, 10:57:22 »
Por ejemplo hacer un bucle con un escaneo a los dos puertos:

Código: C
  1. while(1) {
  2.     if (kbhit(RF1)) {caracter = getc(RF1); break;}
  3.     if (kbhit(RF2)) {caracter = getc(RF2); break;}
  4. }
uff, que bien  muchas gracias.
aplique tus recomendaciones y ya me da sin problema, no se si puedas decirme por favor como quedo.
Código: C
  1. while(true)
  2.    {
  3.                
  4.      
  5.           if ((bascula==1)||(bascula2==1))//si alguna de las 2 esta abierta, led encendido
  6.           {
  7.           output_high(led);
  8.           }
  9.              else
  10.              {
  11.              
  12.              output_low(led);
  13.              }
  14.        
  15.        
  16.    
  17.          while(input_state(acc))// reviso los 2 puertos seriales
  18.          {
  19.             if (kbhit(RF1))// para leer, acc = 1
  20.             {
  21.             caracter = getc(RF1);
  22.             bandera=1;            // habilito la salida 1
  23.             break;
  24.             }
  25.             if(kbhit(RF2))// para leer, acc = 1
  26.             {
  27.             caracter = getc(RF2);
  28.             bandera=2;           // habilito la salida 2
  29.             break;
  30.             }
  31.          }
  32.  
  33.      
  34.        
  35.            if ((bandera==1) || (bandera==2))
  36.            {      
  37.              if(caracter == 0x02) //inicio de tag
  38.              {
  39.              index = 0;
  40.              flag=0;
  41.              }
  42.                 else if(caracter == 0x03) // fin del tag
  43.                 {
  44.                  cadena[index] = '\0'; // finalizo la cadena
  45.                  flag =1;
  46.                 }
  47.                    else
  48.                    {
  49.                    cadena[index++]=caracter;
  50.                    }
  51.  
  52.            }
  53.      
  54.        
  55.        
  56.        
  57.         while(flag==1)// si flag vale uno entra
  58.         {
  59.  
  60.             for(int i=4;i<10;i++)//
  61.             {
  62.              Num<<=4;    //
  63.                 if(cadena[i]>64)
  64.                 {
  65.                 Num+=((cadena[i])-55);//
  66.                 }
  67.                   else
  68.                   {
  69.                   Num+=((cadena[i])-48);//
  70.                   }        
  71.             }  
  72.        
  73.                    // printf("%lu\r\n",Num);
  74.                if ((Num==Password1)||(Num==Password2)||(Num==Password3)||(Num==Password4))// 4 TARJETAS
  75.                {
  76.  
  77.              
  78.                 if ((INPUT(acc))&& (bandera==1))   // SI ACCESORIOS =1
  79.                  {
  80.                  bascula++;
  81.                      if(bascula==1)
  82.                      {              
  83.                      output_high(rele2);// ABRE
  84.                      delay_ms(1000);
  85.                      output_low(rele2);                    
  86.                      }
  87.                    
  88.                      if(bascula==2) // CIERRA
  89.                      {
  90.                      output_high(rele1);
  91.                      delay_ms(1000);
  92.                      output_low(rele1);
  93.                      bascula=0;
  94.                      }
  95.                   bandera=0;
  96.                   }
  97.  
  98.  
  99.  
  100.                 //***********************
  101.            
  102.                   if ((INPUT(acc))&& (bandera==2))   // SI ACCESORIOS =1
  103.                   {
  104.                   bascula2++;
  105.                      if(bascula2==1)
  106.                      {      
  107.                      output_high(rele3);
  108.                      delay_ms(700);
  109.                      output_high(rele2);// ABRE
  110.                      delay_ms(1000);
  111.                      output_low(rele2);
  112.                      delay_ms(700);
  113.                      output_low(rele3);                    
  114.                      }
  115.                    
  116.                          if(bascula2==2) // CIERRA
  117.                          {
  118.                          output_high(rele3);
  119.                          delay_ms(700);
  120.                          output_high(rele1);
  121.                          delay_ms(1000);
  122.                          output_low(rele1);
  123.                          delay_ms(700);
  124.                          output_low(rele3);
  125.                          bascula2=0;
  126.                          }
  127.                  bandera=0; //
  128.                  }
  129.  
  130.  
  131.  
  132.            
  133.              }
  134.                 else
  135.                 {
  136.                     Num=0;
  137.                     for (i=0;i<15;i++ ) // vaciar el buffer
  138.                     {
  139.                     cadena[i]=0x00;
  140.                     }
  141.                 }
  142.           Num=0;
  143.           flag=0;
  144.        
  145.           //while(getc()>0)
  146.  
  147.    
  148.  
  149.  
  150.           } // while flag
  151.        
  152.   }  // while true  
  153.                                
  154.   }  //void main
« Última modificación: 30 de Julio de 2021, 11:29:06 por johenrod »
Si algo parece complicado... es por que esta mal explicado.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:como configurar adecuadamente 2 puertos serie virtuales?
« Respuesta #5 en: 30 de Julio de 2021, 19:41:54 »
Yo lo veo bien. Tal vez, tras la asignación del carácter a la cadena y el incremento del índice de la misma creo que deberías fijar de nuevo la bandera a cero, si no se te va a cumplir siempre haya o no haya carácter nuevo y te va a llenar el array completo con el último carácter recibido.

Código: C
  1. {
  2.                    cadena[index++]=caracter;
  3.                    bandera = 0;
  4.                    }

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:como configurar adecuadamente 2 puertos serie virtuales?
« Respuesta #6 en: 02 de Agosto de 2021, 10:51:49 »
Yo lo veo bien. Tal vez, tras la asignación del carácter a la cadena y el incremento del índice de la misma creo que deberías fijar de nuevo la bandera a cero, si no se te va a cumplir siempre haya o no haya carácter nuevo y te va a llenar el array completo con el último carácter recibido.

Código: C
  1. {
  2.                    cadena[index++]=caracter;
  3.                    bandera = 0;
  4.                    }
No solo me has ayudado con mi problema original, también a optimizar el código.
Gracias hermano por tu tiempo y ayuda tan valiosa.
Si algo parece complicado... es por que esta mal explicado.