Autor Tema: Cambiar el TIMEOUT del RS232 en tiempo de ejecución  (Leído 2814 veces)

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

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Cambiar el TIMEOUT del RS232 en tiempo de ejecución
« en: 27 de Septiembre de 2013, 12:32:13 »
Hola a todos, es que me he encontrado con un jodido problema:

Como ustedes sabrán, para configurar el RS232 es con la siguiente linea:

Código: [Seleccionar]
#Use Rs232(STREAM = UART1, Baud=9600,Parity=N,Bits=8, UART1, DISABLE_INTS, ERRORS, TIMEOUT=500)

Donde TIMEOUT, es el tiempo en milisegundos, que el RS232 esperara, hasta obtener un dato al ejecutar GETC();

Pero lo que quiero ahora es una linea que me permita cambiar el TIMEOUT mientras el programa se esta ejecutando en el PIC, lo que quiero hacer es una vez el pic haya inicializado el modulo inalambrico, quiero que el TIMEOUT sea de 50 Ms y no de 500 Ms que es como lo configuro al principio. Todo esto es lenguaje C del CCS PIC C COMPILER. Saludos

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Cambiar el TIMEOUT del RS232 en tiempo de ejecución
« Respuesta #1 en: 27 de Septiembre de 2013, 12:46:17 »
y por qué no eliminar todo TIMEOUT de la configuración y hacer una subrutina que lea y espere los milisegundos deseados?

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Re: Cambiar el TIMEOUT del RS232 en tiempo de ejecución
« Respuesta #2 en: 27 de Septiembre de 2013, 13:14:08 »
Gracias por la ayuda. El motivo es porque necesito que el GETC compruebe la UART cada menor periodo de tiempo posible, pero si uso una rutina tipo Delay_Ms o Delay_Us, me gastaria varios ciclos de reloj innecesarios, y entonces tendría que utilizar ASM y hacer los delays manualmente y eso es muy molesto. Ademas es como controlar un servo, hacerlo utilizando DELAY_US resultaría en un desastre.

También había pensado en hacer:

Código: [Seleccionar]
#Use Rs232(STREAM = UART1, Baud=9600,Parity=N,Bits=8, UART1, DISABLE_INTS, ERRORS, TIMEOUT=500)
#Use Rs232(STREAM = UART2, Baud=9600,Parity=N,Bits=8, UART1, DISABLE_INTS, ERRORS, TIMEOUT=50)

No estoy seguro que funcione, porque todavia no lo he probado. La idea es cuando necesite hacer un GETC de 50 ms, utilizar el UART2. Ustedes que opinan? funcionara?

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Cambiar el TIMEOUT del RS232 en tiempo de ejecución
« Respuesta #3 en: 27 de Septiembre de 2013, 13:33:35 »
Hasta donde sé, el getc() es un método bloqueante (se detiene el hilo de procesamiento hasta que se recibe el caracter o se produce el timeout deseado). Por ende, no veo diferencia entre usar polling + demora, a usar un getc() con timeout.

Si no quieres utilizar demoras, siempre puedes combinarlo con un timer para evitar bloqueos.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado RodrigoAndres

  • PIC16
  • ***
  • Mensajes: 171
Re: Cambiar el TIMEOUT del RS232 en tiempo de ejecución
« Respuesta #4 en: 27 de Septiembre de 2013, 14:08:28 »
Gracias, creo que lo mejor sera hacer unas cuantas demoras con ASM. Saludos.

Desconectado vdiazg

  • PIC12
  • **
  • Mensajes: 68
Re: Cambiar el TIMEOUT del RS232 en tiempo de ejecución
« Respuesta #5 en: 27 de Septiembre de 2013, 15:26:41 »
lo que yo hago es usar el timer1 y ponerlo a desbordar cada 100ms (en tu caso debes cambiarlo) y usando un flag le indico con otro registro cuanto tiempo esperar hasta que reciba alguna respuesta, te dejo algunas partes del codigo que uso.

por ejemplo aqui envio una orden a un modem gsm y espero alguna respuesta maximo 3 seg, al recibir la respuesta me corta la temporizacion, mas no analizo si la respuesta es correcta o no, eso lo hago con otra funcion

Código: [Seleccionar]
printf("AT\r");        //Envio dato para autobaudio
esperar_respuesta(3);

y aqui esta la funcion que espera recibir al menos un dato durante un tiempo definido
Código: [Seleccionar]
//Esperar respuesta
//TIEMPO MAXIMO 25 SEGUNDOS
void esperar_respuesta(int tiempo){
flagresp=0;                //si se pone en 1 es que ya recibio algo en el usart, al inicio limpiarlo
flagtmr=1; //temporizar de comando HABILITADO, quiere decir que se va a esperar una temporizacion
tmp_cmdat=(tiempo*10); //tiempo*100ms= tiempo en seg max de espera

        //Espero que llegue algo al usart antes que llegue al tiempo maximo
while(((flagtmr==1)&&(flagresp==0)))
{
       //accion a realizar si recibio algo, de preferencia habilitar un indicador para analizarlo fuera de esta funcion
}
flagtmr=0; //temporizar de comando DESHABILITADO
}

Rutinas de interrupcion
Código: [Seleccionar]
#INT_RDA
void recepcion_rxd(){

  if(kbhit()){ // Si hay algo pendiente de recibir ...
    add_2_cbuff(getc()); // lo añado al buffer y ...
  }

}

#INT_TIMER1  //viene cada 100ms con cristal de 20Mhz
void inttimer1(){
set_timer1(3036);
if(flagtmr==1){ //Timer para esperar respuesta de un comando
tmp_cmdat--;
if(tmp_cmdat==0){
flagtmr=0;
}
}
}

Aqui esta la funcinon de recepcion, en mi caso la trama a analizar terminaba con 0x0A por eso la funcion al detectar ese caracter pone "flagresp" a UNO lo que le indica que ya se recibio el dato, en tu caso modificalo a tu criterio, la parte final de la sentencia default esta de esa forma porque usaba 2 buffer para la recepcion y luego las unia, pero ese era en mi caso particular
Código: [Seleccionar]
// Añade a cbuff -----------------------
void add_2_cbuff(char c){
  switch(c){
    case 0x0A: // Enter -> Habilita Flag para procesar comando
        cnttrama--;
        if(cnttrama==0){
            flagresp=1;}
    break;
    case 0x0D:
    break;
    case 0x3E: //simbolo ">" que es la habilitacion para escribir SMS
    break;
    default: // Añade caracter recibido al Buffer
        if (xbuff<=70){
            cbuff_0[xbuff++]=c;}
        else if ((xbuff>=71)&&(xbuff<=141)){
cbuff_1[(xbuff++)-71]=c;}
        else{
            cbuff_1[70]=c;}
      //CNTRXD++;
  }
}

revisalo, quizas te de alguna idea
quiero construir un "Condensador de flujos"

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Re: Cambiar el TIMEOUT del RS232 en tiempo de ejecución
« Respuesta #6 en: 05 de Febrero de 2014, 22:51:05 »
Hola vdiazg,  :oops: y que  sucede si no recibes nada (nigun caracter)...?

Desconectado vdiazg

  • PIC12
  • **
  • Mensajes: 68
Re: Cambiar el TIMEOUT del RS232 en tiempo de ejecución
« Respuesta #7 en: 07 de Febrero de 2014, 12:13:02 »
vamos paso a paso:
Al ingresar a la funcion esperar_respuesta(), tienes 2 flag que tiene que predefinir, estos son flagtmr y flagresp.
flagtmr:  si esta en 0 indica que ya no se esta temporizando (o que se termino el tiempo de espera), si esta en 1 indica que se inicia o se esta temporizando
flagresp:  si esta en 0 indica que no se recibio ningun dato o ningun paquete de datos, si esta en 1 indica que se recibio algun dato.

entonces al ingresar a la funcion  esperar_respuesta(), tiene que poner flagtmr en 1 y flagresp en 0, y entrara al bucle while hasta que flagtmr se ponga en 0 (termine el tiempo de espera) Ó hasta que flagresp se ponga 1 (se recibio al menos 1 dato), en cualquiera de los casos posibles:
* Termino el tiempo y no recibio datos
* Termino el tiempo y recibio datos
* recibio datos antes de terminar la temporizacion
Tienes que poner el flagtmr en 0 para que ya no temporize ya que este flag esta amarrado al tmr1 que siempre esta corriendo, y obviamente flagresp tienes que limpiarlo (y si es que se puso en 1) para poder recibir datos y te pueda avisar mas adelante

Ojala lo hayas entendido, si no sigue preguntando  ;-)
quiero construir un "Condensador de flujos"