Autor Tema: Problemas con interrupcion usart con 18f4550  (Leído 2644 veces)

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

Desconectado murphy9

  • PIC10
  • *
  • Mensajes: 21
Problemas con interrupcion usart con 18f4550
« en: 22 de Octubre de 2012, 10:34:46 »
Hola a todos. Tengo que realizar una comunicación usart entre dos pics 18f. Mientras el emisor envía valores numéricos, el receptor los almacena, muestra y demás. Mi problema radica en que deseo que el receptor le envíe al emisor un código que habilite a este ultimo a enviar la información. Para ello he hecho los siguientes programas y lamentablemente no se realiza la comunicación. Sospecho que el problema está en que al usar interrupciones de recepción el receptor nunca ejecuta la función putc(15), y no tengo idea de por que ocurre esto. Alguien puede ayudarme? Agrego los códigos a continuación:

Transmisor:
#include <18F2550.h>

#fuses XTPLL,USBDIV,PLL1,PUT,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG
#use delay(clock=48000000)

#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,parity=n)

#byte porta=getenv("SFR:PORTA")
#byte portc=getenv("SFR:PORTC")
#byte portb=getenv("SFR:PORTB")

int val,valor;


#int_RDA
void RDA_isr()
{
   delay_ms(250);
   val=GETC();
   
   if (val==15){
                  output_toggle(pin_a0);
                  PUTC(valor);
                  portb=(valor&0x0f);
                  delay_ms(100);
                  valor++;
               }
}

void main()
{
   portb=porta=portc=0;
   set_tris_a(0b11111110);
   set_tris_b(0xf0);
 //  set_tris_c(0b10111111);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

while(true)
   {
   }
}


Receptor:
#include <18F4550.h>

#fuses XTPLL,USBDIV,PLL1,PUT,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG
#use delay(clock=48000000)
#include <lcdpf.c>
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,parity=n)

#byte porta=getenv("SFR:PORTA")
#byte portb=getenv("SFR:PORTB")
#byte portc=getenv("SFR:PORTC")


int8 val;

#int_RDA
void RDA_isr()
{
 val=GETC();
 output_toggle(pin_a0);
}

void main()
{  int i;
   lcd_init();
   porta=portc=portb=0;
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
 
   set_tris_b(0x00);
   set_tris_c(0b10000000);
   set_tris_a(0xfe);
//   set_tris_d(0xff);
   
   WHILE(TRUE)
   { 
                   lcd_gotoxy(1,1);
                   printf(lcd_putc,"usart=%3u     ",val);
                   putc(15);
                   
   }
}

Desde ya agradezco su respuesta

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 439
    • Mcu Tronics
Re: Problemas con interrupcion usart con 18f4550
« Respuesta #1 en: 24 de Octubre de 2012, 11:09:49 »
Pues no se pero a mi me dio algo de problemas la interrupcion del RS232, use kbhit() en el while infinito,se que es mejor la interrupcion pero bueno...

Otra,eso de los delays dentro de las interrupciones no es buena idea,creo que ahi puedes colocar una variable bandera solamente,ejemplo la llamas recepcion

Código: [Seleccionar]
#INT_RDA
void rcepcion(void)
{
      recepcion=1;
}

Y en tu main lo que haces es checar esa bandera

Código: [Seleccionar]
void main(void)
{
.
.
.
.   
    while(TRUE)
    {
           if(recepcion==1)
          {
               .
               .
               .
               recepcion=0;
          }
     }
}

No olvides inicializar tu variable bandera y borrarla despues de que hagas todo lo que quieras (donde puse puntos).

Y por ultimo me queda duda con los dos primeros bits de configuracion que usas en la directiva #fuses.... yo pondria HS y quitaria el USBDIV....
« Última modificación: 24 de Octubre de 2012, 11:13:03 por thegame »
Nunca se deja de aprender

Desconectado richi78x

  • PIC10
  • *
  • Mensajes: 1
Re: Problemas con interrupcion usart con 18f4550
« Respuesta #2 en: 24 de Octubre de 2012, 18:12:34 »
Que tal!! Ya solucionaste tu problema con la comunicación serial??

Efectivamente como menciona thegame, las interrupciones son mejores que el método de poleo con el KBHit(), la cuestión que yo veo es que usas GETC(), y dicha función solo recoge UN caracter solamente, así que si le envías el 15, estará retornando solo el 1, por tanto la variable nunca será igual a 15. Si no vas a usar el valor para operaciones aritméticas, puedes reemplazarlo por una letra 'a', 'b', etc.. que es más fácil... por otro lado si requieres leer mas de dos caracteres, utiliza la función GETS() la cual recoge una cadena de caracteres.
Tampoco me queda claro el porque usas el Delay(), si es para esperar llenar el búfer es mucho lo que espera considerando que solo recibe 2 caracteres, recuerda que al usar interrupciones el micro deja de hacer lo que estaba haciendo para atender a esta, así que entre menos tiempo tarde es mucho mejor.

Por lo demás no le veo ningún inconveniente a la comunicación serial, es fácil implementarla... no revise tus configuraciones pero supongo que estan correctas y no es por ahí el problema.

Saludos cordiales.

RichardMX

Desconectado murphy9

  • PIC10
  • *
  • Mensajes: 21
Re: Problemas con interrupcion usart con 18f4550
« Respuesta #3 en: 25 de Octubre de 2012, 10:21:10 »
Hola, primero quiero agradecer sus respuestas thegame y richi78x. Les comento, los fuses están configurados asi porque aparte de esta comunicación serie hay una comunicación usb. A los delay los puse ahi para que la transmisión de datos no fuera tan rapida y pudiera ver el cambio en el estado de un led cuando esta tuviera lugar, es decir que no es para nada fundamental y puedo eliminarla sin problemas. Siguiendo tu consejo richi78x, cambié la instrucción en el modulo receptor y emisor de forma que la variable de control no fuera 15 sino 1, y conseguí que se llevará a cabo la comunicación, pero solo cinco veces, una vez que el lcd del receptor muestra 5, el emisor no envia ningun dato mas. Tienes alguna idea de por que? ya probé utilizando las funciones fgetc(1), getc(1), getchar('1'), getchar(1)

Desconectado murphy9

  • PIC10
  • *
  • Mensajes: 21
Re: Problemas con interrupcion usart con 18f4550
« Respuesta #4 en: 02 de Noviembre de 2012, 09:45:07 »
Hola a todos nuevamente. Les comento, hice unas muy pequeñas modificaciones a los firmwares y finalmente pude realizar la comunicaciones en la forma en que lo deseaba. Los respectivos programas quedaron como se muestran a continuación:

Transmisor:

#include <18F2550.h>

#fuses XTPLL,USBDIV,PLL1,PUT,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG  // FUSES PARA USAR USB
#use delay(clock=48000000)
#include <lcdpf.c>
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#byte porta=getenv("SFR:PORTA")
#byte portc=getenv("SFR:PORTC")
#byte portb=getenv("SFR:PORTB")

int VALOR;
int val,val1;

#int_RDA
void RDA_isr()
{
   val=GETC();
   if (val==1){
                  output_toggle(pin_a0);
                  PUTC(valor);
                  portb=(valor&0x0f);
                  valor++;
               }
}


void main()
{
   int valor=0;
   portb=porta=portc=0;
   set_tris_a(0b11111110);
   set_tris_b(0xf0);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RDA);

while(true)
    {
    }
}

Receptor:

#include <18F4550.h>

#fuses XTPLL,USBDIV,PLL1,PUT,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG  // FUSES PARA USAR USB
#use delay(clock=48000000)
#include <lcdpf.c>
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8,parity=n)
#byte porta=getenv("SFR:PORTA")
#byte portb=getenv("SFR:PORTB")
#byte portc=getenv("SFR:PORTC")
#byte portd=getenv("SFR:PORTD")
#byte porte=getenv("SFR:PORTE")

int8 val;

#int_RDA
void RDA_isr()
{
   val=GETC();
}

void main()
{  int i;
   lcd_init();
   porta=portc=portb=0;
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
 
   set_tris_b(0x00);
   set_tris_c(0xff);
   set_tris_a(0xff);
   set_tris_e(0x00);
   
   WHILE(TRUE){
                   putc(1);
                   lcd_gotoxy(1,1);
                   printf(lcd_putc,"usart=%3u     ",val);
                   lcd_gotoxy(1,2);
                   printf(lcd_putc,"usart=%3u     ",val);
                   lcd_gotoxy(1,3);
                   printf(lcd_putc,"usart=%3u     ",val);
                   portb=val;   
                   delay_ms(200);
                   output_toggle(pin_e0);
               
         
   }
}

Agradezco nuevamente sus ayudas richi78x y thegame




 

anything