마이크로 컨트롤러 LED 프로그램이 작동을 멈추게하는 원인은 무엇입니까?


11

그래서 저는 완전하고 프로그래밍에 초보자입니다. Arduinos (문자 그대로 LED를 토글하고 LCD에 무언가를 표시)에 대한 몇 가지 기본 작업을 수행했으며 C에서 프로그래밍하는 방법을 스스로 가르치려고 노력하고 있습니다. 무역으로 하드웨어 엔지니어입니다. 펌웨어 / 소프트웨어 측면 중 하나를 수행하고이를 가르치는 저녁 코스가 없으며, 커리어 옵션을 추가하고 싶습니다. 이러한 명령 중 일부가 어떻게 함께 진행되는지 이해하고 어려움을 겪고있는 이유를 이해하지 못했습니다.

그래서 입력과 출력이 있습니다. 내 출력은 LED를 켜는 FET의 게이트를 토글합니다. 입력은 AND 게이트에서옵니다. 따라서 LED가 항상 켜져 있고 AND 게이트에서 입력 신호를 받으면 (2 가지 조건이 충족 됨) 출력 (LED 토글)이 LOW로 전환되고 싶습니다 (LED를 끄십시오. 출력도 연결됨) AND 입력 중 하나 인 경우 입력 신호를 LOW로 설정합니다.

내가하고 싶은 일 : 입력을 '조건 충족'으로 읽고 LED를 끄고 싶습니다. 그런 다음 1 초 동안 꺼졌다가 다시 켜야합니다. 입력이 다시 HIGH가되면 프로세스가 반복됩니다. 다른 AND 게이트 입력으로 스위치를 만들기 위해 간단한 푸시를 사용하고 버튼을 누를 때 출력 (MCU 입력)이 높아지는 것을 측정했지만 LED 토글 (출력)이 꺼지지 않습니다. 내 코드는 매우 간단합니다.하지만 분명히 작동하지 않으므로 올바르게 이해하지 못합니다.

그래서 이것은 내가 사용하는 코드입니다.

#include "mbed.h"

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

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

그리고 그것은 논리적으로 보입니다. 일반적인 상태에서 출력은 HIGH입니다. 입력이 AND 게이트에서 신호를 받으면 LED가 1 초 동안 꺼졌다가 다시 켜집니다.

그것이 논리적 인 방법처럼 보이고 잘못 작동하는 이유를 이해할 수 없기 때문에 내가 잘못한 것은 무엇입니까?

도움이된다면 Nucleo F103RB를 사용하고 있습니다. '깜박임'코드를 사용하고 LED를 켜고 끄는 경우 제대로 작동합니다 .'if '문을 잘못 추가했을 때입니다.

이것은 단순화 된 회로입니다.

개략도

이 회로 시뮬레이션CircuitLab을 사용하여 작성된 회로도

추신 : 회로도에 추가하지 않았지만 AND 게이트에는 입력 및 출력에 풀 다운 저항이 있습니다.


"조건 충족"을 IN에 직접 넣으면 작동합니까?
Transistor

그렇지 않습니다. 버튼을 똑바로
Curious

1
입력 변수를 휘발성으로 표시하는 것이 좋습니다. 그렇지 않으면 컴파일러가 코드 외부에서 변경되지 않는다고 가정하여 이상한 최적화를 수행 할 수 있습니다.
Dirk Bruere

3
@DirkBruere :의 정의에 DigitalIn이미 포함되어 있기를 바랍니다 volatile.
MSalters

3
다음에 힌트 : CPU (또는 마이크로 컨트롤러)를 켜거나 재설정 할 때 버튼을 누르고 있습니다. 이제 어떻게됩니까?
CVn

답변:


26

코드 주위에 루프가 필요하다고 생각했을 것입니다.

while(1)
{

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

버튼을 누르기 전에 코드가 완료되고 종료됩니다. if 문을 반복해서 실행하려면 시간이 필요합니다.


그것이 저와 다른 점은 무엇입니까? 나는 'while'을 볼 수 있지만 그 기능은 무엇입니까? 모든 질문에 사과하지만 실제로 제로 지식으로 시작합니다!
Curious

1
@ 호기심 버튼을 누르기 전에 코드가 완료되고 종료됩니다. if 문을 반복해서 실행하려면 시간이 필요합니다. 프로그래밍하는 마이크로 컨트롤러와 다른 점이 없으면 일반적으로 그렇습니다.
HandyHowie

9
"그 이유를 설명해 주시겠습니까?"-조건이 0으로 해결 될 때까지 while 루프의 모든 항목이 반복됩니다. 조건은 무엇입니까? 그것은 "while"-키워드 다음의 괄호 안에있는 부분입니다. 보시다시피, 조건은 1로 설정되어 있으므로 절대 0이 아니므로 무한정 반복됩니다. while 루프가 없으면 코드가 한 번만 실행 된 후 소프트웨어가 종료되지만 while 루프를 사용하면 하드웨어를 켤 때까지 반복적으로 코드가 실행됩니다.
Jurgy

14
귀하의 오류는 아마도 Arduino로 이동하여 mbed로 발생했을 수 있습니다. Arduino에서는 일반적으로 애플리케이션 코드를 넣지 loop()만 Arduino 프레임 워크는 대략적으로 동작하는 코드를 추가합니다 int main() { setup(); while(1) { loop(); } }.
ris8_allo_zen0

1
@Curious Yours가 작동했습니다. 불행히도 전원을 켜 자마자 정확히 한 번 실행되었습니다. 실행하는 데 1 마이크로 초가 걸렸습니다. 입력을 계속 확인하고 출력을 설정하려면 계속 입력하도록 지시해야합니다. "some_condition"은 "some_condition"이 true 인 한 C 언어에서 0이 아닌 것을 의미합니다. 따라서 "while (1)"은 입력을 영원히 또는 적어도 전원이 켜져있는 한 계속 점검합니다.
Graham

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?
}

프로세서는 명령을 순차적으로 실행합니다 . 그것은에 점프 시작 main()의 mbed 라이브러리 초기화 코드 내에서 DigitalInDigitalOut.
그런 다음 비교를 수행하고 ip == 0명령을 실행 {}한 다음 main()종료합니다. 더 이상 명령이 없습니다 ... 어떻게합니까?

빈 플래시 메모리에서 잘못된 피연산자를 찾아서 재설정 할 수 있습니다. 또는 결함 처리기에 매달리고 mbeds처럼 SOS를 깜박일 수 있습니다. 이것은 이것이 어떻게 구현되는지에 달려 있으며 아마도 당신을 넘어서게 될 것입니다.
그러나 궁금한 점이 있으면 ARM Fault Handling을 조사하거나 main()실제 호출 위치를 찾을 수 있습니다.

자, 이것을 고치는 방법?

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
}

설명 감사합니다. while 루프를 통해 작동했습니다. 불행히도 내 담당자가 너무 낮아서 아직 +1을 줄 수는 없지만 답변과 설명을 대단히 감사합니다.
Curious

아하! 내 질문에 대한 세 번째 찬성 투표로 답을 투표 할 수있었습니다! 다시 한번 감사드립니다
Curious

1
@Curious 프로그래머에게 이것이 더 명확 해지려면 while(1 == 1)그냥 대신에 다음과 같이 쓸 수 있습니다 while(1). 후자는 관용적 C이지만 전자는 "항상 참으로 평가할 것"으로 인간에게 더 분명하다. 괜찮은 컴파일러는 두 변형에 대해 동일한 이진 코드를 생성해야합니다.
CVn

2
@ MichaelKjörling 나는 그것이 인간에게 더 분명하다는 것에 동의하지 않을 것입니다. 당신의 두뇌가 성격이 아닌 모양으로 단어를 읽는 것처럼 숙련 된 프로그래머에게이 관용구는 각각의 진술이 무엇을하고 있는지를 해석하는 대신 개념으로 직접 번역합니다. 관용구에서 멀어지면 사람들이 이해하기 위해 필요한 것보다 낮은 수준의 코드를 사용하게됩니다. 큰 코드 기반에 걸쳐 많은 불필요한 정신 작업이 추가됩니다.
Chuu

1
@Chuu "[숙련 된 프로그래머가 아닌] 인간의 존재에 의해"
user253751

2

다른 사람들이 올바르게 언급했듯이 루프를 사용하면 코드가 반복적으로 실행될 수 있습니다. 그러나 while루프 가 없어도 Arduino에서이를 수행 할 수있는 기본 제공 방법이 있습니다. 이것은 loop기능에 의해 수행됩니다 -문제에 대한 적용 가능성은 Arduino IDE 사용 여부에 따라 다릅니다.

다음과 같이 보일 것입니다 :

#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;
    }
}

주 함수는 이제 숨겨져 컴파일 할 때만 프로그램에 추가됩니다. 여기에 대한 좋은 토론이 있습니다 : http://forum.arduino.cc/index.php?topic=379368.0


네. 나는 원래 nucleo와 mbed IDE로 전환 할 때 왜 작동하지 않는지 이해할 수 없었습니다.
Curious

1
이 답변은 Arduino 시스템 사용에 의존합니다. mbed는 다른 시스템 / 라이브러리 세트이며 Arduino 의 loop()setup()기능은 대부분의 시스템에서 사용 되지 않습니다 . 참고로 Arduino는 간단히 main()다음과 같이 정의합니다 .void setup(); void loop(); int main() { setup(); while (true) loop(); }
Cameron Tacklind

0

조립에 익숙하다면, 이것은 당신의 안락 지대에도 조금 더있을 수 있습니다.

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

}


3
제발 고토 사용하지 않는 조립 위의 모든 언어로.
Jeroen3

나는 내가 두려워하는 집회에 전혀 익숙하지 않다!
Curious

나는 그것을 알고 있지만 그것에 관한 것입니다!
Curious

@ Jeroen3 당신이 연결하는 질문은 "고토가 몇 곳에서 적절하다", "고토가 제대로 사용된다면 아무 문제가 없다", "고토 자체에는 아무 문제가 없다"라는 답을 얻는다. 예외가있는 언어에서는 goto가 불필요하지만 특히 C에서는 그 용도가 있음에 동의합니다.
glglgl 12

@glglgl : 위에서 언급 한 Chuu는 코드를 읽을 수 있어야합니다. goto** 강하게 **는 아마도 "제외의 마술"을 제안 goto cleanup;합니다. 여기 예제에서 독자는 " while(1) { }여기서 사용하지 않은 특별한 점이 무엇 입니까 ???" 라는 수수께끼의 질문을 남길 것 입니다.
MSalters
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.