Ayuda a entender el código

1

Soy nuevo en la programación C Necesito su ayuda para comprender algunas líneas en particular en un segmento de código para el control sensorial de un motor dc sin escobillas. Fue escrito para una MCU de 16 bits (dsPIC33FJ32MC710). Esta sección en particular es de la rutina de servicio de interrupción y contiene dos ISR. ¿Me puede explicar en palabras sencillas, las líneas marcadas con //??? ? ¿Qué se está haciendo allí, y por qué? Cualquier otro comentario también es bienvenido.

int DesiredSpeed;
int ActualSpeed;
int SpeedError;
long SpeedIntegral = 0, SpeedIntegral_n_1 = 0, SpeedProportional = 0;
long DutyCycle = 0;
unsigned int Kps = 20000;                   // Proportional gain
unsigned int Kis = 2000;                    // Integral gain

void __attribute__((interrupt, no_auto_psv)) _T1Interrupt (void)
{
#ifdef CLOSEDLOOP
    ActualSpeed = SPEEDMULT/timer3avg;
    SpeedError = DesiredSpeed - ActualSpeed;
    SpeedProportional = (int)(((long)Kps*(long)SpeedError) >> 15);                 // ???
    SpeedIntegral = SpeedIntegral_n_1 + (int)(((long)Kis*(long)SpeedError) >> 15);   //???      
    SpeedIntegral_n_1 = SpeedIntegral;
    DutyCycle = SpeedIntegral + SpeedProportional;
    PDC1 = (int)(((long)(PTPER*2)*(long)DutyCycle) >> 15);  // ???  PWM duty cycle 
    1PDC2 = PDC1;
    PDC3 = PDC1;
#endif                              // in closed loop algorithm

    IFS0bits.T1IF = 0;
}

void __attribute__((interrupt, no_auto_psv)) _IC1Interrupt (void)
{
    int Hall_Index;

    IFS0bits.IC1IF = 0; // Clear interrupt flag
    HallValue = (unsigned int)((PORTB >> 1) & 0x0007);  // Read halls

    if (Flags.Direction)
    {
        OVDCON = StateTableFwd[HallValue];
        Hall_Index = HALL_INDEX_F;
        }
    else
    {
        OVDCON = StateTableRev[HallValue];
        Hall_Index = HALL_INDEX_R;
        }

// The code below is uses TMR3 to calculate the speed of the rotor
    if (HallValue == Hall_Index)  // has the same position been sensed?
        if (polecount++ == POLEPAIRS)  //has one mech rev elasped?         // ???
        {                               // yes then read timer 3
        timer3value = TMR3;
        TMR3 = 0;
        timer3avg = ((timer3avg + timer3value) >> 1);    // ???
        polecount = 1;
        } 
}
    
pregunta Adeel

3 respuestas

3

Para realizar operaciones matemáticas de enteros fraccionarios en C (y otros idiomas que no admiten matemáticas fraccionales), es necesario realizar trucos como este. Lo que realmente le gustaría hacer es multiplicar dos números de 16 bits y mantener los bits altos del producto.

El primer conjunto de expresiones convierte números de 16 bits en números de 32 bits firmados, luego calcula el producto de 32 bits. Luego lo desplazan a la derecha en 15 bits, descartando los bits menos significativos. Es un poco como lo que ocurre con las matemáticas de coma flotante cuando se multiplican dos mantisas (aunque la matemática de coma flotante se haría de manera más eficiente ya que no hay necesidad de calcular lo que se descartará).

En la segunda expresión (polecount ++ == POLEPAIRS) tiene un valor booleano basado en la comparación del valor de la variable polecount con POLEPAIRS. La variable polecount es post-incrementada (incrementada después de la comparación).

    
respondido por el Spehro Pefhany
1

Estas líneas representan la parte proporcional e integral del control del motor.

El SpeedError se multiplica por la ganancia de Kps directamente y la ganancia de Kis multiplica el SpeedError y lo agrega a los ciclos de salida integral SpeedIntegral_n_1.

Debería haber algunas líneas de código más adelante que sumen los términos proporcionales e integrales para determinar la entrada del motor.

Este método de control está intentando asegurar que el control de velocidad del motor sea estable y no oscile. El ajuste de las ganancias proporcionales e integrales afectará la velocidad y la estabilidad del control del motor.

    
respondido por el Neomada
1

El > > El operador es un cambio a la derecha a nivel de bits. Al desplazar todos los bits hacia la izquierda o hacia la derecha dentro de un número binario, se multiplicará o dividirá el número por 2 (por cada turno). También puede haber ocasiones en las que desee cambiar ciertos bits a ciertas posiciones, posiblemente para alinear los bits en un puerto de E / S o los bits dentro de un registro de datos interno especial.

Además, en algunas de estas fórmulas, una o más de las variables se están convirtiendo en un determinado tipo de datos (usando un prefijo como (int) o (largo) justo delante del número).

Para operador de cambio de bit Ver: enlace

    
respondido por el Nedd

Lea otras preguntas en las etiquetas