Estoy haciendo un programa para el msp430 usando energia launchpad, el primer código que tuve es 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 se deja de presionar el botón, el problema es que a veces (cuando no se presiona el botón y el programa todavía está en el primer retraso) el número 5 en el segundo dígito permanece presente, así que usé 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 excesivo de banderas en su programa es una mala práctica de programación y mi solución no parece elegante ni eficiente, ya que la línea:
flag_delay = false;
Se seguirá procesando cada vez que se encienda la pantalla, y la función clean_leds() se seguirá procesando hasta que termine el código retrasado. ¿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);
}
Todavía no he trabajado con este procesador, pero estoy 100% seguro de que hay alguna forma de rastrear los estados de transición del botón pulsador
es decir, un_button_pressed(low) -> pressed_button (high) transición y viceversa
Si no desea utilizar la bandera, debe verificar la
pressed_button( high ) -> un_pressed_button( low ) transición en el pulsador
el código sudo sería como,
if(current_state_of_button == LOW && previous_state_of_button == HIGH)
{
clean_leds();
}
tendrá que realizar un seguimiento de los estados con dos variables. O configure dos ISRS que se activen en las dos transiciones posibles. Espero que esto ayude
Aquí hay un código 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();
}
Hay una serie de problemas en su código original y creo que es 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();
}
La ISR (rutina de servicio de interrupción) interrumpirá literalmente cualquier código existente a menos que se hayan deshabilitado las interrupciones (como lo explica 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 renderizar '45' en el bucle principal, también debería borrarlo en el bucle principal. Esto reduce la posibilidad de condiciones de carrera y comportamiento no deseado.
Alternativamente, puede limpiar_leds () y dibujar el '45' en el ISR, pero dado que el dibujo está usando retrasos y puede llevar algún tiempo, no lo recomendaría.
broma
rui lima
broma
rui lima