Cours:CoursM2103 : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
(Page créée avec « =Manipulation d'un bit d'un registre= ==Mettre un bit à l'état 1== »)
 
 
(40 révisions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
=Manipulation d'un bit d'un registre=
+
=Fixed width integer types=
 +
On utilisera les types explicitant directement l'espace utilisé dans la mémoire :
  
==Mettre un bit à l'état 1==
+
{| class="wikitable"
 +
|-
 +
! type !! taille (bits) !! minimum || maximum
 +
|-
 +
| uint8_t || 8 || 0 || 255
 +
|-
 +
| int8_t || 8 || -128 || 127
 +
|-
 +
| uint16_t || 16 || 0 || 65535
 +
|-
 +
| int16_t || 16 || -32768 || 32767
 +
|-
 +
| uint32_t || 32 || 0 || 2^32-1 = 4 294 967 295
 +
|-
 +
| int32_t || 32 || -2^31 || 2^31-1
 +
|-
 +
| uint64_t || 64 || 0 || 2^64-1
 +
|-
 +
| int64_t || 64 || -2^63 || 2^63-1
 +
|}
 +
 
 +
=gestion des broches=
 +
==Entrée/Sortie==
 +
{|
 +
|-style="vertical-align:top;"
 +
|style="width: 450px"|
 +
 
 +
===Direction Input/Output===
 +
 
 +
Mettre la broche '''P{{Rouge|C}}{{Bleu|3}}''' en '''sortie''' :
 +
'''DDR{{Rouge|C}} |= ( 1 << P{{Rouge|C}}{{Bleu|3}} );'''
 +
Mettre la broche '''P{{Rouge|E}}{{Bleu|5}}''' en '''entrée''' :
 +
'''DDR{{Rouge|E}} &=~ ( 1 << P{{Rouge|E}}{{Bleu|5}} );'''
 +
||
 +
===Exemples===
 +
 
 +
{| class="wikitable"
 +
|-
 +
! broche !! Rôle !! Registre || Code
 +
|-
 +
| PC5 || Sortie || DDRC || <nowiki>DDRC |= (1<<PC5);</nowiki>
 +
|-
 +
| PD5 et PD7 || Sortie || DDRD || <nowiki>DDRD |= (1<<PD5)|(1<<PD7);</nowiki>
 +
|-
 +
| PA3 || Entrée || DDRA ||  <nowiki>DDRA &=~(1<<PA3);</nowiki>
 +
|-
 +
| PD0 et PD1 || Entrée || DDRD ||  <nowiki>DDRD &=~( (1<<PD0)|(1<<PD1));</nowiki>
 +
|}
 +
<source lang=cpp>
 +
// modifier la direction de toutes les broches d'un port
 +
// ex : PA0,PA1,PA2,PA3 en entrées
 +
// ex : PA4,PA5,PA6,PA7 en sortie
 +
 
 +
DDRA=0b11110000;
 +
//ou
 +
DDRA=0xF0;
 +
//ou
 +
DDRA=(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4)|(0<<PA3)|(0<<PA2)|(0<<PA1)|(0<<PA0);
 +
//ou
 +
DDRA|=(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4);
 +
DDRA&=~((1<<PA3)|(1<<PA2)|(1<<PA1)|(1<<PA0));
 +
 
 +
</source>
 +
|}
 +
 
 +
==Modifier l'état d'une sortie==
 +
 
 +
Il faut avoir déclarer {{Rouge|la broche en sortie, cf ci-dessus}} !!
 +
{|
 +
|-style="vertical-align:top;"
 +
|style="width: 450px"|
 +
 
 +
===Mettre à 0/1===
 +
 
 +
Mettre la broche '''P{{Rouge|C}}{{Bleu|3}}''' à '''1''' :
 +
'''PORT{{Rouge|C}} |=  ( 1 << P{{Rouge|C}}{{Bleu|3}} );'''
 +
Mettre la broche '''P{{Rouge|E}}{{Bleu|5}}''' à '''0''' :
 +
'''PORT{{Rouge|E}} &=~ ( 1 << P{{Rouge|E}}{{Bleu|5}} );'''
 +
||
 +
===Exemples===
 +
 
 +
{{Rouge|'''<big>Attention</big>'''}}, il vaut mieux mettre quques parenthèses en trop que pas assez !!
 +
 
 +
<source lang=cpp>
 +
...
 +
// mettre la broche PA2 à 1 :
 +
PORTA |= (1<<PA2);
 +
// mettre la broche PB3 à 0 :
 +
PORTB &=~ (1<<PB3);
 +
// changer l'état de la broche PC5 :
 +
PORTC ^= (1<<PC5);
 +
// mettre les broche PB2 et PB3 à 1 :
 +
PORTB |= ( (1<<PB2) | (1<<PB3) );
 +
// mettre les broche PC4 et PC6 à 0 :
 +
PORTC &=~ ( (1<<PC4) | (1<<PC6) );
 +
// mettre à 0 PA0 PA1 PA2 et à 1 PA3 PA4 PA5 PA6 PA7
 +
// !! attention, cela modifie toutes les sorties !!
 +
PORTA = 0b11111000;
 +
// ou
 +
PORTA = (1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4)|(1<<PA3)|(0<<PA2)|(0<<PA1)|(0<<PA0);
 +
</source>
 +
|}
 +
 
 +
 
 +
==Lire l'état d'une entrée==
 +
 
 +
Il faut éventuellement  avoir déclarer {{Rouge|la broche en entrée, cf ci-dessus}} !!
 +
{|
 +
|-style="vertical-align:top;"
 +
|style="width: 450px"|
 +
 
 +
===Action si 0/1===
 +
 
 +
include <avr/sfr_defs.h>
 +
 
 +
Action si la broche '''P{{Rouge|C}}{{Bleu|3}}''' à '''1''' :
 +
'''if ( bit_is_set(PIN{{Rouge|C}},P{{Rouge|C}}{{Bleu|3}}) )...'''
 +
Action si broche '''P{{Rouge|E}}{{Bleu|5}}''' à '''0''' :
 +
'''if ( bit_is_clear(PIN{{Rouge|E}},P{{Rouge|E}}{{Bleu|5}}) )...'''
 +
||
 +
 
 +
===Exemples===
 +
 
 +
{{Rouge|'''<big>Attention</big>'''}}, il vaut mieux mettre quques parenthèses en trop que pas assez !!
 +
 
 +
<source lang=cpp>
 +
// si la broche PB2 est à 1 et la broche PD3 est à 0
 +
if ( bit_is_set(PINB,PB2) and bit_is_clear(PIND,PD3) )
 +
{
 +
  // mettre la sortie PE4 à 1
 +
  PORTE |= (1<<PE4);
 +
}
 +
else
 +
{
 +
  // sinon mettre la sortie PE4 à 0
 +
  PORTE &=~ (1<<PE4);
 +
}
 +
</source>
 +
|}
 +
 
 +
 
 +
{|
 +
|-style="vertical-align:top;"
 +
|style="width: 450px"|
 +
 
 +
===Attendre un changement d'état===
 +
 
 +
include <avr/sfr_defs.h>
 +
 
 +
Attendre que '''P{{Rouge|C}}{{Bleu|3}}''' soit à '''1''' :
 +
'''loop_until_bit_is_set(PIN{{Rouge|C}},P{{Rouge|C}}{{Bleu|3}}) ;'''
 +
Attendre que '''P{{Rouge|E}}{{Bleu|5}}''' soit à '''0''' :
 +
'''loop_until_bit_is_clear(PIN{{Rouge|E}},P{{Rouge|E}}{{Bleu|5}});'''
 +
||
 +
 
 +
===Exemples===
 +
 
 +
{{Rouge|'''<big>Attention</big>'''}}, il vaut mieux mettre quques parenthèses en trop que pas assez !!
 +
 
 +
<source lang=cpp>
 +
while(1)
 +
{
 +
  //Attendre un front montant sur PD4
 +
  loop_until_bit_is_set(PIND,PD4);
 +
  //changer alors la sortie PD3
 +
  PORTD^=(1<<PD3);
 +
  //Attendre que PD4 repasse à 0 avant de recommencer
 +
  loop_until_bit_is_clear(PIND,PD4);
 +
}
 +
</source>
 +
|}
 +
 
 +
 
 +
==Déclencher une interruption sur changement des entrées==
 +
 
 +
{|
 +
|-style="vertical-align:top;"
 +
|style="width: 450px"|
 +
 
 +
===n°interruption===
 +
Spécifique à chaque µcontrôleur, en général :
 +
#choisir le numéro d'interruption en fonction de la broche<br>INT0 INT1 INT2 ...
 +
#choisir à quel moment s'exécute l'interruption
 +
#*front montant de l'entrée
 +
#*front descendant de l'entrée
 +
#*changement d'état (tous les fronts)
 +
#autoriser l'interruption
 +
#écrire la fonction d'interruption
 +
||
 +
===Exemples===
 +
pour un atmega328p, INT1 exécutée à chaque changement d'état
 +
 
 +
cf [[Cours:Atmega328p#Interruptions]] pour détails
 +
 
 +
<source lang=cpp>
 +
#include <avr/io.h>
 +
#include <avr/interrupt.h>
 +
 
 +
ISR(INT1_vect)
 +
{
 +
  // changer l'état de PC3 à chaque interruption
 +
  PORTC ^= (1<<PC3);
 +
}
 +
 
 +
int main()
 +
{
 +
  // broche en sortie
 +
  DDRC |= (1<<PC3);
 +
  // INT1 sur changement d'état
 +
  EICRA |= (1<<ISC10);
 +
  // autorisation interruption
 +
  EIMSK |= (1<<INT1);
 +
  sei();
 +
  while(1)
 +
  {
 +
  }
 +
}
 +
</source>
 +
|}
 +
 
 +
=I2C=

Version actuelle datée du 26 mars 2024 à 17:17

Fixed width integer types

On utilisera les types explicitant directement l'espace utilisé dans la mémoire :

 type taille (bits) minimum maximum
uint8_t 8 0 255
int8_t 8 -128 127
uint16_t 16 0 65535
int16_t 16 -32768 32767
uint32_t 32 0 2^32-1 = 4 294 967 295
int32_t 32 -2^31 2^31-1
uint64_t 64 0 2^64-1
int64_t 64 -2^63 2^63-1

gestion des broches

Entrée/Sortie

Direction Input/Output

Mettre la broche PC3 en sortie :
DDRC |=  ( 1 << PC3 );
Mettre la broche PE5 en entrée :
DDRE &=~ ( 1 << PE5 );

Exemples

broche Rôle Registre Code
PC5 Sortie DDRC DDRC |= (1<<PC5);
PD5 et PD7 Sortie DDRD DDRD |= (1<<PD5)|(1<<PD7);
PA3 Entrée DDRA DDRA &=~(1<<PA3);
PD0 et PD1 Entrée DDRD  DDRD &=~( (1<<PD0)|(1<<PD1));
// modifier la direction de toutes les broches d'un port
// ex : PA0,PA1,PA2,PA3 en entrées
// ex : PA4,PA5,PA6,PA7 en sortie

DDRA=0b11110000;
//ou
DDRA=0xF0;
//ou
DDRA=(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4)|(0<<PA3)|(0<<PA2)|(0<<PA1)|(0<<PA0);
//ou
DDRA|=(1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4);
DDRA&=~((1<<PA3)|(1<<PA2)|(1<<PA1)|(1<<PA0));

Modifier l'état d'une sortie

Il faut avoir déclarer la broche en sortie, cf ci-dessus !!

Mettre à 0/1

Mettre la broche PC3 à 1 :
PORTC |=  ( 1 << PC3 );
Mettre la broche PE5 à 0 :
PORTE &=~ ( 1 << PE5 );

Exemples

Attention, il vaut mieux mettre quques parenthèses en trop que pas assez !!

...
// mettre la broche PA2 à 1 :
PORTA |= (1<<PA2);
// mettre la broche PB3 à 0 :
PORTB &=~ (1<<PB3);
// changer l'état de la broche PC5 :
PORTC ^= (1<<PC5);
// mettre les broche PB2 et PB3 à 1 :
PORTB |= ( (1<<PB2) | (1<<PB3) );
// mettre les broche PC4 et PC6 à 0 :
PORTC &=~ ( (1<<PC4) | (1<<PC6) );
// mettre à 0 PA0 PA1 PA2 et à 1 PA3 PA4 PA5 PA6 PA7
// !! attention, cela modifie toutes les sorties !!
PORTA = 0b11111000;
// ou
PORTA = (1<<PA7)|(1<<PA6)|(1<<PA5)|(1<<PA4)|(1<<PA3)|(0<<PA2)|(0<<PA1)|(0<<PA0);


Lire l'état d'une entrée

Il faut éventuellement avoir déclarer la broche en entrée, cf ci-dessus !!

Action si 0/1

include <avr/sfr_defs.h>
Action si la broche PC3 à 1 :
if ( bit_is_set(PINC,PC3) )...
Action si broche PE5 à 0 :
if ( bit_is_clear(PINE,PE5) )...

Exemples

Attention, il vaut mieux mettre quques parenthèses en trop que pas assez !!

// si la broche PB2 est à 1 et la broche PD3 est à 0
if ( bit_is_set(PINB,PB2) and bit_is_clear(PIND,PD3) )
{
  // mettre la sortie PE4 à 1
  PORTE |= (1<<PE4);
}
else
{
  // sinon mettre la sortie PE4 à 0
  PORTE &=~ (1<<PE4);
}


Attendre un changement d'état

include <avr/sfr_defs.h>
Attendre que PC3 soit à 1 :
loop_until_bit_is_set(PINC,PC3) ;
Attendre que PE5 soit à 0 :
loop_until_bit_is_clear(PINE,PE5);

Exemples

Attention, il vaut mieux mettre quques parenthèses en trop que pas assez !!

while(1)
{
  //Attendre un front montant sur PD4
  loop_until_bit_is_set(PIND,PD4);
  //changer alors la sortie PD3
  PORTD^=(1<<PD3);
  //Attendre que PD4 repasse à 0 avant de recommencer
  loop_until_bit_is_clear(PIND,PD4);
}


Déclencher une interruption sur changement des entrées

n°interruption

Spécifique à chaque µcontrôleur, en général :

  1. choisir le numéro d'interruption en fonction de la broche
    INT0 INT1 INT2 ...
  2. choisir à quel moment s'exécute l'interruption
    • front montant de l'entrée
    • front descendant de l'entrée
    • changement d'état (tous les fronts)
  3. autoriser l'interruption
  4. écrire la fonction d'interruption

Exemples

pour un atmega328p, INT1 exécutée à chaque changement d'état

cf Cours:Atmega328p#Interruptions pour détails

#include <avr/io.h>
#include <avr/interrupt.h>

ISR(INT1_vect)
{
  // changer l'état de PC3 à chaque interruption
  PORTC ^= (1<<PC3);
}

int main()
{
  // broche en sortie
  DDRC |= (1<<PC3);
  // INT1 sur changement d'état
  EICRA |= (1<<ISC10);
  // autorisation interruption
  EIMSK |= (1<<INT1);
  sei();
  while(1)
  {
  }
}

I2C