Autor Tema: pic18f97j60 y el puerto serie  (Leído 2948 veces)

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

Desconectado Maria33

  • PIC12
  • **
  • Mensajes: 54
pic18f97j60 y el puerto serie
« en: 07 de Noviembre de 2008, 17:36:21 »
Hola, estoy realizando un pequeño programa en mplab con el compilador c18. El codigo tiene que recibir cuatro caracteres por el puerto serie y hacer un eco. El codigo que se ejecuta cuando se reciben datos por el puerto serie es el siguiente:
#pragma interrupt Low_Int_Handler
void Low_Int_Handler(void)
{

   if(PIR1bits.RCIF)   //Se comprueba si la interr ha sido por recepción
   {   PORTJ = 0X02;
      Delay10KTCYx(retraso1s);
      Delay10KTCYx(retraso1s);
      tempx = ReadUSART();      //lee un caracter de la usart
      WriteUSART((char)tempx);   //escribe el caracter
      esperaTx();
      tempx = ReadUSART();      //lee un caracter de la usart
      WriteUSART((char)tempx);   //escribe el caracter
      esperaTx();
      tempx = ReadUSART();      //lee un caracter de la usart
      WriteUSART((char)tempx);   //escribe el caracter
      esperaTx();
      tempx = ReadUSART();      //lee un caracter de la usart
      WriteUSART((char)tempx);   //escribe el caracter
      esperaTx();
      PIR1bits.RCIF = 0;

   }
}   

Pero ocurre un error y es que si por ejemplo por el puerto serie se recibe la cadena hola, el pic no vuelve a enviar hola en el eco sino que envia hooo.
Alguien sabe que podria estar pasando.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: pic18f97j60 y el puerto serie
« Respuesta #1 en: 07 de Noviembre de 2008, 17:55:29 »
Hola.

La interrupcion se da cuando el pic recibe el bit de start,  lo recomendable es que solo guardes el byte correspondiente en un buffer y salgas de la interrupcion, una vez hallas recibido todo el string completo harias el eco, esto se haria mejor en el programa principal.

Código: C++
  1. #pragma interrupt Low_Int_Handler
  2. void Low_Int_Handler(void)
  3. {
  4.    if(PIR1bits.RCIF)   //Se comprueba si la interr ha sido por recepción
  5.    {
  6.       tempx [i++]= ReadUSART();      //lee un caracter de la usart
  7.       PIR1bits.RCIF = 0;
  8.    }
  9. }

Me explico: si vas a recibir "hola" el PIC entrara en la interrupcion de la USART 4 veces y en cada una guardara el byte correspondiente.

Saludos
El papel lo aguanta todo

Desconectado Maria33

  • PIC12
  • **
  • Mensajes: 54
Re: pic18f97j60 y el puerto serie
« Respuesta #2 en: 07 de Noviembre de 2008, 18:09:40 »
Muchas gracias, voy a probarlo, pero ¿ como envio luego el buffer tempx?

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: pic18f97j60 y el puerto serie
« Respuesta #3 en: 07 de Noviembre de 2008, 18:57:55 »
Hola.

Lo envias con un printf("%s", tempx);

Saludos
El papel lo aguanta todo

Desconectado Maria33

  • PIC12
  • **
  • Mensajes: 54
Re: pic18f97j60 y el puerto serie
« Respuesta #4 en: 07 de Noviembre de 2008, 19:14:24 »
Hola de nuevo,


Esque estoy un poco verde en este tema y no me aclaro mucho.
¿cada vez que salte la interrupcion sera porque llega un caracter nuevo?
¿entonces si yo envio la cadena "hola" pasará 4 veces por la interrupcion?

Esque si es asi, a mi no me funciona ya que solamente pasa dos veces.

¿sabes lo que podría ser?

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: pic18f97j60 y el puerto serie
« Respuesta #5 en: 08 de Noviembre de 2008, 00:50:06 »
Hola.
¿cada vez que salte la interrupcion sera porque llega un caracter nuevo?

Si, asi es.
El buffer donde guarda el PIC la informacion es de 8bits, la interrupcion del micro salta cuando detecta el bit de start (cuando se envia desde PC) del primer byte del string "hola".

Esque si es asi, a mi no me funciona ya que solamente pasa dos veces.

El codigo que tu tienes no es el mas adecuado ya que al enviar el ASCII h salta la interrupcion y se guarda, pero despues estas enviadando algo por el serial y haces una espera, en ese tiempo pueden estar llegando mas bytes desde el PC al PIC, informacion que estas perdiendo y que satura el buffer de recepcion del microcontrolador. Que pase dos veces con tu codigo no significa que entre dos veces en la interrupcion, de hecho solo entra una vez.

Para que sea mas claro, has debugg con el proteus y coloca un breakpoint en la parte de la interrupcion y checa como entra a la interrupcion con cada byte.

Saludos
El papel lo aguanta todo

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: pic18f97j60 y el puerto serie
« Respuesta #6 en: 08 de Noviembre de 2008, 08:11:14 »
Para recibir por interrupcion, la rutina debe hacer lo siguiente:
  • Entra en la interrupcion
  • Lee el caracter que recepciona, trasladandolo a un byte de un Buffer preparado a tal fin
  • Limpia la bandera de recepcion de la USART
  • Sale de la interrupcion volviendo a habilitarla
  • La interrupcion volvera a repetirse por cada caracter enviado
  • Cuando se recibe el caracter de fin de transmicion, en el buffer estara el contenido del string transmitido
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: pic18f97j60 y el puerto serie
« Respuesta #7 en: 08 de Noviembre de 2008, 11:54:59 »
Hola.

Seria bueno que coloques todo el codigo para evitar confusiones, ya que la idea -tal como lo dice MGLSOFT- es tener un byte de finalizacion de trama, puede ser el ascii \r o \n, de esta manera el envio seria: 'h', 'o', 'l', 'a', \r.

Código: C (Mac)
  1. #pragma interrupt Low_Int_Handlervoid Low_Int_Handler(void){  
  2.  if(PIR1bits.RCIF)   //Se comprueba si la interr ha sido por recepción  
  3.   {       tempx [i++]= ReadUSART();      //lee un caracter de la usart
  4.            if(tempx[i]=='\r')
  5.              data_ok=1      
  6.            PIR1bits.RCIF = 0;  
  7.    }
  8. }

y ya en el main se controla el envio con el flag data_ok

Código: C (Mac)
  1. void main (void)
  2. {
  3.    .....
  4.    while(1)
  5.    {
  6.      if(data_ok)
  7.      {
  8.         data_ok=0;
  9.         printf("%s", tempx);
  10.       }
  11.    }
  12. }

Saludos
El papel lo aguanta todo

Desconectado Maria33

  • PIC12
  • **
  • Mensajes: 54
Re: pic18f97j60 y el puerto serie
« Respuesta #8 en: 08 de Noviembre de 2008, 12:22:52 »
Muchas gracias por vuestras explicaciones. Voy a probarlo ahora mismo a ver que sucede

Desconectado Maria33

  • PIC12
  • **
  • Mensajes: 54
Re: pic18f97j60 y el puerto serie
« Respuesta #9 en: 08 de Noviembre de 2008, 17:59:33 »
Hola de nuevo, he probado los ejemplos y sigo teniendo el mismo problema. Solo puedo enviar dos bytes a la vez ya que si envio mas unicamente se reciben los dos primeros.¿Alguien sabe cual es el tamaño del buffer de recepción de la usar?

Desconectado Maria33

  • PIC12
  • **
  • Mensajes: 54
Re: pic18f97j60 y el puerto serie
« Respuesta #10 en: 08 de Noviembre de 2008, 20:05:26 »
¿puede ser que se produzca desbordamiento del buffer con mas de 16 bits?
parece muy poco ¿no?

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: pic18f97j60 y el puerto serie
« Respuesta #11 en: 08 de Noviembre de 2008, 20:29:48 »
Es muy probable que tu codigo no borre el byte de la USART una vez que lo tomas y lo guardas.
Si ese byte no se borra no hay forma que entre otro alli.
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Maria33

  • PIC12
  • **
  • Mensajes: 54
Re: pic18f97j60 y el puerto serie
« Respuesta #12 en: 08 de Noviembre de 2008, 20:52:55 »
¿como hago para borrar el byte de la USART?
¿No vale con leerlo?
Lo que me parece raro es que pueda leer dos y no mas

Desconectado MGLSOFT

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: pic18f97j60 y el puerto serie
« Respuesta #13 en: 08 de Noviembre de 2008, 21:15:44 »
Tendrias que leer la hoja de datos del PIC en cuestion, normalmente en el modulo USART encontraras cual es la forma de leer y dejar libre para la proxima interrupcion.
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.