web-dev-qa-db-fra.com

C - AVR - Simple PORTB, DDRB, PINB explication

Je travaille sur un projet scolaire et j'ai besoin d'apprendre les bases du C avec un contrôleur AVR atmega.

Je ne comprends pas comment tout est mis en place. Par exemple PORTB, PORTD, DDRB; DDRD, PINB, PIND et des trucs comme ça. Et je ne sais pas comment tout fonctionne avec les instructions if, les boucles while, etc.

Quelqu'un peut-il me donner une courte explication s'il vous plaît?

J'ai quelques lignes de code ...

DDRB = 0b00000011; // I know that here DDRB is set to input/output

Et une instruction if:

if (PINB & (1 << PINB0)){
    A = true;
}

Quelqu'un peut-il m'expliquer comment fonctionne cette "déclaration if"? Pourquoi PINB & (1<< PINB0))?

Merci

14
Mike_NotGuilty

Voulez-vous dire quelle est la condition if PINB & (1<< PINB0))?

Il vérifie si PINB0 + 1 le bit numérique (de rhs) est activé (1) dans PINB ou désactivé (0).

Par exemple. (a & (1 << 2)) vérifie si le 3e bit est activé dans a ou désactivé. Dans l'expression, deux opérateurs sont utilisés << décalage gauche au niveau du bit et & au niveau du bit et ci-dessous, j'ai expliqué pour un exemple d'octet:

  1. 1 est 0000 0001
  2. 1 << 2 après décalage à gauche donne 0000 0100
  3. a au niveau du bit et avec 0000 0100 donne soit tous les zéros 0000 0000 ou 0000 0100

    3a. Si tous les zéros, alors si la condition est fausse (lorsque le troisième bit dans a est nul).
    3b. Si le résultat au niveau du bit et est 0000 0100 alors si la condition est évaluée comme vraie (lorsque le troisième bit dans a en est un).

11
Grijesh Chauhan

Les microprocesseurs utilisent une carte mémoire pour interfacer leurs fonctionnalités matérielles avec le logiciel.

Fondamentalement, il existe des adresses statiques en mémoire que le matériel utilisera pour déterminer sa fonctionnalité. Ceux-ci sont spécifiques au fabricant, à la pièce et parfois même à la configuration de la pièce.

La fiche technique de la pièce vous indiquera l'emplacement exact de la mémoire pour contrôler différentes fonctionnalités. Cependant, cela est normalement très fastidieux. En conséquence, la fiche technique donnera également (presque) toujours un nom à cet emplacement particulier en mémoire qui décrit ses fonctionnalités. Encore une fois, ces noms sont spécifiques au fabricant et à la pièce.

Pour rendre cette interface plus facile pour les programmeurs, les personnes (le fabricant ou la communauté) créent souvent des macros vers ces emplacements de mémoire. Par exemple, vous pouvez trouver

// Clock Prescalar Register for ATMega328p
#define CLKPR *0x61

dans un fichier d'en-tête associé à la pièce (comme AVR libc).

Maintenant, en écrivant OSCCAL = 0b10000000 (ou tout ce que je veux écrire qui est permis par les spécifications de la fiche technique) Je peux accéder directement et changer le module d'horloge prescalaire pour cette partie.

Mais, souvent, nous nous intéressons à la valeur d'un seul bit, pas à l'ensemble de l'octet. Par conséquent, nous utilisons des opérateurs au niveau du bit (tels que &, |, ~, <<>>) pour "masquer" les bits que nous souhaitons manipuler.

Cela offre l'avantage simultané de nous permettre de lire uniquement la valeur du bit d'intérêt, sans changer par inadvertance les bits que nous ne voulons pas basculer.

De nombreuses positions de bits sont également fournies par des macros. Par exemple, le bit 7 dans OSCCAL est nommé CLKPCE (encore une fois, à partir de la feuille de données).

CLKPCE est très probablement défini (au moins dans AVR libc - les normes varient) par:

#define CLKPCE 7

car il définit le décalage de bit nécessaire pour atteindre le bit souhaité dans OSCCAL.

Afin de parler du bit ici, je peux faire plusieurs choses.

Mettez le bit

Pour définir le bit, nous voulons lui donner un 1, sans affecter aucun des autres bits. Pour ce faire, nous utilisons un masque OR, comme suit:

OSCCAL = (OSCCAL | (1 << CLKPCE));

Je vous laisse le soin d'examiner les opérateurs de bits et de voir comment cela fonctionne.

Dégagez le bit

Ici, nous voulons en faire un 0, sans affecter les autres bits. Cela ressemblera à ceci:

OSCCAL = (OSCCAL & ~(1 << CLKPCE));

Interrogez le bit

Lors de la requête, nous voulons une expression qui retourne non nulle si le bit a été défini (1), et zéro si le bit a été effacé (0). Cela ressemblera à ceci:

(OSCCAL & (1 << CLKPCE));

The Takeaway

En utilisant ces différentes opérations au niveau du bit avec des macros prédéfinies, nous pouvons directement contrôler et interroger l'état du matériel en utilisant cette carte de mémoire statique.

Cependant, pour donner un sens à toutes ces macros, vous devrez consulter (et lire, relire et relire) la fiche technique de votre pièce. Heureusement, les PDF consultables sont disponibles gratuitement chez Atmel sur la page de votre pièce!

9
Glenn
if (PINB & (1 << PINB0)){
        A = true;
    }

Ce code vérifie si PIN 0 in PORTB Est HIGH or LOW. S'il est élevé, il affecte alors A = true; Ici, PINB -> Lit les données de PORTB, (1<<PINB0) -> Rend le 0e bit égal à 1 et les deux valeurs de AND pour savoir si PIN 0 dans PORTB est élevé ou non.

5
Chinna