Autor Tema: enviar bytes , buffer lleno?  (Leído 2883 veces)

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

Desconectado tinchomar

  • PIC10
  • *
  • Mensajes: 9
enviar bytes , buffer lleno?
« en: 26 de Abril de 2011, 18:37:02 »
Hola soy nuevo en el foro y en ccs con pics y si es posible agradeceria una ayuda. :-/
Quiero hacer un control robotico con unos controles inalambricos manejados por rs232, de modo de controlar con pwm los motores atraves de un joystic tipo control analogico de los playstations.
Eso a futuro obviamente, empece con tratar de enviar informacion pic a pic conectados fisicamente por el puerto serie, pero el problema es que el receptor al recibir ,valga la redundancia, el byte de info que le envio pareceria que se trabara (buffer lleno?) y se queda con un numero trabado. Adjunto una imagen de simulacion, en ella se traba en 49, y probando fisicamente se traba en 128.
Alguna idea?
Gracias.

Código: [Seleccionar]
///////////////////////Transmisor:

#use delay (clock=4000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)

int c=0x00;
void main(){
 
      while(true){
                  printf("%U",c);
                  ++c;
                  delay_ms(500);
      }
}

/////////////////////Receptor:

#use delay (clock=4000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define LCD_DB4   PIN_d0
#define LCD_DB5   PIN_d1
#define LCD_DB6   PIN_d2
#define LCD_DB7   PIN_d3
#define LCD_RS    PIN_d4
#define LCD_RW    PIN_d5
#define LCD_E     PIN_d6

#include <flex_lcd.c>

void main(){
lcd_init();
int rec=0x00;

while (TRUE) {
                //rec=0x00;
                if (kbhit()) {
                              rec=getc();}

printf(lcd_putc,"\fAn = %U" ,rec); 

delay_ms(200);
                           
}
}

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: enviar bytes , buffer lleno?
« Respuesta #1 en: 26 de Abril de 2011, 19:16:06 »
El problema puede ser que estas enviando más de 1 byte y solo recibes 1. Si las dos posiciones del registro RCREG están llenas y se detecta el bit de Stop de un tercer dato de recepción, se activará el indicador de sobreescritura OERR (RCSTA<1>).
La única manera de limpiar el bit OERR una vez que ha sido activado es reseteando el módulo de recepción, si no se limpia OERR se bloquea la transferencia de datos de RSR a RCREG y no puede haber más recepción de datos.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado tinchomar

  • PIC10
  • *
  • Mensajes: 9
Re: enviar bytes , buffer lleno?
« Respuesta #2 en: 26 de Abril de 2011, 19:58:19 »
Citar
El problema puede ser que estas enviando más de 1 byte y solo recibes 1. Si las dos posiciones del registro RCREG están llenas y se detecta el bit de Stop de un tercer dato de recepción, se activará el indicador de sobreescritura OERR (RCSTA<1>).
La única manera de limpiar el bit OERR una vez que ha sido activado es reseteando el módulo de recepción, si no se limpia OERR se bloquea la transferencia de datos de RSR a RCREG y no puede haber más recepción de datos.

Hola Suky, gracias por responder, tengo que aprovechar y decirte que leo muy amenudo las soluciones que das y son impecables.
Bueno evidentemente ese parece ser el problema, pero antes de insertar una rutina en asm probe cambiar el PRINTF por el PUTC, que segun lei es menos complejo que el anterior, por decirlo de alguna manera  :? y ahora si recibo el byte como necesito y se ve el valor del TX en el RX.
De todas formas te agradezco por darme a conocer esa bandera de ese registro, la verdad no la tenia.
El proximo reto sera leer de dos conversores AD y enviar la informacion al otro pic, no se todavia si enviarlos por separado e intentarlos diferenciar de alguna manera o mandar los dos juntos y separarlos en destino, vamos a ver como salen las pruebas, por lo que lei el buffer de recepcion en rs232 por harware tiene hasta 2 bytes de espacio, voy a probar.

Saludos.
« Última modificación: 26 de Abril de 2011, 20:54:50 por tinchomar »

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: enviar bytes , buffer lleno?
« Respuesta #3 en: 26 de Abril de 2011, 23:34:57 »
Podes mandarlo todo junto, lo que si la rutina de recepción tiene que ser tal que reciba todos los bytes y luego los trate, entonces no tendrás problema.  ;-)

El problema de usar printf("%U",c), es que estas formateando la variable a un string, entonces dependiendo del valor no sabras que largo tiene la trama a recibir. Lo que se puede hacer es agregarle un caracter que indique es es final de trama, por ejemplo printf("%U\n",c). Entonces en el receptor podrías hacer:

Código: C
  1. char rec[5],k;
  2.  
  3. k=0;
  4. while(1){
  5.      if (kbhit()){
  6.           rec[k]=getc();
  7.           if(rec[k]=='\n'){
  8.               rec[k]=0; // reemplazamos por carácter nulo para indicar final de string
  9.               printf(lcd_putc,"\fAn = %s" ,rec);  
  10.               k=0;
  11.           }else{
  12.               k++;
  13.           }
  14.      }
  15. }


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado tinchomar

  • PIC10
  • *
  • Mensajes: 9
Re: enviar bytes , buffer lleno?
« Respuesta #4 en: 27 de Abril de 2011, 15:20:22 »
Gracias Suky por la pista, implemente algo parecdido a lo que me mostras pero aun asi se traban los numeros al llegar a destino, algo estoy haciendo mal pero no se que sera, seguire probando.
Creo o mas bien no se si la variable que va recibiendo los datos puede ser char, aunque en realidad lo que se transmiten son caracteres...asi que no se.
De todas formas aca esta lo que no funciona.

Saludos.

Código: [Seleccionar]
////////////////////////////////////////////TX///////////////////////////////////

#include <16f876A.h>
#device ADC=8
#FUSES NOWDT, XT, NOPUT, NOLVP
#use delay (clock=4000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)//, bits=8, parity=N)

void main(){

int ejex,ejey;
long eje_xy;

setup_adc_ports(AN0_AN1_AN3);
setup_adc(ADC_CLOCK_INTERNAL); // Trabajo con reloj interno

 while(true){
 
         set_adc_channel(0); //Selecciono canal 0 de ADC
         delay_us(30);
         ejex=read_adc(); //Leo el ADC0 y ejey toma su valor
         
         delay_us(50);
         
         set_adc_channel(1);  //Selecciono canal 1 de ADC
         delay_us(30);
         ejey=read_adc();  //Leo el ADC1 y ejex toma su valor

     ejex=make8(eje_xy,0);
     ejey=make8(eje_xy,1);
   
     printf("%lu\n",eje_xy);
      delay_ms(300);

/////////////////////////////////////////RX////////////////////////////////////////
void main(){
lcd_init();

int ejex,ejey;
char rec[3],k;
k=0;

while (TRUE) {             
              if (kbhit()) {
                            rec[k]=getc();
                           
                          if(rec[k]=='\n'){                     
                                rec[k]=0;                                                             
                              }
                           else {
                                if(k==0) ejex=rec[k];
                                if(k==1) ejey=rec[k];
                                k++;
                          }
                                                                             
                                                                                                 
printf(lcd_putc,"\fAn = %U" ,ejex); 
printf(lcd_putc,"\nAn = %U" ,ejey);


Desconectado tinchomar

  • PIC10
  • *
  • Mensajes: 9
Re: enviar bytes , buffer lleno?
« Respuesta #5 en: 28 de Abril de 2011, 21:47:49 »
Despues de renegar y tratar de enviar los datos en 2 bytes , cosa que no funcionaba, no llegan bien,no se porque ,ahora en lugar de enviarlos con printf los envio separados con putc y un caracter para indicar el comienzo de la trama, ahora funcionando, aca esta:

Gracias Suky por las ideas.
Saludos.

Código: [Seleccionar]
TX

      putc(0x0d);
      putc(ejex);
      putc(ejey);

RX

while (TRUE) {             
              if (kbhit()) {
                            rec=getc();
                           
                          if(rec==0x0d){                     
                             for(k=0;k<=1;k++){
                                 recf[k]=getc();
                             }
                              }
              }
ejex=recf[0];
ejey=recf[1];
                                                                                                                                                                           
printf(lcd_putc,"\fAn = %U" ,ejex); 
printf(lcd_putc,"\nAn = %U" ,ejey);