Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

30/05/2014 #1


Comunicación serial entre 2 micros PIC
Hola !

Estoy haciendo un driver para un motor a pasos unipolar. Uso 2 micros, uno emulando al PLC (ahi le dices que velocidad quieres, tipo, direccion y cantidad de pasos. El otro recibe los datos y hace la secuencia de giro del motor.
Tengo el problema de que... no pasa nada. El primer micro funciona perfecto, envia los datos bien y muestra todo en la pantalla LCD. Estoy seguro de que el error esta en la llegada de los datos al segundo micro. Lo sé porque puse un if con para el valor que envio, y PORTB deberia cambiar de estado pero no lo hace. Sé que si cambia entre bucles while, porque ya habia puesto un 'PORTB=0xXX' entre ellos y lo hacia.
No se como hacerlo correctamente, ya que he intentado muchas formas distintas.

La cantidad de pasos la envio al primer micro mediante serial con la computadora.

RA1 de ambos micros están unidos y van a un push.

Uso dos PIC18f4550 y compilador mikroc. Adjunto los códigos.

CODIGO TRANSMISOR (uC 1)
Código:
while(1)
{
i=0;

        Lcd_Cmd(_LCD_CLEAR);
        Lcd_Out(1,1,"Driver Stepper");
        Delay_ms(3000);
        Lcd_Cmd(_LCD_CLEAR);

        while((PORTA.RA1)==0)                        //Velocidad
        {
                if((PORTE.RE0)==1)
                {vel++; Delay_ms(500); Lcd_Cmd(_LCD_CLEAR);}
                if((PORTE.RE1)==1)
                {vel--; Delay_ms(500); Lcd_Cmd(_LCD_CLEAR);}

                memset(Vel1, \'\\0\', 10);
                sprintf(Vel1,"%d",vel);
                strcpy(Vel2,Vel1);

                Lcd_Out(1,4,"Velocidad:");
                Lcd_Out(2,5,Vel2);
                Lcd_Out(2,7," p/seg");
        }
        UART1_Write(vel);
        Delay_ms(500);
        Lcd_Cmd(_LCD_CLEAR);
        //UART1_Write(0xFF);

        while((PORTA.RA1)==0)                        //Direccion
        {
                if((PORTE.RE2)==1)
                {
                switch(dir)
                {
                case 1: dir=0; break;
                case 0: dir=1; break;
                }
                Delay_ms(500);
                Lcd_Cmd(_LCD_CLEAR);
                }
                sprintf(Dir1,"%d",dir);
                memset(Dir2, \'\\0\', 10);

                if(dir==1){strcpy(Dir2,"Reloj");}
                if(dir==0){strcpy(Dir2,"Contra");}

                Lcd_Out(1,4,"Direccion:");
                Lcd_Out(2,5,Dir2);
        }
        UART1_Write(dir);
        Delay_ms(500);
        Lcd_Cmd(_LCD_CLEAR);
        //UART1_Write(0xFF);

        while((PORTA.RA1)==0)                        //Tipo de paso
        {
                if((PORTA.RA2)==1)
                {
                tipo+=1;
                if(tipo>3){tipo=1;}
                memset(T,\'\\0\',10);
                sprintf(T,"%d",tipo);
                strcpy(Tipo1,T);
                              switch(tipo)
                              {
                              case 1: strcpy(NMW,"Normal");break;
                              case 2: strcpy(NMW,"Medio");break;
                              case 3: strcpy(NMW,"Wave");break;
                              }
                Delay_ms(500);
                Lcd_Cmd(_LCD_CLEAR);
                }
                Lcd_Out(1,1," Tipo de paso:  ");
                Lcd_Out(2,5,NMW);
        }
        UART1_Write(tipo);
        Delay_ms(500);
        Lcd_Cmd(_LCD_CLEAR);
        //UART1_Write(0xFF);

        while((PORTA.RA1)==0)                        //Cantidad de pasos
        {
                if (UART1_Data_Ready())                         // If data is received,
                {
                   UART1_Read_Text(&uart_rd, "OK", 255);    // reads text until \'OK\' is found
                   strcpy(tum,&uart_rd);
                   paaso=atoi(tum);
                   Lcd_Cmd(_LCD_CLEAR);
                }

                Lcd_Out(1,1,"     Pasos:     ");
                Lcd_Out(2,7,tum);
        }
        UART1_Write(paaso);
        Delay_ms(500);
        Lcd_Cmd(_LCD_CLEAR);
        //UART1_Write(0xFF);

        while((PORTA.RA1)==0)
        {
                Lcd_Out(1,1,"Al finalizar");
                Lcd_Out(2,1,"Presiona RA1");
        }
  }

CODIGO RECEPTOR (uC 2)
Código:
while(1)
{
Delay_ms(500);

while((PORTA.RA1)==0)                         //Recibe Velocidad
        {
              if (UART1_Data_Ready())                      // If data is received,
              {
              recibe=UART1_Read();  // reads UART
              vel=recibe;
              }
        }
        recibe=0;
        Delay_ms(500);
        if(vel==2){PORTB=0x90;}
        
while((PORTA.RA1)==0)                         //Recibe direccion
        {
              if (UART1_Data_Ready())                      // If data is received,
              {
              recibe=UART1_Read();  // reads UART
              dir=recibe;
              }
        }
        recibe=0;
        Delay_ms(500);
        if(dir==1){PORTB=0x60;}
        
while((PORTA.RA1)==0)                                 //Recibe tipo de paso
        {
              if (UART1_Data_Ready())                      // If data is received,
              {
              recibe=UART1_Read();  // reads UART
              T=recibe;
              }
        }
        recibe=0;
        Delay_ms(500);
        if(T==3){PORTB=0x30;}

while((PORTA.RA1)==0)                                //Recibe pasos
        {
              if (UART1_Data_Ready())                      // If data is received,
              {
              recibe=UART1_Read();  // reads UART
              pasos=recibe;
              }
        }
        recibe=0;
        flg2=0;
        Delay_ms(500);
        if(pasos==40){PORTB=0x90;}
...
30/05/2014 #2

Avatar de TRILO-BYTE

es que no debes poner retardos
es decir atoras el micro todos unos 500ms es decir medio segundo desperdiciado

entonces cuando recivas el dato pues ¿cuando lo recibira pues se atora?

yo diria que quitaras esos delays

y si pudireas poner el uart por interrupcion es decir cuando llegue un dato que interrumpa el micro lo prosece y continue con lo que estaba haciendo
30/05/2014 #3


Gracias por responder

Puse los retardos por el rebote del push, y porque si se dejara presionado mucho tiempo, saltaria los otros while debido a que uso el mismo push para salir de cada uno. Hay otra forma de evitar eso?

En cuanto a las interrupciones, nunca las he usado. Investigare un poco para aplicarlas y ver como me va.
30/05/2014 #4

Avatar de Nuyel

Aparte de enviar los datos completos en una cadena específica para que los proceses todos juntos y además, la variable "recibe" en tú código es innecesaria, en lugar de enviar a recibe y borrarlo a cada momento mejor transfiere directamente a tus variables (vel, dir, T y paso)
30/05/2014 #5


Nuyel dijo: Ver Mensaje
Aparte de enviar los datos completos en una cadena específica para que los proceses todos juntos...
Puedes por favor explicarme un poco sobre eso?
30/05/2014 #6

Avatar de Nuyel

Me refiero a que envíes los datos uno tras el otro, así evitas esa espera enorme e innecesaria, si lo haces por interrupciones usas un contador y esperas los bytes necesarios que mandan la información, ya cuando recibes todos los procesas juntos en lugar para que las instrucciones se ejecuten rápidamente en lugar de tardar se 1,5s en recibir los 3 datos.
30/05/2014 #7


Agradecería mucho un pequeño ejemplo :S
Estoy dándome de topes con esto.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.