PORTB &= ~(1<<5) et PORTB |= (1<<5);

Ces commandes changent l'état de la sortie 13 mais quelqu'un pourrait m'expliquer comment ça fonctionne?
Car j'aimerais pouvoir l'appliquer à d'autres sortie digitales...

J'ai compris que c'est de la manipulation de ports de l'arduino mais je n'ai pas saisi réellement comment ça fonctionne?

Il te faut lire la datasheet du micro.
Lire la datasheet
Hors de la datasheet point de salut !
Tu y trouvera la description et le rôle des registres DDRB, DDRC et DDRD ainsi que PORTB, PORTC, PORTD

Pour comprendre comment ça fonctionne il va te falloir apprendre les opération bit à bit (ou bitwise). Skywodd a fait un très bon tuto sur le sujet :

Ça peut paraître long et rébarbatif au début, mais on s'y fait assez vite, à tel point qu'il est difficile de s'en passer une fois qu'on y a pris goût :slight_smile:

PORTB &= ~(1<<5)
(1<<5) c'est 1 décalé 5 fois à gauche soit 00100000
~ complémente la valeur soit 11011111
PORTB &= ~(1<<5) c'est équivalent à PORTB = PORTB & ~(1<<5)
soit PORTB = PORTB & 11011111

Cette opération sert à mettre à 0 le bit 6ème bit du port

Avec les explications ci-dessus tu devrais pouvoir interpréter facilement la seconde commande

Ok, merci pour vos réponses, je vais me pencher là dessus dès que j'ai un peu de temps pour lire le datasheet :wink:

Bonjour les copains,
Les instructions que tu présentes sont particulièrement illisibles à mon sens. Franchement, si je devais inverser la sortie 13 je coderais plus "directement".
Bon, je suis très débutant en langage C, mais ayant plus ou moins quelques instructions qui semblent contenues dans ces codes je vais t'exprimer ce que je crois.
PORTB est un registre à six bits qui est directement représentatif des E/S de 8 à 13 :
Le bit de poids faible est en relation directe avec la sortie binaire 8.
Le bit de poids fort est en liaison avec l'E/S binaire 13 qui sur Arduino pilote la LED soudée sur le circuit imprimé.
<< est le décalage de tous les bits d'un registre vers "la gauche", c'est à dire vers le poids fort. Le poids fort initial est perdu et l'on "entre" un "0" dans le poids faible.
1<<5 je ne suis pas certain, mais je crois que ça veut dire que l'on prend la valeur 1 que l'on décale 5 fois à gauche.
On obtient alors 100000. Si je ne me trompe pas, on force à 1 précisément le représentant binaire de la sortie 13 sur un registre de six bits. (J'imagine que l'on construit un masque logique en vue d'effectuer ensuite un ET logique.
Par contre, je ne comprend pas vraiment toute l'instruction PORTB I= (1<<5), cette affectation complexe échappe à mes notions actuelles sur le langage C.
L'instruction PORTB &= ~(1<<5) est une forme d'écriture qui est équivalete à :
PORTB = PORTB & ~(1<<5) que je trouve bien plus lisible personnellement.
Donc, PORTB reçoit sa valeur actuelle avec laquelle on fait un ET logique avec le résultat de (~(1<<5)).
L'opérateur ~ inverse tous les bits d'un registre.
Pour obtenir un "1" avec le ET logique il faut que les deux bits en vis à vis soient égals à "1".
Je ne suis pas capable d'en décortiquer plus, mais c'est un déjà début. :blush:

P.S : Quand j'ai rédigé cette réponse, pour une raison qui m'échappe il n'y avait que la première question sur mon écran. ce qui explique mes informations "saugrenues".

Bonjour,
Bon finalement je n'ai pas réglé mon problème.

J'ai une trame qui est de cette façon : b11111111 et qui correspond aux pins 0 à 7.

Ce que je veux c'est passer les pins 3,5et6 à des valeurs 0 sans toucher au reste de la trame.

Par exemple je pars de B01110101
Je veux forcer les bits 5 et 6 à 0 sans toucher les autres pour obtenir: B00010101 sans toucher les autres.

J'ai testé du &, du | du ^ et du ~ mais à chaque fois ça ne marche pas car je change la trame de départ
Comment je fais?

john_lenfr:
Par exemple je pars de B01110101
Je veux forcer les bits 5 et 6 à 0 sans toucher les autres pour obtenir: B00010101 sans toucher les autres.

V &= ~((1 << 6) | (1 <<5 ))

Les détails du fonctionnement ont été donnés par fdunews ci-dessus.

Pour rendre la chose plus claire, tu peux même remplacer la position des bits par des noms.

const byte LEDROUGE=5;
const byte LEDVERTE=6;

V &= ~((1 << LEDROUGE) | (1 <<LEDVERTE ))

Oui j'aurais bien voulu maitriser le changement des pins.

Mais en fait j'ai fait ça:

// define colors
#define RGB_RED               PORTD =(PORTD & B10010111) | B01100000;
#define RGB_GREEN             PORTD =(PORTD & B10010111) | B01001000; 
#define RGB_BLUE              PORTD =(PORTD & B10010111) | B00101000;
#define RGB_YELLOW            PORTD =(PORTD & B10010111) | B01000000;
#define RGB_MAGENTA           PORTD =(PORTD & B10010111) | B00100000;
#define RGB_CYAN              PORTD =(PORTD & B10010111) | B00001000;
#define RGB_WHITE             PORTD =(PORTD & B10010111);
#define RGB_BLACK             PORTD =(PORTD & B10010111) | B01101000;
#define LEDPIN13_ON           PORTB |= (1<<5);
#define LEDPIN13_OFF          PORTB &= ~(1<<5);

// define toggle switch
#define RGB_RED_SWITCH         PIND =(PIND | B01101000) & B00001000;
#define RGB_GREEN_SWITCH       PIND =(PIND | B01101000) & B00100000;
#define RGB_BLUE_SWITCH        PIND =(PIND | B01101000) & B01000000;
#define RGB_YELLOW_SWITCH      PIND =(PIND | B01101000) & B00101000;
#define RGB_MAGENTA_SWITCH     PIND =(PIND | B01101000) & B01001000;
#define RGB_CYAN_SWITCH        PIND =(PIND | B01101000) & B01100000;
#define RGB_WHITE_SWITCH       PIND =(PIND | B01101000) & B01101000;
#define LEDPIN13_SWITCH        PINB |= 1<<5;

Comment je peux l'adapter pour pouvoir remplacer les pins par des constantes?

La méthode V &= ~((1 << LEDROUGE) | (1 <<LEDVERTE )) fonctionne pour mettre une couleur mais pour faire le changement d'état avec PIND je n'ai pas trouvé comment faire?

Pour le portD j'ai fait comme ça mais je sais pas si c'est bon en terme de code (sinon en terme de réalisation ça fonctionne):

#define RGB_RED PORTD = (PORTD & (0<<PIN_BLUE)|(0<<PIN_GREEN)|(0<<PIN_RED)) | ~((0<<PIN_BLUE)|(0<<PIN_GREEN)|(1<<PIN_RED));

Pour PIND j'ai pas encore fait.

Dans le mçeme temps je me rend compte que je suis de toute façon un peut bridé car je ne prend en compte que les pins 0 à 7, pour les pins 8 à 13 il faudrait faire avec PORTB mais je ne sais pas comment on peut le prendre en compte en fonction des pins choisis?

Bon finalement ça ne fonctionne pas car ça me change l'état de la sortie 2 :frowning:

Donc je reste sur mon ancien code

Nulentout a bien résumé :

nulentout:
PORTB est un registre à six bits qui est directement représentatif des E/S de 8 à 13 :
Le bit de poids faible est en relation directe avec la sortie binaire 8.
Le bit de poids fort est en liaison avec l'E/S binaire 13 qui sur Arduino pilote la LED soudée sur le circuit imprimé.

après, il faut connaître les registres (datasheet...), car tu parles de PIND, sais-tu à quoi il correspond?

après, 0<<5 = 0, et même que 0<<x = O quelque soit x. d'où l'utilisation de ~ là où il faut.