Catégories
Arduino

Arduino #26: Introduction aux pointeurs

Objectifs

  1. Comprendre qu’est ce qu’un pointeur
  2. Savoir manipuler les registres du µC & la mémoire
  3. Savoir utiliser les pointeurs scalaires
  4. Savoir utiliser les pointeurs et les tableaux
  5. Mise en pratique sur carte Arduino

Importance

  • Notion de la valeur et l’adresse (Arduino Mega)
  • Accès direct aux registres du µC
  • Création des alias: Une adresse pour plusieurs variables
  • Création des fonctions multi-retours
  • Voir les pages 399-403 (Datasheet)
  • Etc.

Comment déclarer un pointeur scalaire (valeur unique) ?

byte    *p1_b; byte *p2_b;  

int     *p1_i; int  *p2_i;  

long    *p1_l; long *p2_l;  

float   *p1_f; byte *p2_f;  

Comment initialiser un pointeur ?

  • Affectation d’une adresse mémoire constante OU bien
  • L’adresse d’une variable de même type (Opérateur « & »)
  • Un pointeur vide: NULL: p1_b=NULL;

Exemples

int *p; int valP;

p=  &valP;    // Adresse d'une variable

p=  0x00ff;   // Adresse constante

Comment savoir la taille d’une variable ?

  • => Anticiper la location mémoire et l’adressage
  • Voir le programme

Opérations sur les pointeurs = Mêmes opérations sur les variables

byte    *p_b; 

int     *p_i ;

double  *p_d;




p_b=p_b+1;    // Avance d'un octet en mémoire

p_i=p_i+1;    // Avance de "2" octets en mémoire

p_d=p_d+1;   // Avance de "8" octets en mémoire

p_d=p_d+10;   // Avance de 8x10 octets en mémoire !!!!!

p_d=p_d+n;    // Avance e 8xn octets

Les pointeurs et les tableaux

int tab[10];
  • tab ou tab[0] est un pointeur contant sur le premier élément du tableau
  • Si je connais l’adresse du premier élément et son type je peux ensuite
  • accéder à l’ensemble des éléments du tableau!
int tab[10], *ptab;

ptab=&tab[0]; // je pointe sur le premier élément

Exemple

for(int i=0;i<10;i++)

  {

    // Init 1

    tab[i]=10;

   

    // Equivalent à

    *(ptab+i)=10; // Contenu de l'adresse ptab+i 

  }

Tableau & la mémoire (optimisation de la mémoire)

  • byte     tab[10];    // 10*1=10 octets
  • int      tab[10];    // 10*2=20 octets
  • double   tab[10]     // 10*8=80 octets
  • => Rapport de 1 à 8, il faut tenir en compte le type de données
  • Avant d’effectuer la location mémoire.

Plusieurs tableaux ayant la même adresse

  • =>Une seule initialisation est suffisante pour l’ensemble des tableaux
byte tab[10], *tab1, *tab2, *tab3;

tab1=&tab[0];

tab2=&tab[0];

tab3=tab;

Exemple 1: taille & utilisation

byte a,  *pa; 

unsigned char *MyPORTA;

word  AddPORTA,Adda;




void setup()

{

  // Init port série

  Serial.begin(9600);




  // Init pointeurs

  pa=&a; 

  MyPORTA=&OCR3CH;

}




void loop()

{

  // Affichage de la taille des variables

  Serial.println("Tailles");

  Serial.println(sizeof(a));

  Serial.println(sizeof(PORTA));

  Serial.println("----------");




  // Init des valeurs des pointeurs

  *pa=10; PORTA=40;

  AddPORTA=MyPORTA; // Ou bien AdPORTA=MyPORTA;

  Adda=(word)pa;




  // Affichage des valeurs des variables

  Serial.println("Valeurs");

  Serial.println(a);

  Serial.println(PORTA);

  Serial.println("----------");




  // Affichage  des adresses

  Serial.println("Adresses");

  Serial.println(Adda);

  Serial.println(AddPORTA);

  Serial.println("----------");




  // délai de la boucle

  delay(2000);

}

 Exemple 2: les tableaux

byte tab[10], *tab1, *tab2;




void setup()

{

  // Init port série

  Serial.begin(9600);




  // Init pointeurs

  tab1=&tab[0];

  tab2=tab;




  // Init tab

  for(int i=0;i<10;i++)

    tab[i]=i;

}







void loop()

{

  // Affichage tab1

  for (int i=0;i<10;i++)

  {

    Serial.print(*(tab1+i));

    Serial.print(" ");

  }

  Serial.print("\n");




  for (int i=0;i<10;i++)

  {

    Serial.print(*(tab2+i));

    Serial.print(" ");

  }

  Serial.print("\n \n");




  // Délai

  delay(1000);

}

Laisser un commentaire