Donc, je suis un novice COMPLET et total en programmation. J'ai fait quelques trucs de base sur Arduinos (basculer littéralement les LED et afficher quelque chose sur un écran LCD) et j'essaie de m'auto-apprendre à programmer en C. Je suis ingénieur matériel de métier, mais cela me dérange que je ne puisse pas faire n'importe quel côté du firmware / logiciel et il n'y a pas de cours du soir pour l'enseigner, et j'aimerais approfondir mes options de carrière. J'ai du mal à comprendre comment certaines de ces commandes vont ensemble et ont rencontré un problème que je n'arrive pas à comprendre pourquoi cela ne fonctionne pas.
Donc, j'ai une entrée et une sortie. Ma sortie bascule la porte d'un FET qui allume une LED. L'entrée provient d'une porte ET. Donc, ma LED est toujours allumée, et quand je reçois un signal d'entrée de la porte ET (2 conditions sont remplies), je veux que la sortie (bascule LED) passe à LOW (éteignez la LED. Comme la sortie est également connectée à l'une des entrées ET, cela fera également baisser le signal d'entrée.
Ce que je veux faire: je veux juste lire l'entrée comme «conditions remplies» et éteindre la LED. Il devrait ensuite être éteint pendant 1 seconde, puis rallumé. Si l'entrée revient à HAUT, le processus se répète. J'utilise une simple pression pour commuter comme l'autre entrée de porte ET et j'ai mesuré que la sortie (entrée MCU) monte haut lorsque le bouton est enfoncé, mais la bascule LED (sortie) ne s'éteint pas. Mon code est (je pense) sacrément simple, mais clairement je ne comprends pas quelque chose correctement car il ne fonctionne tout simplement pas.
Voici donc le code que j'utilise:
#include "mbed.h"
DigitalIn ip(D7);
DigitalOut op(D8);
int main() {
if (ip == 1){
op = 0;
wait (1.0);
op = 1;
}else{
op = 1;
}
}
Et pour moi, cela semble logique. Dans l'état habituel, la sortie est HAUTE. Si l'entrée reçoit le signal de la porte ET, la LED s'éteindra pendant 1 seconde, puis se rallumera.
Qu'est-ce que j'ai fait de mal car cela ressemble à la façon logique de le faire et je ne comprends tout simplement pas pourquoi cela ne fonctionne pas?
Si cela aide, j'utilise le Nucleo F103RB. Lorsque j'utilise le code «clignotant» et que je active et désactive simplement la LED comme ça, cela fonctionne bien, c'est juste lorsque j'ajoute la déclaration «si» que ça va mal.
Voici le circuit simplifié:
simuler ce circuit - Schéma créé à l'aide de CircuitLab
PS Je sais que je ne les ai pas ajoutés dans le schéma, mais les portes ET ont des résistances déroulantes sur les entrées et les sorties.
DigitalIn
comprend déjàvolatile
.Réponses:
J'aurais pensé que vous auriez besoin d'une boucle autour de votre code -
Avant de pouvoir appuyer sur le bouton, votre code sera terminé et terminé. Vous avez besoin de temps pour que l'instruction if soit exécutée à plusieurs reprises.
la source
loop()
, mais le cadre Arduino ajoute du code qui se comporte à peu près commeint main() { setup(); while(1) { loop(); } }
.Le processeur exécute les instructions séquentiellement . Il commence par un saut à
main()
partir du code d'initialisation de la bibliothèque mbed deDigitalIn
etDigitalOut
.Effectue ensuite la comparaison
ip == 0
, exécute l'instruction dans le{}
puismain()
se termine ... plus d'instructions ... Que fait-il?Il pourrait se réinitialiser en raison de la découverte d'opérandes illégaux dans la mémoire flash vide. Ou il pourrait se bloquer dans un gestionnaire de fautes et clignoter SOS comme le font les mbeds. Cela dépend de la façon dont cela est mis en œuvre et vous dépassera probablement en ce moment.
Mais si vous êtes curieux, vous pouvez rechercher ARM Fault Handling, ou savoir d'où
main()
est réellement appelé.Maintenant, comment y remédier?
la source
while(1 == 1)
au lieu de simplementwhile(1)
. Ce dernier est idiomatique C, mais le premier est plus évident pour un être humain car "sera toujours évalué comme vrai". Tout compilateur décent devrait produire le même code binaire pour les deux variantes.Comme correctement mentionné par d'autres, une boucle permettrait à votre code de s'exécuter à plusieurs reprises. Cependant, il existe un moyen intégré de le faire pour Arduino sans avoir besoin d'une
while
boucle. Cela se fait par laloop
fonction - son applicabilité à votre problème dépend de l'utilisation de l'IDE Arduino.Ça devrait ressembler a quelque chose comme ca:
Votre fonction principale est désormais masquée et n'est ajoutée à votre programme qu'une fois compilée. Voici une bonne discussion à ce sujet: http://forum.arduino.cc/index.php?topic=379368.0
la source
loop()
etsetup()
d'Arduino ne sont pas utilisées dans la plupart des systèmes. Pour référence, Arduino définit simplementmain()
quelque chose comme ceci:void setup(); void loop(); int main() { setup(); while (true) loop(); }
Si vous êtes familier avec l'assemblage, cela pourrait aussi être un peu plus dans votre zone de confort:
int main() {
}
la source
goto
** fortement ** suggère "la magie qui se passe ici", peut-être à l'exception degoto cleanup;
. Dans l'exemple ici, le lecteur se retrouvera avec la question déroutante "qu'est-ce qui est si spécial que vous n'avez pas utiliséwhile(1) { }
ici ???".