TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: juno303 en 09 de Octubre de 2004, 08:32:00

Título: Funcion GETS() y el stream rs232
Publicado por: juno303 en 09 de Octubre de 2004, 08:32:00
Hola, estoy trabajando con el puerto serial, y necesito enviar al pic unos datos.
Hice la siguiente funcion para atender a la interrupccion de cuando hay datos en el 232

#INT_RDA
void rsis(void)
{

   char string[20];


   printf("
Tiempo de encendido: ");
   gets(string);
   ton=atol(string);

   printf("
Tiempo de apagado: ");
   gets(string);
   toff=atol(string);

}

Como podran ver, al ser lanzada la interrupcion, el pic imprime: Tiempo de encendido:  y luego llama a un GET string gets() para agarrar la cadena, que segun lei retorna de la funcion cuando encuentra un ENTER (/13), Hasta aqui todo bien, el pic pide el dtao, le das, y tdoo bien, pasa al siguiente y ok, pero al darle enter al siguiente, se queda la funcion en  un loop infinito, y el GETS() ya no espera al ENTER, nadamas llama y retorna al instante, como si hubiese quedado el ENTER en el stream, como hago para refrescar el stream del 232, o sea, borrar todo lo que haya, algo asi como la funcion fflush de C.

Graciass
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 09 de Octubre de 2004, 10:50:00
A ver si lo entiendo. El primer gets te funciona, tú le das al enter y pasa al 2º gets donde teóricamente debiera almacenar lo que le mandas hasta encontrar un RETURN. Recibido este saldrá de la interrupción.

Según tú al recibir el 2º RETURN ¿se queda en un bucle infinito? ¿o sale de la interrupción? Si sale de la interrupción está bien ¿no?

Un saludo
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 09 de Octubre de 2004, 13:39:00
queda en loop infinito,  o sea los dos primeros enters los acepta bien, pero luego queda en loop toda la rutina de interrupcion, y cuando llega a la fucnion gets() esta vuelve inmediatamente, como si fuese que le dejaras apretado el ENTER, por eso quisiera saber como hacer un flush del stream
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pacalaconcurso en 09 de Octubre de 2004, 16:14:00
es el típico fallo de overun del buffer
recuerda que mientras ejecutas el codigo de la interrupcion esta se queda desatendida....

el codigo que ejecutas en la interrupcion es demasiado largo... solo deberias llenar un buffer con los caracteres que llegan y en todo caso activar un flag para saber en tu main que hay datos nuevos.

cuando configures el puerto añade ERRORS para que se limpien los errores de recepcion.

saludos
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 09 de Octubre de 2004, 20:42:00
no es un problema de overrun, por que no pierdo ningun dato, ademas como podras ver el codigo es muy sencillo.

Pasa que despues de ejecutar GETS(), al parecer queda lo mismo en el stream el ENTER, por eso sigue llamandose a la interrupcion ni bien salgo de ella. A ver quien me ayuda...
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 11 de Octubre de 2004, 12:07:00
por favo que alguien me ayude... aun sigo sin poder hacer nada...
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 11 de Octubre de 2004, 13:14:00
Pués no entiendo porque al recibir el 2º ENTER (RETURN) te vuelve a entrar en la interrupción.

Pega el código, a ver si te lo solucionamos.

Un saludo
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 11 de Octubre de 2004, 17:17:00
#include <18F452.h>
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7)


#include <stdlib.h>

unsigned int ton=0;
unsigned int toff=0;

#INT_RDA
void rsis(void)
{

char string[20];

getc();

printf("
Tiempo de encendido: ");
gets(string);
ton=atol(string);

printf("
Tiempo de apagado: ");
gets(string);
toff=atol(string);

}




void main()
   {
   unsigned int z;
   
    enable_interrupts(INT_RDA);
     enable_interrupts(GLOBAL); // Habilita todas las interrupciones.
     printf(" Presione una tecla para setear datos");


      set_tris_d(0x00);

     while(1)
      {

     
      output_d(0xff);
      for(z=0; z<ton; z++)  delay_us(10);

      output_d(0x00);
      for(z=0; z<toff; z++)  delay_ms(1);
           

       }


}




este es el codigo, deben simularlo con una terminal en el proteus, al inciar presionen cualquier tecla, luego le pide los datos, toodo bien, luego veran que pasa...

 
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 12 de Octubre de 2004, 01:02:00
Te lo voy a mirar, aunque has introducido un getc() que antes no estaba.
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 12 de Octubre de 2004, 02:03:00
Esta es la solución (usando un 876):

Codigo:
//#include <18F452.h>
#include <16F876.h>  
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7)


#include <stdlib.h>

unsigned long int ton=0;
unsigned long int toff=0;

#INT_RDA
void rsis(void)
{

char string[20];

//getc();

//printf("
Tiempo de encendido: ");
gets(string);
ton=atol(string);

printf("
Tiempo de apagado: ");
gets(string);
toff=atol(string);

printf("
Tiempo de encendido: ");

}




void main()
{
unsigned long int z;

enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL); // Habilita todas las interrupciones.
//printf(" Presione una tecla para setear datos");
printf("
Tiempo de encendido: ");

//set_tris_d(0x00);
set_tris_b(0x00);  

while(1)
{


//output_d(0xff);
output_b(0xff);  
for(z=0; z<ton; z++)
    //delay_us(10);
    delay_ms(1);  

//output_d(0x00);
output_b(0x00);  
for(z=0; z<toff; z++) delay_ms(1);


}


}



Tenías algunos errores. Sobretodo lo que creo que te mareaba era el "pulse una tecla". Ten encuenta que al pulsar la tecla ese primer caracter ya formará parte del ton y si resulta que como primera tecla pulsas una letra pues en fin, sin comentarios.

Un saludo
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 12 de Octubre de 2004, 11:00:00
por eso le puse GetC, para que tome ese caracter, y luego imprimir:  Tiempo de encendido...

entiendes ?,  esta solucion no sirve, por que en realidad, el pic va a estar enviando algunos datos por serial, y si tu presionas una tecla tiene que ir al menu de recepcion de datos. Por eso lo hice de esa manera...

tu como harias si tienes que, cuando presiona una tecla, diga: Inserte TON,  scanear lo que inserto, inserte TOff, scanear lo que inserto, Gracias por insertar.... de vuelta a esperar que se presione una tecla...

saludos
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 12 de Octubre de 2004, 11:04:00
el problema reside en eso que te digo del GETS()
al finalizar la interrupcion, creo que la solucion sería borrar el buffer del rs232... pero no se donde llo aloja el picc...

ademas, simulalo, hace lo mismo que el mío, queda en loop...
fijate...

una pregunta, por que lo hiciste para el 16f876 ???


Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 12 de Octubre de 2004, 11:38:00
El programa que te he enviado funciona bien, está simulado. La única precaución es que cuando en el hiperterminal te pida el tiempo de encendido que envies un número no una letra.

En fin, a mí me va bien, no sé porqué dices que se sigue quedando en bucle infinito.

Lo he hecho para un 876 porque el PROTEUS con los delays para los PIC18 es un poco puñetero y no los saca bien.

Un saludo
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 12 de Octubre de 2004, 14:20:00
Te paso la simulacion que hago yo:
esto es el terminal:

Al comenzar me pide, el tiempo de encendido, le doy 1000 y enter, luego el de apagado le doy 2000 y enter, y luego mira lo que pasa, se repite  por siempre lo de abajo


///////////////////////////////////////////////////////////////////////////////
Tiempo de encendido: 1000

Tiempo de apagado: 2000

Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Tiempo de apagado:
Tiempo de encendido:
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 13 de Octubre de 2004, 00:01:00
Vaya, pués entonces habrá que pensar en otra cosa.

Te mando el .hex a ver si la culpa la tiene el compilador.
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 13 de Octubre de 2004, 09:54:00
no lo puedo creer, tu hex funciona, luego probe tu codigo fuente usando el 16f876, antes habia probado solo con el 18f452, pues me dijiste que usas el 16f876 solo por cuestiones de que funciona mejor el tiempo. Y no lo vas a creer, funciona bien.

El programa funciona bien cuando lo hago para el 16f876, pero con el 18f452 pasa eso que te cuento, pruebalo tu y me dices.

No se que hacer, tendre que actualizar el compilador???

saludos
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 13 de Octubre de 2004, 10:47:00
Las pruebas que has hecho supongo que las has hecho con PROTEUS. Los PIC18 en algunas cosas creo que con PROTEUS no van muy bien. Efectivamente con el 452 pasa eso que dices.

Porqué no haces la prueba físicamente con un PIC18 y salimos de dudas?
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pacalaconcurso en 13 de Octubre de 2004, 15:44:00
permitidme ser pesado
pero usar la INT_RDA de esa forma no es correcto.

prueba tu código en el main veras como te funciona

Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 13 de Octubre de 2004, 21:09:00
oye pocher, si, ya hice la prueba fisica y es la misma cosa. Y vos pacalaconcurso, por que dices que esta mal ?? es que debo usarlo ahi..., como lo harias tu ? con banderas?
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 14 de Octubre de 2004, 04:57:00
A ver si centramos las cosas.

El programa que yo he enviado funciona bien en un 16F876 pero no en un 18F452. Si alguién sabe el porqué de esto, se agradecería una pequeña explicación.

Félix, supongo que tú a lo que te refieres, es a que cada vez que llega un caracter que se dispare la interrupción y desde dentro de esta con getc(), almacenar ese caracter en un buffer al que previamente le habremos dado una dimensión y luego salir de la interrupción.

Ese método está claro, lo que no entiendo es porqué tiene que dar errores haciéndolo con un gets() desde dentro de la interrupción, si a mí no me estan dando errores.

 ¿Quizá la cosa se complique si en lugar de enviar los caracteres uno a uno como es el caso de este programa, se envían a toda leche y saturas el buffer?

Pero es que en el caso que nos ocupa el buffer no se satura nunca.
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 14 de Octubre de 2004, 09:56:00
la verdad que si...

la idea sería borrar el buffer que usa el CCS despues de cada interrupcion...
no se como hacerlo, en C existia una funcion el fflush(stream);
algo asi...
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 14 de Octubre de 2004, 11:07:00
DISCULPAS !
pero entre tantas pruebas y pruebas surgio la confusion, el programa en el 18f452 funciona FISICAMENTE, el problema reside en el PROTEUS.
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 14 de Octubre de 2004, 11:56:00
yo uso el proteus 6.2 SP5, tu que version tienes "??
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 14 de Octubre de 2004, 13:00:00
Yo estoy usando ahora mismo la 6.3 SP1 y tal como te comenté en mensajes anteriores he encontrado problemas con los PIC18 en algunos programas.
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 14 de Octubre de 2004, 13:25:00
ahh, que macana...  y tienes el mismo problema que yo ???

de donde bajaste el proteus que tienes ???
saludos
Título: RE: Funcion GETS() y el stream rs232
Publicado por: pocher en 14 de Octubre de 2004, 13:42:00
Tengo el mismo problema que tú con este programa.
Para bajar "cosas" agénciate el programa emule.
Título: RE: Funcion GETS() y el stream rs232
Publicado por: juno303 en 14 de Octubre de 2004, 13:51:00
ahh. Oye, tu chateas en algun lugar ? o messenger ?