Buenas prácticas de bandera - energia msp430

1

Estoy haciendo un programa para el msp430 usando el launchpad de energia, el primer código que tuve fue el siguiente:

// display flag
boolean flag_display = false;

void setup() {
  // define ISR to activate the display
  attachInterrupt(PUSH2, display_ISR, CHANGE);
}

void display_ISR() {
  clean_leds();
  flag_display = !flag_display;
}

void loop() {
  if(flag_display == true) {

    // prints the number 45 on the display
    pick_digit(1);
    pick_number(4);
    delay(8);
    pick_digit(2);
    pick_number(5);
    delay(8);

  }
}

Básicamente, el programa presenta el número 45 en la pantalla cada vez que se presiona el botón PUSH2 y limpia la pantalla cada vez que no se presiona el botón, el problema es que algunas veces (cuando el botón no se presiona y el programa está aún en el primer retraso) el número 5 en el segundo dígito permanece presente, así que utilicé lo siguiente para evitar este problema:

// display flag
boolean flag_display = false;

// delay flag from the display
boolean flag_delay = true;

void setup() {
  // define ISR to activate the display
  attachInterrupt(PUSH2, display_ISR, CHANGE);
}

void display_ISR() {
  flag_display = !flag_display;
}

void loop() {
  if(flag_display == true) {

    // prints the number 45 on the display
    pick_digit(1);
    pick_number(4);
    delay(8);
    pick_digit(2);
    pick_number(5);
    delay(8);

    // if the code runs till the end, un-flag the delay flag
    flag_delay = false;

  }

  // Keeps cleaning the leds until the delayed code is over processing
  if(flag_display == false && flag_delay == false) {
    clean_leds();
    flag_delay = !flag_delay;
  }
}

Pero leí que el uso de indicadores en su programa es una mala práctica de programación y mi solución no parece elegante ni eficiente desde el punto de vista de la línea:

flag_delay = false;

Se seguirá procesando cada vez que la pantalla esté encendida, y la función clean_leds () se seguirá procesando hasta que el código retrasado haya terminado. ¿Hay una forma más eficiente de usar los ISR y las banderas en este caso particular? Gracias.

La función clean_leds () tiene lo siguiente:

void clean_leds()
{
  digitalWrite(P1_7, LOW);
  digitalWrite(P1_6, LOW);
  digitalWrite(P2_5, LOW);
  digitalWrite(P2_4, LOW);
  digitalWrite(P2_3, LOW);
  digitalWrite(P2_2, LOW);
  digitalWrite(P2_1, LOW);
}
    
pregunta Rui Lima

3 respuestas

2

No he trabajado con este procesador todavía, pero estoy 100% seguro de que hay alguna forma de rastrear el botón de transición estados

es decir, un_pressed_button (bajo) - > pulsado_botón (alto) transición y viceversa

Si no desea utilizar el indicador, debe comprobar el

Press_button ( alto ) - > un_pressed_button ( low ) transición en el botón pulsador

el código sudo sería como,

if(current_state_of_button == LOW && previous_state_of_button == HIGH)
{
    clean_leds();
}

tendrás que hacer un seguimiento de los estados con dos variables. O configure dos ISRS que activen las dos transiciones posibles. Espero que esto ayude

    
respondido por el Dexobox
1

Aquí hay un código de psudo para lo que estoy tratando de explicar

bool prev_state
bool current state

setup{
//attach ISR 
}
ISR1.subroutine{
cli();   //disable interrupts
//Print your digits to LCD
sei();   //enable interrupts
}


loop{

 if(prev_state == HIGH && current_state == LOW)
 {
    //if this routine takes time also you might want to disable the interrupts here too
clead_leds();
 }
    
respondido por el Dexobox
1

Hay un número de problemas en su código original y creo que hay un malentendido de los ISR.

Su código original se puede arreglar eliminando clean_leds () del ISR y moviéndolo a la rutina de bucle. No hay necesidad de flag_delay en absoluto.

if(flag_display == true) 
{
   // prints the number 45 on the display
   pick_digit(1);
   pick_number(4);
   delay(8);
   pick_digit(2);
   pick_number(5);
   delay(8);
}
else
{
   clean_leds();
}

El ISR (rutina de servicio de interrupción) literalmente interrumpirá cualquier código existente a menos que las interrupciones hayan sido desactivadas (como se explica en Dexobox).

Esto significa que clean_leds () puede ejecutarse después de que se muestre el número 4 pero antes del número 5 dejando solo '5' en la pantalla en lugar de '45'. Como regla general, si va a representar '45' en el bucle principal, entonces también debería estar eliminándolo en el bucle principal. Esto reduce la posibilidad de condiciones de carrera y comportamiento involuntario.

Alternativamente, puede clean_leds () y dibujar el '45' en el ISR, pero dado que el dibujo está usando retrasos y puede llevar algo de tiempo, no lo recomendaría.

    
respondido por el Lummo

Lea otras preguntas en las etiquetas