Partage
  • Partager sur Facebook
  • Partager sur Twitter

Galère typique avec microcontrôleur Atmega328P

Arrivez-vous à comprendre la supercherie?

Sujet résolu
    23 janvier 2019 à 11:23:35

    Bonjour, je me suis lancé dans la quête qu'est de faire clignoter une led avec un microcontrôleur atmega328P.

    Petite difficulté : Je veux lire l'état de la led pour savoir si je dois l'allumer ou l'éteindre à chaque passage dans la boucle.

    Mon code : 

    #define RED B00100000
    
    void setup()
    {
    	DDRD = RED;
    	
    }
    
    void loop()
    {
    	
            Serial.print("ALLUME       ");
    	PORTD = PORTD | RED;
    	Serial.print("PORTD        ");
    	Serial.println(PORTD, BIN);
    	Serial.print("PORTD & RED  ");
    	Serial.println(PORTD & RED, BIN);
    	Serial.print("RED          ");
    	Serial.println(RED, BIN);
    	if (PORTD & RED == RED) Serial.println("yes");
    	else Serial.println("no");
    	delay(500);
    	Serial.print("ETEIND       ");
    	PORTD = PORTD & ~RED;
    	Serial.print("PORTD        ");
    	Serial.println(PORTD, BIN);
    	Serial.print("PORTD & RED  ");
    	Serial.println(PORTD & RED, BIN);
    	Serial.print("RED          ");
    	Serial.println(RED, BIN);
    	if (PORTD & RED == RED) Serial.println("yes");
    	else Serial.println("no");
    	delay(500);	
    }

    Le Serial moniteur : 

    Connaissez vous la logique de ce microcontrôleur? 

    Je m'attends à avoir yes quand PORTD = PORTD | RED; et no quand PORTD = PORTD &~ RED;

    Pourquoi ais-je tout le temps no?

    Merci d'avance pour votre enquête.

    -
    Edité par yoyo22 23 janvier 2019 à 11:32:14

    • Partager sur Facebook
    • Partager sur Twitter
      23 janvier 2019 à 15:21:43

      va voire des tutoriels Arduino , c'est le même micro-contrôleur qu'il utilise donc le même code, sinon attention au branchement si tu le fais directement avec le microcontrôleur sans passer par la carte Arduino ou autre type de carte .
      • Partager sur Facebook
      • Partager sur Twitter
        24 janvier 2019 à 10:33:37

        En fait j'ai dit Atmega328 pour ne pas qu'on me dise d'utiliser la lib Arduino, car je veux faire du code pro. Je veux donc utiliser l'aruino comme un microcontrôleur standard genre pic. 

        Je ne veux pas par exemple utiliser la fonction digitalRead(), qui fonctionne dans mon cas. 

        Ma question est tout simplement est-ce que quelqu'un sait pourquoi la condition 

        if (PORTD & RED == RED)

        renvoie false lorsque PORTD = RED soit

            PORTD = 0b01000000;
            RED = 0b01000000;

        Merci.

        -
        Edité par yoyo22 24 janvier 2019 à 10:34:55

        • Partager sur Facebook
        • Partager sur Twitter
          24 janvier 2019 à 12:22:27

          Il manque des parenthèses :

          if ( PORTD & RED == RED )
          // est équivalent à :
          if ( PORTD & (RED == RED) )
          // il faut plutôt écrire
          if ( (PORTD & RED) == RED )
          • Partager sur Facebook
          • Partager sur Twitter

          En recherche d'emploi.

            24 janvier 2019 à 13:32:06

            Voir les priorités dans https://fr.cppreference.com/w/cpp/language/operator_precedence

            PrioritéOpérateurDescriptionAssociativité
            1 :: Résolution de portée Gauche à droite
            2 ++   -- Incrémentation et décrementation suffixe/postfixe
            () Appel de fonction
            [] Accès dans un tableau
            . Sélection membre par référence
            −> Sélection membre par pointeur
            3 ++   -- Incrementation et décrementation préfixe Droite à gauche
            +   Plus et moins unaires
            !   ~ NON logique et NON binaire
            (type) Transtypage
            * Indirection (déréférence)
            & Adresse
            sizeof Taille
            new, new[] Allocation dynamique de la mémoire
            delete, delete[] Libération dynamique de la mémoire
            4 .*   ->* Pointeur vers un membre Gauche à droite
            5 *   /   % Multiplication, division et reste
            6 +   Addition et soustraction
            7 <<   >> Décalage binaire à gauche et à droite
            8 <   <= Respectivement pour les opérateurs de comparaison < et ≤
            >   >= Respectivement pour les opérateurs de comparaison > et ≥
            9 ==   != Respectivement pour les comparaisons = et ≠
            10 & ET binaire
            11 ^ XOR binaire (ou exclusif)
            12 | OU binaire (ou inclusif)
            13 && ET logique
            14 || OU logique
            15 ?: opérateur conditionnel ternaire Droite à gauche
            = Affectation directe (fourni par défaut pour les classes C++)
            +=   −= Affectation par somme ou différence
            *=   /=   %= Affectation par produit, division ou reste
            <<=   >>= Affectation par décalage binaire à gauche ou à droite
            &=   ^=   |= Affectation par ET, XOR ou OU binaire
            16 throw opérateur Throw (pour les exceptions)
            17 , Virgule

            Gauche à droite

            Ce qui est sur une ligne est "plus fort" que ce qui est sur les lignes suivante, donc par exemple dans a*b+c, la multiplication (ligne 5) l'emporte sur l'addition (ligne 6) et donc on lit (a*b)+c;

            Dans  a & b == c,   le & est ligne 10 et le == ligne 9, donc  le == l'emporte =>   a & (b==c).

            -
            Edité par michelbillaud 24 janvier 2019 à 13:35:15

            • Partager sur Facebook
            • Partager sur Twitter
              24 janvier 2019 à 13:58:05

              C'était bien une histoire de parenthèses! Vous êtes de chefs, merci :)

              • Partager sur Facebook
              • Partager sur Twitter
                25 janvier 2019 à 11:32:51

                Dalfab a écrit:

                Il manque des parenthèses :

                if ( PORTD & RED == RED )
                // est équivalent à :
                if ( PORTD & (RED == RED) )
                // il faut plutôt écrire
                if ( (PORTD & RED) == RED )


                D'où l'intéret d'écrire une fois pour toute une fonction qui fait le job, et rendra le programme plus clair de toutes façons

                /**
                 * Test if bits are all set in the value
                 * @param mask    mask with ones at the positions to be checked
                 * @param value   
                 * @return   true if all bits are set
                 */
                
                bool isSet(int mask, int value) {
                   return (mask & value) == mask;
                }
                


                usage

                if (isSet(RED, PORTD)) {
                   ...
                }
                

                Le compilateur est assez grand pour "inliner" et optimiser. C'est son job. Celui du programmeur est d'écrire des programmes lisibles qui marchent sans se prendre la tete ni celle de celui qui devra modifier le programme.

                -
                Edité par michelbillaud 25 janvier 2019 à 11:34:30

                • Partager sur Facebook
                • Partager sur Twitter

                Galère typique avec microcontrôleur Atmega328P

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown