TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: micronet3 en 20 de Junio de 2009, 01:56:30

Título: puts() y gets()
Publicado por: micronet3 en 20 de Junio de 2009, 01:56:30
hola amigos, les cuento que tratando de entablar comunicacion entre pics, me encontre con una dificultad, mi configuracion es de master/slave. yendo a la duda.

idea: deseo enviar  datos del master al slave, en el master utilizare la funcion puts().
         para recepcionar esos datos en el slave utilizare la funcion gets();

es posible que el esclavo reciba correctamente la informacion  que le envia el master.

la funcion puts() aparte de enviar los datos o caracteres envia un retorno de carro y un retorno de linea,
ahora la funcion gets(); termina de recibir los datos en una variable cuando le llega un retorno de carro(enter?)





























Título: Re: puts() y gets()
Publicado por: Suky en 20 de Junio de 2009, 02:27:58
Todo lo dicho es correcto, de esa manera funciona.
Título: Re: puts() y gets()
Publicado por: micronet3 en 20 de Junio de 2009, 02:34:09
ola suky gracias por responder,
 aqui hay algo que no cuadra por ejemplo en el master la funcion  puts envia un retorno de carro y un retorno de linea, aparte de los datos o cadena de caracteres, mientras que la funcion gets()  espera recibir solo un retorno de carro mas no el retorno de linea.
que puede pasar con ese retorno de linea, afecta la comunicacion? o como se haria para que la funcion puts solo envie un retorno de carro(13)?

estare poniendo un ejemplo, tal ves mi error este en otra parte pero igual es algo curioso esto
Título: Re: puts() y gets()
Publicado por: migsantiago en 20 de Junio de 2009, 10:56:40
Gets() va a leer hasta encontrar el RETURN, pero ya no va a capturar el NEW LINE, por lo que tu buffer no se vaciaría y en una nueva recepción aparecerá el NEW LINE anterior.

La ayuda de CCS dice que es mejor usar printf para el envío y para la recepción yo implementaría una función de recepción de caracter por caracter que busque el NULL que envía printf al final.
Título: Re: puts() y gets()
Publicado por: gera en 20 de Junio de 2009, 19:27:11
Claro, la idea de las funciones gets() y puts() es q te vas a comunicar con una terminal, donde el usuario presiona enter al terminar de colocar los datos. Ademas al enviarle datos a la terminal, se envia un retorno de carro y de linea para que el usuario distinga en la terminal los distintos datos q van llegando.
Como dice Santi, podrias enviar tus datos con un
Código: [Seleccionar]
ptrintf("%s",dato_snd);y recibirlos con un
Código: [Seleccionar]
while(*dato_rcv)
   *(dato_rcv++)=getc();

Habria q revisar eso ultimo, porq me parece q dato_rcv va a quedar apuntando un lugar mas alla del caracter nulo.. pero por ahi va la idea.
Saludos!!!
Título: Re: puts() y gets()
Publicado por: micronet3 en 20 de Junio de 2009, 22:59:03
el problema que tengo con el printf es el siguiente.
por ejemplo supongamos que queremos que un pic que tenga dos puertos seriales, bueno como estoy utilizando el 18f4550, este solo tiene un puerto serial implementado por hardware, el otro puerto serial lo implemento por software, que es muy facil en ccs,

#use rs232(baud=9600 xmit=PIN_B6, rcv=PIN_B7, stream=computadora)//puerto implementado por hardware
#use rs232(baud=9600 xmit=PIN_B2, rcv=PIN_B3, force_sw, stream=esclavo)    //puerto implementado por software

al momento de utilizar la funcion printf por ejemplo

printf("%s",dato,computadora)

no envia nada, es como que esta funcion no reconoce porque puerto serial va a salir, sin enbargo utilizando la funcion puts() si envia, ya que para recepcionar con gets(), termina con un retorno de carro, y el retorno de linea queda para la siguiente gets() pero asi se deforma los datos.

asi si reconoce porque puerto serial va asalir
 
puts(dato,computadora)
 que puede ser, como le indico a la funcion printf porque puerto salir.
Título: Re: puts() y gets()
Publicado por: Suky en 20 de Junio de 2009, 23:31:04
No tiene que ir antes el identificador?
Osea:
Código: C
  1. printf(computadora,"%s",dato);
Título: Re: puts() y gets()
Publicado por: micronet3 en 20 de Junio de 2009, 23:57:29
voy a probarlo amigo, asi lo compila correctamente, me guié de la funcion puts o gets, ahi me funcionan correctamente ,
Título: Re: puts() y gets()
Publicado por: gera en 20 de Junio de 2009, 23:58:44
Exacto, el primer parametro de la funcion printf (y todas sus derivadas), es el identificador del buffer a donde vamos a escribir. En una computadora puede ser el stdin, stdout, stderr, un archivo, un socket, un espacio de memoria... en un pic puede ser un puerto serial, un espacio de memoria...
Título: Re: puts() y gets()
Publicado por: micronet3 en 21 de Junio de 2009, 21:18:06
a ya entonces por eso es que no funcionaba.
utilizando las funciones puts y gets, si salia correctamente, osea primero ponia el dato o la cadena que queria enviar o recibir, y luego la direccion del puerto serial, es decir

#use rs232(baud=9600, xmit=PIN_B6, rcv=PIN_B7, stream=computadora)
char string[15];

puts("hola mundo",computadora);
gets(string, computadora);

bueno ese fue mi error, entonces dije si ese es el orden para puts y gets, entonces usando la funcion printf tambien debe tener el mismo orden.
 estoy haciendo el codigo y despues, lo muestro aqui.


Título: Re: puts() y gets()
Publicado por: micronet3 en 21 de Junio de 2009, 21:20:52
muchisimas gracias a todos, cosa que no significa que ya que solucione el problema me voy, sino al contrario me quedo.
Título: Re: puts() y gets()
Publicado por: micronet3 en 21 de Junio de 2009, 21:46:17
pues si tienen razon, primero se pone la direccion por ejemplo:

printf(LCD_PUTC, "Pres=%4lu",presion);

yo como tengo definido dos puertos seriales uno por hardware y otro por software utilizando el pic 18f4550

#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,stream=pc) //por hardware
#use rs232(baud=9600, xmit=PIN_B0, rcv=PIN_B1,stream=nodo) //por software

al utilizar la sintaxix

printf(nodo,"%s",string);
no compila, se genera un error. "expecting LVALUE such as variable name or expresion ::"

 sin embargo si utilizo la otra forma

printf("%s",string,nodo);
si compila correctamente pero no envia informacion


 
Título: Re: puts() y gets()
Publicado por: micronet3 en 21 de Junio de 2009, 21:49:32
esto me genera un error no compila:

#include <18F4550.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //HS Osc
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES PUT                      //Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                   //Master Clear pin used for RESET
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,stream=pc)

#INT_RDA
void serial_isr()
{

}

void main() {

char dato[20]="hola";
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_OFF);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(VREF_LOW|-2);
   setup_low_volt_detect(FALSE);
   set_tris_b(0);
   
   enable_interrupts(INT_RDA);
   enable_interrupts (GLOBAL);

   while (true)
   {
   
   printf (pc,"%s",dato);

   };

}
Título: Re: puts() y gets()
Publicado por: Suky en 21 de Junio de 2009, 22:19:13
Lo solucione agregando dos funciones que hacen de intermedarias:

Código: C
  1. #use rs232(baud=9600,parity=N,xmit=PIN_A3,rcv=PIN_A2,bits=8,STREAM=Pepe)
  2. #use rs232(baud=9600,parity=N,xmit=PIN_B0,rcv=PIN_B1,bits=8,STREAM=Nene)
  3.  
  4. void pepeTx(char c){
  5.    putc(c,pepe);
  6. }
  7. void neneTx(char c){
  8.    putc(c,nene);
  9. }
  10.  
  11.    printf(pepeTx,"envia a pepe");
  12.    printf(neneTx,"envia a nene");
Título: Re: puts() y gets()
Publicado por: MLO__ en 21 de Junio de 2009, 23:16:45
Hola.

Para usar directamente los streams declarados en el #use rs232 se tiene:

Código: [Seleccionar]
fprintf(pc, "dato al PC");
Saludos
Título: Re: puts() y gets()
Publicado por: micronet3 en 22 de Junio de 2009, 04:41:34
pues efectivamente, tienen razon asi si funcionan, busque informacion de la funcion fprintf y encontre lo siguiente

Función fprintf ANSI C

int fprintf(FILE *stream, const char *formato, ...);

Esta función envía datos al stream apuntado por stream, bajo el control de la cadena apuntada por formato que especifica cómo los argumentos posteriores son convertidos para la salida. Si hay argumentos insuficientes para el formato, el comportamiento no está definido. Si el formato termina mientras quedan argumentos, los argumentos restantes son evaluados (como siempre) pero ignorados. La función retorna control cuando el final de la cadena de formato es encontrado.

Título: Re: puts() y gets()
Publicado por: micronet3 en 25 de Junio de 2009, 09:14:36
Ahora lo que estoy pensando es agregarle un relog en tiempo real, que puede ser el ds1307.
este CI funciona mediante el bus I2C, una duda, se puede comunicar este bus por software? o es necesario que el pic tenga implementado este periferico por hardware, o este depende de la libreria que se esta utilizando.
yo he visto varias librerias en el internet y estoy viendo cual de ellas es la mas conveniente.

Título: Re: puts() y gets()
Publicado por: MLO__ en 25 de Junio de 2009, 10:29:37
Hola.

Si usas el CCS si se puede trabajar el i2c por software, de hecho, CCS lo trabaja por software por default.
Título: Re: puts() y gets()
Publicado por: RALF2 en 29 de Noviembre de 2009, 14:38:05
Que tal amigos!
Voy a aprovechar este post para ver si alguien me puede decir que estoy haciendo mal o que le falta a mi programa  :(

Citar
#include <18f252.h>
#use delay (CLOCK = 40000000)
#fuses H4,PUT,NOWDT,NOSTVREN,CCP2C1,NOOSCSEN

#use rs232(baud=9600, xmit=pin_b7, rcv=pin_b6,stream=computadora)

#define LCD_ENABLE_PIN  PIN_C2                                  
#define LCD_RS_PIN      PIN_C0                                  
#define LCD_RW_PIN      PIN_C1                                  
#define LCD_DATA4       PIN_C4                                  
#define LCD_DATA5       PIN_C5                                  
#define LCD_DATA6       PIN_C6                                  
#define LCD_DATA7       PIN_C7

#include <lcd.c>

void main()
{
   char str1[20];
  
   lcd_init();
   while(1)
   {
      gets(str1,computadora);
      printf(lcd_putc,"%s",str1);
    
   }
  
}

Lo pruebo en el proteus y nada no me funciona y en fisico tampoco, no logro ver donde esta el error
Agradezco cualquier ayuda!
Gracias
Título: Re: puts() y gets()
Publicado por: Suky en 29 de Noviembre de 2009, 14:58:04
gets termina la recepción de datos cuando recibe salto de linea y retorno de carro, lo estas asiendo así?

Exactamente cual es el problema, no recibís nada?

Saludos!
Título: Re: puts() y gets()
Publicado por: RALF2 en 29 de Noviembre de 2009, 15:33:30
Que tal suky!
Mira como ves en el archivo adjunto que coloque cuando escribo por ejemplo "hola" y presiono enter en la lcd no me aparece nada al igual que en la varible str1  :5]
Se supone que gets deberia ir almacenandome los caracteres que vaya ingresando en str1 hasta que pulse enter y luego me deberia mostrar en la lcd las teclas que pulse pero como ves no hace nada no me almacena los datos en str1 por lo que no me muestra nada la lcd, porque?
He alli el dilema  :shock:

Saludos
Título: Re: puts() y gets()
Publicado por: Suky en 29 de Noviembre de 2009, 16:19:11
No funciona  :5] Si se lee byte a byte hasta leer 0x0D con getc funciona  :shock:




Off topic: Gooool Del Barca  :-/  :mrgreen:
Título: Re: puts() y gets()
Publicado por: RALF2 en 29 de Noviembre de 2009, 16:27:01
Hola suky
Si con getc funciona perfecto pero con el gets nada de nada de hecho probe el ejemplo que coloca la ayuda donde esta el gets y no funciona debe ser un bug al que no le han parado mucho la gente del ccs, porque en input.c utilizan el getc para capturar el string  :shock:

Bueno alli queda eso para los que se les ocurra entrar en el misterioso mundo del gets  :D

Saludos
Título: Re: puts() y gets()
Publicado por: RALF2 en 29 de Noviembre de 2009, 21:15:36
Buenas!
Revizando el programa con la ayuda del maestro palitroquez he podido resolver el problema  :-/ :mrgreen:
La falla se deriba del proteus  :shock:   si otra vez me dejo mal mi querido simulador  :(
pero bueno nada es perfecto  :D

Les adjunto el programa con el nuevo diseño  ;-)

Saludos
Título: Re: puts() y gets()
Publicado por: PalitroqueZ en 29 de Noviembre de 2009, 21:19:18
nooo vale jeje ni que maestro voy a ser yo   :)

Título: Re: puts() y gets()
Publicado por: Suky en 29 de Noviembre de 2009, 21:21:55
La falla se deriba del proteus  :shock:   si otra vez me dejo mal mi querido simulador  :(

 :D :D Era de esperar  :5]

Hay que hacerle caso a Santiago me parece  :mrgreen: Grande Pali!!



Saludos!
Título: Re: puts() y gets()
Publicado por: RALF2 en 30 de Noviembre de 2009, 00:51:02
Bueno bueno sigo en la lucha con el gets  :shock:
Probe el codigo con un pic18f252 en fisico y lamentablemente tampoco funciono  :5] apenas tenga un chance pruebo con un pic16f876A para ver, si definitivamente el problema esta en el proteus o en el CCS  :shock:
No se si sera mi codigo que no le gusta al pic o al ccs pero bueno si alguien tiene un pic18f252 y lo puede probar en fisico o postar aqui un codigo de prueba no estaria de mas y asi salgo de la duda  :mrgreen:
 
Título: Re: puts() y gets()
Publicado por: RALF2 en 01 de Diciembre de 2009, 21:28:47
Que tal amigos!
Coloco esta informacion para corregir algunas cosas que escribi arriba  :mrgreen:
Realizando pruebas con el pic 18f252 operando a 40Mhz los resultados obtenidos, fueron que el ccs falla cuando el pic opera a esa velocidad con el gets  :shock:  asi es amigos el problema no se debe al proteus sino al ccs!.
El problema lo solvente cambiando el cristal por uno de 4Mhz y luego con uno de 20Mhz, con ambos probe y el gets funciona como se debe, pero, si coloco un cristal de 10Mhz y activo el pll el gets falla  :5]
Les coloco esta aclaratoria que considere pertinente y para corregirme a mi mismo!

Saludos
Título: Re: puts() y gets()
Publicado por: MLO__ en 01 de Diciembre de 2009, 23:14:41
Recuerdo ahora que un forero uso un cristal de 8MHz u otro (no recuerdo bien) y no le funcionaba bien la transmisión serial. Raro, raro ..... !!!! nada raro tratándose de CCS.

Saludos
Título: Re: puts() y gets()
Publicado por: RALF2 en 01 de Diciembre de 2009, 23:42:20
Asi es MLO_

Yo lo probe con un cristal de 20Mhz y trabaja fino el problema esta cuando uno opera a alta frecuencia de hecho probe con un cristal de 4Mhz y el PLL activado (16Mhz) y funciona bien pero cuando le meto un cristal de 10Mhz para que opere a 40Mhz no trabaja.
Por lo visto la libreria no esta ajusta bien para operar a altas frecuencias  :(
Título: Re: puts() y gets()
Publicado por: vasconinicolas en 30 de Mayo de 2010, 22:50:10
Perdon la intromisión y después de tanto tiempo, pero se me ocurría pensar que usar la función gets, sobre todo, me simplifica el código para recibir por RS232 por ejemplo, si lo comparamos con la recepcion con getc + buffer etc (que por cierto anda de 10). Pregunto, funcionará hacer una rutina con algún timer para que, en caso que venga llegando un string y por error nunca llegue el caracter de final de instrucción (el enter), la rutina nos saque del bucle gets? (sino entiendo que el programa del pic se va a quedar esperando eso y se producirá la "clavada del pic"). Lo voy a intentar porque me resisto a creer que el gets no se aconseja usar siendo tan facil.
Un abrazo a todos.
N
Título: Re: puts() y gets()
Publicado por: aprediz en 08 de Junio de 2010, 05:25:58
Que tal, soy nuevo en el foro,  entiendo que pueden ayudar con temas relacionados con pics, les comento algo que no puedo resolver, y agradecería la ayuda.
Estoy realizando pruebas de comunicación rs485 entre dos PIC18F242 con SN75176, la idea es que uno mande un dato serial cada cierto tiempo, y el otro reciba este dato confirmando una petición, al recibir este debe mandar 4 datos(4 bytes), -ahí- está el problema no puedo almacenar los 4 datos, solo uno, con la función getc();, he buscado información al respecto e incluso adquirí un libro pero no encuentro nada que me  ayude, les dejo algo de mi código solo para que puedan ver lo perdido que estoy, hace poco estoy intentando programar en lenguaje c.
Sin más por el momento agradezco que se tomen un minuto de su tiempo para poder ayudar a un desorientado.

Un saludo.

//parte en la que quiero almacenar 4 bytes
#define var1[4]

#int_rda
void serial_isr()
{
    disable_interrupts(global);
    var1=getc();
    enable_interrupts(global);
}