Jestem więc ZUPEŁNYM i kompletnym nowicjuszem w programowaniu. Zrobiłem kilka podstawowych rzeczy na Arduinos (dosłownie przełączając diody LED i wyświetlając coś na wyświetlaczu LCD) i staram się samemu nauczyć się programowania w C. Z zawodu jestem inżynierem sprzętu, ale przeszkadza mi, że nie mogę zrobić jakąkolwiek stronę oprogramowania / oprogramowania i nie ma wieczornych kursów, aby tego nauczyć, i chciałbym rozwinąć opcje kariery. Próbuję zrozumieć, w jaki sposób niektóre z tych poleceń idą w parze i napotkałem problem, którego po prostu nie mogę zrozumieć, dlaczego to nie działa.
Mam więc wejście i wyjście. Moje wyjście to przełączanie bramki FET, która włącza diodę LED. Dane wejściowe pochodzą z bramki AND. Tak więc moja dioda LED jest zawsze włączona, a gdy otrzymam sygnał wejściowy z bramki AND (spełnione są 2 warunki), chcę, aby wyjście (przełączanie diody LED) było NISKIE (wyłącz diodę. Ponieważ wyjście jest również podłączone do jedno z wejść AND, spowoduje to również zmianę sygnału wejściowego na NISKI.
Co chcę zrobić: chcę tylko odczytać wejście jako „spełnione warunki” i wyłączyć diodę LED. Następnie należy go wyłączyć na 1 sekundę i włączyć ponownie. Jeśli sygnał wejściowy ponownie stanie się WYSOKI, proces się powtarza. Używam prostego przycisku, aby zrobić przełącznik jako inne wejście bramki AND i zmierzyłem, że wyjście (wejście MCU) idzie wysoko po naciśnięciu przycisku, ale przełącznik LED (wyjście) nie wyłącza się. Mój kod jest (myślę) dość cholernie prosty, ale najwyraźniej nie rozumiem czegoś poprawnie, ponieważ to po prostu nie działa.
Oto kod, którego używam:
#include "mbed.h"
DigitalIn ip(D7);
DigitalOut op(D8);
int main() {
if (ip == 1){
op = 0;
wait (1.0);
op = 1;
}else{
op = 1;
}
}
I wydaje mi się to logiczne. W zwykłym stanie sygnał wyjściowy jest WYSOKI. Jeśli wejście otrzyma sygnał z bramki AND, dioda LED zgaśnie na 1 sekundę, a następnie ponownie się zaświeci.
Co zrobiłem źle, ponieważ wygląda to na logiczny sposób i po prostu nie rozumiem, dlaczego to nie działa?
Jeśli to pomoże, używam Nucleo F103RB. Kiedy używam kodu „mrugania” i po prostu włączam i wyłączam diodę LED w ten sposób, działa to dobrze, to tylko wtedy, gdy dodam instrukcję „if”, że idzie źle.
To jest uproszczony obwód:
symulacja tego obwodu - Schemat utworzony przy użyciu CircuitLab
PS Wiem, że nie dodałem ich do schematu, ale bramki AND mają rozwijane rezystory na wejściach i wyjściach.
DigitalIn
zawiera jużvolatile
.Odpowiedzi:
Myślałem, że potrzebujesz pętli wokół swojego kodu -
Zanim będziesz mógł nacisnąć przycisk, kod zostanie zakończony i zakończony. Potrzebujesz czasu, aby wielokrotnie uruchamiać instrukcję if.
źródło
loop()
, ale framework Arduino dodaje kod, który z grubsza się zachowujeint main() { setup(); while(1) { loop(); } }
.Procesor wykonuje instrukcje sekwencyjnie . Zaczyna się od skoku do
main()
z kodu inicjalizacji biblioteki mbedDigitalIn
iDigitalOut
.Następnie wykonuje porównanie
ip == 0
, uruchamia instrukcję wewnątrz,{}
a następniemain()
kończy ... nie więcej instrukcji ... Co to robi?Może zostać zresetowany z powodu znalezienia niedozwolonych operandów w pustej pamięci flash. Lub może zawiesić się w module obsługi błędów i mrugać SOS, tak jak robią to mbeds. Zależy to od tego, w jaki sposób jest to realizowane, i prawdopodobnie wykroczy teraz poza ciebie.
Ale jeśli jesteś ciekawy, możesz zbadać obsługę błędów ARM lub dowiedzieć się, skąd
main()
tak naprawdę pochodzi.Jak to naprawić?
źródło
while(1 == 1)
zamiast po prostuwhile(1)
. Ten drugi to idiomatyczny C, ale ten pierwszy jest bardziej oczywisty dla człowieka, ponieważ „zawsze oceni się jako prawdziwy”. Każdy przyzwoity kompilator powinien wygenerować ten sam kod binarny dla obu wariantów.Jak słusznie wspominają inni, pętla pozwala na wielokrotne uruchamianie kodu. Istnieje jednak wbudowany sposób, aby to zrobić dla Arduino bez potrzeby używania
while
pętli. Odbywa się to przezloop
funkcję - jej zastosowanie do twojego problemu zależy od tego, czy korzystasz z Arduino IDE.Powinno to wyglądać mniej więcej tak:
Twoja główna funkcja jest teraz ukryta i jest dodawana do programu dopiero po skompilowaniu. Oto dobra dyskusja na ten temat: http://forum.arduino.cc/index.php?topic=379368.0
źródło
loop()
asetup()
funkcje i Arduino nie są używane w większości systemów. Dla porównania, Arduino po prostu definiujemain()
coś takiego:void setup(); void loop(); int main() { setup(); while (true) loop(); }
Jeśli jesteś zaznajomiony z montażem, może to być nieco więcej w twojej strefie komfortu:
int main () {
}
źródło
goto
** zdecydowanie ** sugeruje „magię tu się dzieje”, być może z wyjątkiemgoto cleanup;
. W tym przykładzie czytelnikowi pozostanie zagadkowe pytanie „co jest takiego specjalnego, że niewhile(1) { }
użyłeś tutaj ???”.