Autor Tema: SOS en control de buffer  (Leído 10207 veces)

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

Desconectado santipic_9

  • Colaborador
  • PIC10
  • *****
  • Mensajes: 36
SOS en control de buffer
« en: 22 de Septiembre de 2006, 17:21:08 »
Hola  a todos, primeramente espero que el Maestro Red_ Pic no me "eche la bronca" por haberle destrozado uno de sus ejemplos, el  doy fé que funcionaba correctamente.

He trasladado este post para aquí porque creo que es el sitio más adecuado al ser de programación ( estaba en  gsm, gps).  Gracias a Badtzdizzy por sus respuestas y ya que lo he modificado pero no funciona aún correctamente , me gustaría , por favor , que me dieraís alguna sugerencia, os lo agradezco. gracias.
El código es el siguiente:


Código: C
  1. // CONTROL DEL BUFFER ORIGINAL DE RED_PIC Y  "destrozado por Santipic"
  2.  
  3. // Por el puerto serie me entra esta secuencia de caracteres cada 2 segundos
  4. // $GPGGA,194345.0,,,,,0,02,,,,,,,*74    y quiero meterla en el buffer y de ahí poder
  5. // recuperla y enviarla otra vez por el puerto serie.
  6.  
  7.  
  8. #include <18f2550.h>                          // Definiciones del PIC 18F2550
  9. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT  // Los Fuses de siempre
  10. #use delay(clock=8000000)                     // Oscilador a 8Mhz
  11.  
  12. #include <stdlib.h>
  13.  
  14. #use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar
  15.  
  16. // CONSTANTES /////////////////////////////////////////////////////////////////
  17.  
  18. int const lenbuff=100;                  // Longitud de buffer, Ajustar
  19.                                        // a lo que desees (o te sea posible)
  20.  
  21. // VARIABLES EN RAM ///////////////////////////////////////////////////////////
  22.  
  23. int  xbuff=0x00;                       // Índice: siguiente char en cbuff
  24. char cbuff[lenbuff];                   // Buffer
  25. char rcvchar=0x00;                     // último caracter recibido
  26. int1 flagcommand=0;                    // Flag para indicar comando disponible
  27.  
  28. // Declaración de Funciones ///////////////////////////////////////////////////
  29.  
  30. void inicbuff(void);                   // Borra buffer
  31. int  addcbuff(char c);                 // añade caracter recibido al buffer
  32. void echos(char c);                    // Eco selectivo sobre RS232
  33. void procesa_comando(void);            // Procesa comando
  34.  
  35. // INTERRUPCIONES /////////////////////////////////////////////////////////////
  36.  
  37. #int_rda
  38. void serial_isr() {                    // Interrupción recepción serie USART
  39.  
  40.    rcvchar=0x00;                       // Inicializo caracter recibido
  41.    if(kbhit()){                        // Si hay algo pendiente de recibir ...
  42.       rcvchar=getc();                  // lo descargo y ...
  43.       addcbuff(rcvchar);               // lo añado al buffer y ...
  44.    }
  45. }
  46.  
  47. // Desarrollo de Funciones ////////////////////////////////////////////////////
  48. int addcbuff(char c){                  // Añade a cbuff -----------------------
  49.  
  50.       switch(c){
  51.          case 0x0D:                    // Enter -> Habilita Flag para procesar
  52.             flagcommand=1;             // Comando en Main
  53.             break;
  54.          case 0x08:                    // Del   -> Borra último caracter del Buffer
  55.             if(xbuff>0) cbuff[--xbuff]=0x00;
  56.             break;
  57.          case 0x01B:                   // Esc   -> Borra el Buffer completamente
  58.             inicbuff();
  59.             break;
  60.          default:
  61.             cbuff[xbuff++]=c;          // Añade caracter recibido al Buffer
  62.       }
  63. }
  64.  
  65. void inicbuff(void){                   // Inicia a \0 cbuff -------------------
  66.    int i;
  67.  
  68.    for(i=0;i<lenbuff;i++){             // Bucle que pone a 0 todos los
  69.       cbuff[i]=0x00;                   // caracteres en el buffer
  70.    }
  71.    xbuff=0x00;                         // Inicializo el indice de siguiente
  72.                                        // caracter
  73. }
  74. // Programa Principal /////////////////////////////////////////////////////////
  75.  
  76. void main() {
  77.    printf("\r\n\** prueba buffer **\r\n\r\n");  // Presenta menú
  78.  
  79.    enable_interrupts(int_rda);                   // Habilita Interrupción RDA
  80.    enable_interrupts(global);                    // Habilita interrupciones
  81.  
  82.    do {
  83.  
  84.       if(flagcommand) procesa_comando();         // Si hay comando pendiente
  85.                                                  // de procesar ... lo procesa.
  86.    } while (TRUE);
  87.  
  88. }
  89. // Procesador de Comandos /////////////////////////////////////////////////////
  90.  
  91. void procesa_comando(void){
  92.  
  93.    int i, xv;
  94.    char arg[lenbuff];                   // Argumento de comando (si lo tiene)
  95.    disable_interrupts(int_rda);
  96.    flagcommand=0;                       // Desactivo flag de comando pendiente.
  97.    printf("\r\nProcesando ... ");       // Monitorizo procesando ...
  98.  
  99.       xbuff=0x00;                     //Lo que necesito hacer es scanear el buffer para
  100.    for (cbuff[0];xbuff='$';xbuff=0x4A){   //extraer la cadena de caracteres que me interesa
  101.     printf("\r\nfor ... ");            // Prueba de que pasa por aquí
  102.     i=0;
  103.       do{
  104.                                        // Extraemos argumento del buffer
  105.          arg[0]=xbuff ;             //
  106.       }while(cbuff[++i] == 0x4A);
  107.       xv = atoi(arg);
  108.       printf("Escribiendo %s %u ... ",arg,xv);
  109.    }                                 // Monitorizamos el argunmento.
  110.    
  111.    inicbuff();                          // Borro buffer.
  112.  
  113.    printf("Procesado.\r\n\r\n");        // Monitorizo procesado.
  114.    enable_interrupts(int_rda);
  115. }


Y en el hyperterminal me sale esto:

for ... Escribiendo $½³
for ... Escribiendo $i±;2L 0 ...       
hQÐ&ã¢ÁÖN(E.         
for ... Escribiendo $i±;2L 0 ...
for ... Escribiendo $i±;2L 0 ...
for ... Escribiendo $i±;2L 0 ...
for ... Escribiendo $i±;2L 0 ...
for ... Escribiendo $i±;2L 0 ...
for ... Escribiendo $i±;2L 0 ...

Disculpar pero mi nivel en programación es muy bajo, pero lo estoy intentanto.

Bueno espero que me podaís decir algo. Muchas gracias a todos
Saludos desde A Coruña, España
« Última modificación: 23 de Septiembre de 2006, 02:19:39 por RedPic »

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: SOS en control de buffer
« Respuesta #1 en: 23 de Septiembre de 2006, 02:13:26 »
Santi, gallego de mis entretelas, cuéntale a este andalúz de a pié qué es lo que no te funciona.

Díme los síntomas para poder efectuar un diagnóstico acertado y veraz.  :mrgreen:

P.D: Ponle [ code = c ]  ... [ / code ] (sin espacios) a tu código para que sea mas visible y no desaparezcan trozos como [ i ] (sin espacios) que el php de texto interpreta como cambiar la letra a itálica.

Edito: Se lo coloco yo mismo modificando tu post. (Es una de las prerrogativas que disfruto como Moderador de este foro)

« Última modificación: 23 de Septiembre de 2006, 02:19:03 por RedPic »
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: SOS en control de buffer
« Respuesta #2 en: 23 de Septiembre de 2006, 02:33:38 »
Santi .... ja ja ja  :D  :D  :D

Tienes la gentileza de explicarme:
¿qué es esto?  ja ja ja  :D  :D  :D
¿cual es la intención que tenías en mente al escribir este bucle for? ja ja ja  :D  :D  :D
¿has bebido o fumado algo ilegal? ja ja ja  :D  :D  :D
(No te me cabrees, es broma  :mrgreen: )

Código: C
  1. xbuff=0x00;                                   //Lo que necesito hacer es scanear el buffer para
  2. for (cbuff[0];xbuff='$';xbuff=0x4A){   //extraer la cadena de caracteres que me interesa
  3.   printf("\r\nfor ... ");                      // Prueba de que pasa por aquí
  4.   i=0;
  5.   do{                                           // Extraemos argumento del buffer
  6.     arg[0]=xbuff ;                           //
  7.   }while(cbuff[++i] == 0x4A);
  8.    xv = atoi(arg);
  9.    printf("Escribiendo %s %u ... ",arg,xv);
  10. }                                               // Monitorizamos el argunmento.


Cuéntame en detalle qué cadena de carácteres es la que recibes por el canal serie y qué es lo que deseas hacer con ella.

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: SOS en control de buffer
« Respuesta #3 en: 23 de Septiembre de 2006, 03:36:12 »
Intuyo por otros mensajes que he leído al amigo Santipic que pretende leer un chorizo del puerto serie y encontrar en el mismo el string que se delimita al comienzo por el '$' y finaliza por 0x4A.

Si estuviera en lo cierto, podría resolverse más o menos de esta forma (conste que no he probado, eh):

Código: C
  1. j=0;
  2. printf("Escribiendo ");                        
  3. for (i=0;i<xbuff;i++){                      
  4.   if (cbuff[i]=="$")
  5.      while((cbuff[i] != 0x4A) & (i<xbuff))
  6.         {
  7.          salida[j++]=cbuff[i++];
  8.          printf ("%c",salida[j-1]);
  9.         }
  10.   i++;
  11. }
                   

Desconectado santipic_9

  • Colaborador
  • PIC10
  • *****
  • Mensajes: 36
Re: SOS en control de buffer
« Respuesta #4 en: 23 de Septiembre de 2006, 09:36:55 »
Muy buenos dias a todos.

Gracias Maestros ( Red_Pic y Nocturno- Nocturno  y Red_Pic ) por vuestra rápida contestación a esta llamada de auxilio.
Tambien por poner correctamente el  código  (ya tomo nota para la próxima vez). La verdad es que estaba muy sobrío cuando le metí mano a ese código, pero lamentablemente no tengo  mucho nivel en programación c  y estoy empezando a hacer mis pinitos. De todas maneras  da gusto aprender y con buen humor siempre :lol: :lol: :lol:, no hay problema.  gracias de nuevo.

Basicamente, como apuntaba Nocturno,  lo que quiero es aprender a controlar  un buffer a partir de los datos que entran por el puerto serie.( en este caso me los manda un gps pero puede ser de otro medio). Es decir de todos los churros que entran poder scanear o buscar un caracter  en dicho buffer y a partir de ahí recuperar esa cadena de caracteres y poder  hacer printf con ella o incluso guardarla en una memoria.

Voy a probar tú código  Nocturno a ver que pasa, ya os contaré.
 
No estaría mal Red_Pic, si es posible, que le pegaras a este ejemplo tuyo una pequeña adaptacón o reforma para dicho control del buffer, su grabación y recuperación en la eeprom. Seguro que muchos principiantes como yo te estarian muy agradecidos pues los cabezazos en la mesa no nos dolerian tanto.

Tenemos mucha suerte al entrar en este foro y encontar gente como vosotros dos y más gente , de verdad y no lo digo por haceros la pelota, que no se me da nada bien, lo digo porque lo siento de verdad. GRACIAS

TODOPIC NUESTRA UNIVERSIDAD A DISTANCIA.Saludos y gracias  al Fundador, Moderadores, Colaboradores y Foristas.

Un abrazo a todos desde A Coruña, España

 :-/ :-/ :-/

Desconectado santipic_9

  • Colaborador
  • PIC10
  • *****
  • Mensajes: 36
Re: SOS en control de buffer
« Respuesta #5 en: 23 de Septiembre de 2006, 20:16:28 »
Hola a  todos.
 :-/ :-/ :-/ :-/ :-/ESTOY SUPERCONTENTO HOY :-/ :-/ :-/
Por fín he visto salir del pic una cadena de caracteres, es  una maravilla.
Pues sí Nocturno, el código funcionó aunque me tarda unas  setenta y algo de veces en echar cada trama pero ES UNA PASADA al fín veo  el resultado.

Bueno pues de dos Maestros de cocina Sevillanos y un pinche de cocina gallego sale una mezcla de gazpacho y cocido " que no se puede aguantar",Ole, ole  y ole :-) :-) :-).
Debo tambien acordarme de Badtzdizzy , el cual cordialmente me ha resuelto algunas dudas y por supuesto a todos los foristas de Todopic que con sus dudas y ejemplos aprendemos un montón.

El código ha quedado así:
Código: C
  1. // CONTROL DEL BUFFER ORIGINAL DE RED_PIC
  2.  
  3. // Por el puerto serie me entra esta secuencia de caracteres cada 2 segundos
  4. // $GPGGA,194345.0,,,,,0,02,,,,,,,*74(esta es una trama sin stelite
  5. //, sino tendría sobre 70 caracteres)
  6. //    y quiero meterla en el buffer y de ahí poder
  7. // recuperla y enviarla otra vez por el puerto serie.
  8.  
  9.  
  10. #include <18f2550.h>                          // Definiciones del PIC 18F2550
  11. #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT  // Los Fuses de siempre
  12. #use delay(clock=8000000)                     // Oscilador a 8Mhz
  13.  
  14. #include <stdlib.h>
  15.  
  16. #use rs232(baud=4800, xmit=PIN_C6, rcv=PIN_C7)// RS232 Estándar
  17.  
  18. // CONSTANTES /////////////////////////////////////////////////////////////////
  19.  
  20. int const lenbuff=76;                  // Longitud de buffer, Ajustar
  21.                                        // a lo que desees (o te sea posible)
  22.  
  23. // VARIABLES EN RAM ///////////////////////////////////////////////////////////
  24.  
  25. int  xbuff=0x00;                       // Índice: siguiente char en cbuff
  26. char cbuff[lenbuff];                   // Buffer
  27. char rcvchar=0x00;                     // último caracter recibido
  28. int1 flagcommand=0;                    // Flag para indicar comando disponible
  29.  
  30. // Declaración de Funciones ///////////////////////////////////////////////////
  31.  
  32. void inicbuff(void);                   // Borra buffer
  33. int  addcbuff(char c);                 // añade caracter recibido al buffer
  34. void echos(char c);                    // Eco selectivo sobre RS232
  35. void procesa_comando(void);            // Procesa comando
  36.  
  37. // INTERRUPCIONES /////////////////////////////////////////////////////////////
  38.  
  39. #int_rda
  40. void serial_isr() {                    // Interrupción recepción serie USART
  41.  
  42.    rcvchar=0x00;                       // Inicializo caracter recibido
  43.    if(kbhit()){                        // Si hay algo pendiente de recibir ...
  44.       rcvchar=getc();                  // lo descargo y ...
  45.       addcbuff(rcvchar);               // lo añado al buffer y ...
  46.    }
  47. }
  48.  
  49. // Desarrollo de Funciones ////////////////////////////////////////////////////
  50. int addcbuff(char c){                  // Añade a cbuff -----------------------
  51.  switch(c){
  52.          case 0x0D:                    // Enter -> Habilita Flag para procesar
  53.             flagcommand=1;             // Comando en Main
  54.        
  55.             break;
  56.          default:
  57.             cbuff[xbuff++]=c;          // Añade caracter recibido al Buffer
  58.          
  59.       }
  60. }
  61.  
  62. void inicbuff(void){                   // Inicia a \0 cbuff -------------------
  63.    int i;
  64.  
  65.    for(i=0;i<lenbuff;i++){             // Bucle que pone a 0 todos los
  66.       cbuff[i]=0x00;                   // caracteres en el buffer
  67.    }
  68.    xbuff=0x00;                         // Inicializo el indice de siguiente
  69.                                        // caracter
  70. }
  71. // Programa Principal /////////////////////////////////////////////////////////
  72.  
  73. void main() {
  74.    printf("\r\n\** prueba buffer **\r\n\r\n");  // Presenta menú
  75.  
  76.    enable_interrupts(int_rda);                   // Habilita Interrupción RDA
  77.    enable_interrupts(global);                    // Habilita interrupciones
  78.  
  79.    do {
  80.       if(flagcommand) procesa_comando();         // Si hay comando pendiente de procesar ... lo procesa.
  81.         printf("..\r"); // printf CR              
  82.    } while (TRUE);
  83.  
  84. }
  85. // Procesador de Comandos /////////////////////////////////////////////////////
  86.  
  87. void procesa_comando(void){
  88.  
  89.    int i, j;
  90.    char salida[lenbuff];                   // Argumento de comando (si lo tiene)
  91.  
  92.    disable_interrupts(int_rda);
  93.    flagcommand=0;                       // Desactivo flag de comando pendiente.
  94.  
  95.       j=0;
  96.       for (i=0;i<xbuff;i++){
  97.        if (cbuff[i] == '$')
  98.         while((cbuff[i] != 0x4A) & (i<xbuff))
  99.           {
  100.            salida[j++]=cbuff[i++];
  101.            printf ("%c",salida[j-1]); // Monitorizamos el argunmento.
  102.           }
  103.            i++;
  104.            }
  105.                                
  106.    inicbuff();                          // Borro buffer.
  107.  
  108.    for(i=0;i<lenbuff;i++){             // Bucle que pone a 0 todos los
  109.       salida[i]=0x00;                     // caracteres en el argumento
  110.  
  111.    }    enable_interrupts(int_rda);
  112.    }

Por cierto Red_Pic, cuando te sea posible, si puedes, por favor.  hazle esa adapatación que te comenté en el anterior post. Gracias.

GRACIAS A TODOS Y:

[scroll]DESDE A CORUÑA, ESPAÑA PARA EL MUNDO, SALUDOS DE  Santipic[/scroll]







Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: SOS en control de buffer
« Respuesta #6 en: 24 de Septiembre de 2006, 03:10:34 »
Así dá gusto ... ja ja ja  :D  :D  :D

Si esto no es el espíritu del Foro, que venga Dios y lo vea.  :mrgreen:

Santi, enhorabuena por haberlo conseguido y por la alegría que muestras, que es nuestra alegría.  :-/

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado jorge luis

  • PIC10
  • *
  • Mensajes: 13
Re:SOS en control de buffer
« Respuesta #7 en: 17 de Octubre de 2015, 03:59:37 »
hola, una consulta yo tengo implementado el siguiente codigo, pero al simular en proteus, el do while de la interrupcion RDA solo me esta capturando el valor del caracter que llega, la variable data se esta actualizando pero no se adiciona a la variable cadena, es decir no se esta juntando los caracteres en el array cadena. podrian ayudarme con esta duda por favor, probe en proteus simulando paso a paso y ahi pude ver que solo el valor de la variable "data" se va actualizando, mientras que la variable "cadena" no actualiza ninguno de sus caracteres ni siquiera el primer caracter, ayuda por favor.

Código: [Seleccionar]
#include <16f877a.h>
#include <string.h>
#include <stdlib.h>
#fuses NOWDT,HS,NOLVP
#use delay(clock=10M)

#use RS232(baud=9600,XMIT=PIN_C6,RCV=PIN_C7,stream=receptor)

#bit RB0=0x06.0
#bit RB1=0x06.1
#bit RC3=0x07.3
#bit RC4=0x07.4
#bit RC7=0x07.7

int i;
int const length=10;
char data;
char cadena[length];
short flagcomand=0;
signed int16 p=0;

#int_RDA
void  RDA_isr(void)
{
   do
   {
    data=fgetc(receptor);
    if(data=='\0')
      {
       break;
      }
    else
      {
       cadena[i]=data;
       i++;
      }
   }while(kbhit(receptor));
  flagcomand=1;
}


void limpiar_buffer()
 {
  int j;
  for(j=0;j<length;j++)
   {
    cadena[j]=0x00;
   }
 }

#INT_EXT                    // directiva de interrupcion por cambio de estado en RB0
void interrupcion_RB0()
{
 if(RB0==1)
   {
    ext_int_edge(H_TO_L);
    if(RB1==1)
      {
       p=p+1;
      }
   }
 else
   {
    ext_int_edge(L_TO_H);
    if(RB1==1)
      {
       p=p-1;
      }
   }
 //putc(p);
 //puts(p);
 printf("\r%Ld",p);
}

void main()
{
  //char valorRec[4];          //variable donde se recibira desde la cadena
  char c;
  int d;
 
 set_tris_b(0xFF);               //configuro portb=in
 set_tris_c(0x80);               //solo el Rx esta como entrada
 RC3=0;
 RC4=0;
 //configuracion pwm
 setup_ccp1(CCP_PWM);
 setup_timer_2(T2_DIV_BY_16,255,1);      //Tpwm=1.63ms--->el ciclo de trabajo sera de 0-255
 set_timer2(0);
 set_pwm1_duty(0);
 enable_interrupts(INT_RDA);
 enable_interrupts(INT_EXT);     //habilito interrupcion RB0
 ext_int_edge(L_TO_H);           //configuro interrupcion por flanco de subida
 enable_interrupts(GLOBAL);      // habilito interrupcion global
 
 
 while(TRUE)
  {
   //gets(valorRec);
   c=cadena[0];
   if(flagcomand==1)
    {
    flagcomand=0;
   switch(c)
     {
      case 's':
        {
         //printf("%3Lu",p);
         //putc(p);
         //printf("%3u",pv);
         //delay_ms(500);
         break;
        }
      case 'i':
         {
          RC3=0;
          RC4=1;
          break;
         }
      case 'd':
         {
          RC3=1;
          RC4=0;
          break;
         }
      default:
         {
          d=atoi(cadena);
          set_pwm1_duty(d);
          //putc(p);
          //printf("%3Lu",p);
          break;
         }
     }
   limpiar_buffer();
   }
 }

}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:SOS en control de buffer
« Respuesta #8 en: 17 de Octubre de 2015, 04:23:38 »
jorge trata de poner tus dudas en un solo lugar.
Ubicandolo en varios lugares lo unico que vas a hacer es que se creen varios hilos y tengas que navegar por varias paginas para seguir el tema, en el cual se pueden repetir opiniones.

Asi que te respondi en el otro :

http://www.todopic.com.ar/foros/index.php?topic=44335.msg377276#msg377276

Desconectado jorge luis

  • PIC10
  • *
  • Mensajes: 13
Re:SOS en control de buffer
« Respuesta #9 en: 17 de Octubre de 2015, 05:14:06 »
Gracias por responder KILLERJC, y por la observación de publicar en un solo lugar. Voy a modificar los cambios que me mencionas en el otro lado y ahi mismo te comento que me resulta. Gracias por las sugerencias.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re:SOS en control de buffer
« Respuesta #10 en: 17 de Octubre de 2015, 09:54:42 »
Veo un problema con la variable i, esta deberia ir de 0 a 10 en tu programa debido a la constante length = 10, eso te dara problemas.
Y lo otro lo que comento Killerjc de no realizar varios post iguales.

Saludos


 

anything