Ejecutando dos ciclos while (1) separados paralelamente en c incrustada para 8051

-2

Recientemente, mientras escribía un programa en c incrustado para 8051 para ejecutar un robot con sensor ultrasónico, tuve un problema. Mientras que el sensor ultrasónico sigue escaneando su función está bloqueada en un momento, pero al mismo tiempo quiero mantener mi bucle infinito funcionando para otras funciones. ¿Es posible ejecutar dos bucles while (1) en paralelo? Aquí está el programa un poco largo, pero eso es lo complejo que es -

#include <reg51.h>
#include <stdio.h>
sbit GC_X = P1^2                ;    //ON grass cutting motor
sbit SP_X = P1^3                ;    //ON water pump
sbit PL_X = P1^4                ;    //Positive of ploughing
sbit PL_Y = P1^5                ;    //Negative of ploughing
sbit RM1_X = P2^0               ;    //Positive of Right Motors
sbit RM1_Y = P2^1               ;    //Negative of Right Motors
sbit LM1_X = P2^2               ;    //Positive of Left Motors
sbit LM1_Y = P2^3               ;    //Negative of Left Motors
sbit RM2_X = P2^4               ;    //Positive of Right Motors
sbit RM2_Y = P2^5               ;    //Negative of Right Motors
sbit LM2_X = P2^6               ;    //Positive of Left Motors
sbit LM2_Y = P2^7               ;    //Negative of Left Motors
sbit SW1 = P1^6                 ;    //Ploughing ON switch
sbit SW2 = P1^7                 ;    //Ploughing OFF switch
sbit US_E = P1^0                ;    //Echo pin of Ultrasonic sensor
sbit US_T= P1^1                 ;    //Trigger pin of Ultrasonic sensor

void main()
{
    TMOD=0x01                       ;
    TH0=0x00                        ;
    TL0=0x00                        ;
    P1=0X00                         ;
    P2=0x00                         ;
    P0=0x00                         ;

    while(1)                        
    {
        unsigned char R             ;
        GC_F()                      ;
        SP_F()                      ;
        RM_F()                      ;
        LM_F()                      ;
        R=get_range()               ;

        if(P0^0==0)
        {
            if(R<30) 
            {
                P0=0x01             ;
                LM_F()              ;
                delay_ms(4000)      ;  
            }                     
            else 
            {
                RM_F()              ;
                LM_F()              ;
            }
        }
        else
        {
            if(R<30) 
            {
                P0=0x00             ;
                RM_F()              ;
                delay_ms(4000)      ;  
            }                     
            else 
            {
                RM_F()              ;
                LM_F()              ;
            }
        }

        if (SW1==1)
        {
            PL_F()                  ;
            delay_ms(60)            ;
            PL_S()                  ;
        }
        else
        {
            PL_S()                  ;
        }

        if (SW2==1)
        {
            PL_B()                  ;
            delay_ms(60)            ;
            PL_S()                  ;
        }
        else
        {
            PL_S()                      ;
        }
    }
}

unsigned char get_range() 
{
    unsigned char Count,Time,Dist   ;
    trig()                          ;
    while(US_E == 0)                ;//Wait for Rising edge at Echo pin
    TR0=1                           ;//Start Timer
    TL0=TH0=0                       ;//Clear timer count register

    while(US_E == 1)                 //Wait for Falling edge at Echo pin
    {
        if(TF0 == 1)                 //timer over if no obstacle is detected
        break                       ;
    }

    TR0=0                           ;//Stop Timer.
    TF0 = 0                         ;//clear Timer Over Flow Flag
    Count = TL0 + TH0*256           ;//Calculate number of count
    Time = Count*1.085              ;//Calculate total time in uS.
    Dist = Time/58                  ;//As per datasheet of HC-SR04 Distance is in Centimeter
    return Dist                     ;
}

void trig()
{
    TH0=0x00                        ;
    TL0=0x00                        ; 
    US_T=1                          ;
    delay_us(10)                    ;                        
    US_T=0                          ;
}

void GC_F()
{
    GC_X = 1                        ;    //Make positive of Grass cutter motor
}

void SP_F()
{
    SP_X = 1                        ;    //Make positive of water pump motor
}

void PL_F()
{
    PL_X = 1                        ;    //Make positive of motor 1
    PL_Y = 0                        ;    //Make negative of motor 0
}

 void PL_B()
{
    PL_X = 0                        ;    //Make positive of motor 0
    PL_Y = 1                        ;    //Make negative of motor 1
} 

void PL_S()
{
    PL_X = 0                        ;    //Make positive of motor 0
    PL_Y = 0                        ;    //Make negative of motor 0
} 

void RM_F()
{
    RM1_X = 1                       ;    //Make positive of motor 1
    RM1_X = 0                       ;    //Make negative of motor 0
    RM2_X = 1                       ;    //Make positive of motor 1
    RM2_Y = 0                       ;    //Make negative of motor 0
}

void RM_S()
{
    RM1_X = 0                       ;    //Make positive of motor 0
    RM2_X = 0                       ;    //Make positive of motor 0
}

void LM_F()
{
    LM1_X = 1                       ;    //Make positive of motor 1
    LM1_Y = 0                       ;    //Make negative of motor 0
    LM2_X = 1                       ;    //Make positive of motor 1
    LM2_Y = 0                       ;    //Make negative of motor 0
}

void LM_S()
{
    LM1_X = 0                       ;    //Make positive of motor 0
    LM2_X = 0                       ;    //Make positive of motor 0
} 

void delay_us(unsigned int us)//This function provide delay in us uS.
{
    while(us--)                     ;
}

void delay_ms(unsigned int ms)//This function Provide delay in ms Ms.
{
    unsigned int i,j                ;
    for(i=0;i<ms;i++)
    for(j=0;j<1275;j++)             ;
}

Ahora, como puede ver, mientras que el sensor ultrasónico busca un obstáculo, espera en el estado de alerta para que el borde caiga en el pin de eco. Pero debido a esto, cuando no se detecta ningún obstáculo, permanecerá allí para siempre. Quiero que también ejecute la segunda declaración if si comprueba la polaridad de los interruptores SW1 y SW2, que se verificará continuamente con el escaneo continuo del sensor ultrasónico. Ahora, una vez que sale del ciclo (1) del sensor ultrasónico hasta el momento en que se detecta un obstáculo, no vuelve al ciclo (1). Por lo tanto, quiero ejecutar dos bucles infinitos en paralelo y, si no es posible, ¿hay alguna otra solución para ejecutar ambas funciones continuamente juntas sin que una entre en conflicto con otra?

    
pregunta devansh

4 respuestas

2

Otra alternativa es la multitarea cooperativa, donde su bucle principal llama a varias funciones en un estilo de round-robin. En este caso, uno podría sondear los sensores ultrasónicos y reaccionar ante la presencia (o no) de un obstáculo, y uno sondear los interruptores y reaccionar ante los cambios en los estados del interruptor.

Usted, como diseñador, debe garantizar que cada una de esas funciones [n] tomará menos tiempo que [t / n] (sin importar qué camino interno tomen), donde t es el tiempo máximo que cualquier función robótica puede ignorarse y el robot seguirá funcionando correctamente.

Para lograr eso, es posible que tenga que escribir una o más de esas funciones para hacer solo una parte de su trabajo en cada entrada, recordar dónde se detuvieron para abandonar el control y reanudar en ese momento la próxima vez que reciban el control.

Esto se vuelve oneroso, en el mejor de los casos, con más de unas pocas funciones, de complejidad más que mínima, pero para sistemas bastante simples puede ser viable.

    
respondido por el JRobert
1

Una técnica que parece apropiada para su aplicación es diseñar su firmware a State Machine , porque está claro que puedo dividirme en estados bien definidos y una transición clara entre sus estados. es decir, su estado parece estar en un estado de espera, luego cambia de ese estado una vez que se detecta el flanco descendente. No estoy seguro de cuán familiarizado está con las máquinas de estado, pero el artículo de enlace es un buen manual. State Machines es una forma bastante poderosa y fácil de diseñar e implementar firmware.

    
respondido por el Kvegaoro
1

Para un 8051, debe haber al menos dos pines de interrupción externa (INT0, INT1).

Tipodeinterrupciones:

  1. Interrupciónactivadapornivel,generadaporunaseñaldebajonivel

  2. Interrupciónactivadaporelborde,generadaporunaseñaldebordedescendente

Elsegundomodoesexcelenteparaelsensorultrasónico,yaqueutilizaunbordedescendenteparaindicarunobstáculo.UnavezquesedetectaelflancodescendenteenelpinINT0,elmicrocontroladorsedetieneysaltaalatabladevectoresdeinterrupciónparadarservicioaesainterrupción,parahacerloquequieracuandosedetecteunobstáculo.

Mientrastanto,elestadodelosinterruptoressepuedeverificarenelbuclewhileprincipal.Deestamanera,lastresperiferiassepuedenservircasiinmediatamente.Aquíhayunsitiowebsobre interrupciones externas de 8051 .

Pero para darte un pequeño ejemplo:

#include <REG52.H>

void ex0_isr(void) interrupt 0
{
    // falling edge detected
    // do what needs to be done
}

void main(void)
{
    IT0 = 1;   // Configure interrupt 0 for falling edge on /INT0 (P3.2)
    EX0 = 1;   // Enable INT0 Interrupt
    EA = 1;    // Enable Global Interrupt Flag

    while(1)
    {
        if (SW1 == 1)
        {
            // SW1 is high, do something
        }
        else
        {
            // SW1 is low, do something else  
        }

        if (SW2 == 1)
        {
            // SW2 is high, do something
        }
        else
        {
            // SW2 is low, do something  else 
        }
    }
}

Tenga en cuenta que no necesita if(INT0==1) , se llamará automáticamente a ex0_isr cuando se genere una interrupción.

    
respondido por el Bence Kaulics
0
  

y si no es posible, ¿hay alguna otra solución para ejecutar ambos   ¿Funcionan continuamente juntas sin que una esté en conflicto con otra?

Sí, diseño impulsado por interrupción.

En lugar de un sondeo infinito del estado de los pines, es mejor asignar a cada uno un ISR que haga el trabajo.

    
respondido por el Malek

Lea otras preguntas en las etiquetas