¿Qué está causando que el programa LED de mi microcontrolador deje de funcionar?

11

Entonces, soy un principiante COMPLETO y absoluto en programación. He hecho algunas cosas básicas en Arduinos (literalmente encender LED y mostrar algo en una pantalla LCD) y estoy tratando de aprender por mí mismo cómo programar en C. Soy un ingeniero de hardware de oficio, pero me molesta que no pueda haga cualquier parte del firmware / software y no hay cursos nocturnos para enseñarlo, y me gustaría ampliar mis opciones de carrera. Me cuesta entender cómo algunos de estos comandos se juntan y se han topado con un problema que simplemente no puedo entender por qué no funciona.

Por lo tanto, tengo una entrada y una salida. Mi salida es alternar la puerta de un FET que enciende un LED. La entrada proviene de una puerta AND. Entonces, mi LED está siempre encendido, y cuando recibo una señal de entrada de la puerta AND (se han cumplido 2 condiciones) quiero que la salida (interruptor de LED) vaya hacia BAJA (apague el LED. Como la salida también está conectada a Una de las entradas AND, esto también hará que la señal de entrada sea BAJA.

Lo que quiero hacer: solo quiero leer la entrada como "condiciones cumplidas" y apagar el LED. Debería estar apagado durante 1 segundo y volver a encenderlo. Si la entrada se vuelve ALTA otra vez, el proceso se repite. Estoy usando un simple impulso para hacer el cambio como la otra entrada de la compuerta AND y he medido que la salida (entrada de MCU) se eleva cuando se presiona el botón, pero el interruptor de LED (salida) no se apagará. Mi código es (creo) bastante simple, pero claramente no entiendo algo correctamente, ya que simplemente no funciona.

Este es el código que estoy usando:

#include "mbed.h"

DigitalIn ip(D7);
DigitalOut op(D8);

int main() {
    if (ip == 1){
        op = 0;
        wait (1.0);
        op = 1;
    }else{
        op = 1;
    }
}

Y para mí, eso parece lógico. En el estado habitual, la salida es ALTA. Si la entrada recibe la señal de la compuerta AND, el LED se apagará durante 1 segundo y luego se volverá a encender.

¿Qué es lo que he hecho mal, ya que parece ser la forma lógica de hacerlo y no puedo entender por qué no funciona?

Si ayuda, estoy usando el Nucleo F103RB. Cuando uso el código 'parpadear' y simplemente enciendo y apagando el LED de esa manera, funciona bien, es solo cuando agrego la declaración 'if' de que va mal.

Este es el circuito simplificado:

simular este circuito : esquema creado usando CircuitLab

PD: Sé que no los agregué en el esquema, pero las puertas AND tienen resistencias desplegables en las entradas y salidas.

    
pregunta Curious

4 respuestas

26

Pensé que necesitarías un bucle alrededor de tu código -

while(1)
{

    if (ip == 1){
       op = 0;
       wait (1.0);
       op = 1;}
    else {
       op = 1;}
}

Antes de que tenga la oportunidad de presionar el botón que su código habrá terminado y salido. Necesitas el tiempo para mantener la instrucción if repetidamente en ejecución.

    
respondido por el HandyHowie
21
#include "mbed.h"

DigitalIn ip(D7);
DigitalOut op(D8);

int main() {
    if (ip == 1){
        op = 0;
        wait (1.0);
        op = 1;
    }else{
        op = 1;
    }
    // and now the program ends? What to do?
}

El procesador ejecuta las instrucciones secuencialmente . Comienza con un salto a main() desde dentro del código de inicialización de la biblioteca mbed de DigitalIn y DigitalOut .
Luego realiza la comparación ip == 0 , ejecuta la instrucción dentro del {} y luego termina main() ... no hay más instrucciones ... ¿Qué hace?

Se podría reiniciar debido a la búsqueda de operandos ilegales en la memoria flash vacía. O podría colgarse en un manejador de fallas y parpadear SOS como lo hacen mbeds. Esto depende de cómo se implemente, y probablemente irá más allá de ti en este momento.
Pero si tiene curiosidad, puede investigar el manejo de fallas de ARM o averiguar de dónde se llama en realidad a main() .

Ahora, ¿cómo arreglar esto?

int main() {
    // Add a while(1) infinite loop
    while(1){
        if (ip == 1){
            op = 0;
            wait (1.0);
            op = 1;
        }else{
            op = 1;
        }
    }
    // Program never gets here
}
    
respondido por el Jeroen3
2

Como lo mencionaron otros correctamente, un bucle permitiría que su código se ejecute repetidamente. Sin embargo, hay una forma integrada de hacer esto para Arduino sin la necesidad de un bucle while . Esto se realiza mediante la función loop : su aplicabilidad a su problema depende de si utiliza el IDE de Arduino.

Debería verse algo como esto:

#include "mbed.h"

DigitalIn ip(D7);
DigitalOut op(D8);

void setup() {
    // any code before loop is run
}

void loop() {
    if (ip == 1){
        op = 0;
        wait (1.0);
        op = 1;
    }else{
        op = 1;
    }
}

Su función principal ahora está oculta y solo se agrega a su programa cuando se compila. Aquí hay una buena discusión sobre esto: enlace

    
respondido por el OLLEY102
0

Si está familiarizado con el montaje, esto podría ser un poco más en su zona de confort también:

int main () {

//A label or function similar to assembly

label:

    if (ip == 1){

        op = 0;

        wait (1.0);

        op = 1;

    }else{

        op = 1;

    }

// Goto used same as "jmp" in assembly

goto label;

// Program never gets here

}

    
respondido por el Susmit Agrawal

Lea otras preguntas en las etiquetas