====== Utiliser les entrées sorties ======
===== Exemple 1 =====
#include
int main (void)
{
DDRB = 0xFF; //Met le port B en sortie
PORTB = 0x0F; //Met les 4 bit de poids faible à 1 et les 4 bits de poids fort à 0
DDRC = 0x00; //Met le port C en entrée
asm volatile("nop;"); //Necessaire pour la synchronisation lors de la lecture d'une pin - Voir datasheet : I/O Port-Reading the Pin Value
PORTB = PINC; //Copie les niveaux logique du port C sur le port B
return 0;
}
Remarque : DDRx indique la direction de chaque pin (1 : sortie, 0 : entrée) , PORTx sert de registre pour fixer les niveaux logiques en sortie, PINx sert à lire les niveaux logiques en entrée.
{{:avr:winavr:exemple_io.gif|:avr:winavr:exemple_io.gif}}
La valeur de PINC doit être fixée manuellement avant que l'instruction PORTB = PINC; ne soit exécutée.
===== Exemple 2: Les masques =====
#include
int main (void)
{
DDRB = 0xFF; //Met le port B en sortie
PORTB |=(1<<1)|(1<<3)|(1<<5)|(1<<7); //Met les bits 1,3,5,7 à l'état haut
PORTB &=~((1<<3)|(1<<5)); //Met les bits 3 et 5 à l'état bas
DDRB &=~((1<<3)|(1<<5)); //Met les bits 3 et 5 en entrée
return 1;
}
Quand vous faites : PORTB |= X vous faites un OU logique entre X et PORTB ce qui permet de ne pas influer sur l'état précédent des bits de PORTB qui ne sont pas modifiés.
PORTB = 0x0F; // Soit en binaire 0b00001111
PORTB |=(1<<1)|(1<<3)|(1<<5)|(1<<7); //Met les bits 1,3,5,7 à l'état haut
PORTB correspondra à la valeur binaire 0b10101111, les bits 0 et 2 n'ont pas étaient modifiés.
Si par contre vous faites :
PORTB = 0x0F; // Soit en binaire 0b00001111
PORTB =(1<<1)|(1<<3)|(1<<5)|(1<<7); //Met les bits 1,3,5,7 à l'état haut mais met aussi tous les autres bits à 0
PORTB correspondra à la valeur binaire 0b10101010, les bits 0 et 2 ne sont pas conservés mais ca vous fait une instruction en assembleur en moins.\\
Même principe pour "&=".
===== Exemple 3: Utiliser une variable=====
#include
unsigned char port; // Type unsigned char donc sur 8bits comme un port du µC
int main (void)
{
DDRB = 0xFF; //Met le port B en sortie
port=1+2;
PORTB = port;
return 1;
}
===== Exemple 4: Utilisation de _BV()=====
Vous pouvez aussi utiliser _BV() pour mettre à l'état haut un bit particulier.\\
ex : _BV(3) est totalement equivalent à 1<<3
En regardant le code en assembleur on voit bien qu'il n'y a aucune différence :
: PORTB |= _BV(3); //Met le bit 3 à l'état haut
+00000069: 91800038 LDS R24,0x0038 Load direct from data space
+0000006B: 6088 ORI R24,0x08 Logical OR with immediate
+0000006C: 93800038 STS 0x0038,R24 Store direct to data space
: PORTB |= (1<<3); //Met le bit 3 à l'état haut
+00000069: 91800038 LDS R24,0x0038 Load direct from data space
+0000006B: 6088 ORI R24,0x08 Logical OR with immediatespace
+0000006C: 93800038 STS 0x0038,R24 Store direct to data
#include
int main (void)
{
DDRB = 0xFF; //Met le port B en sortie
PORTB |= _BV(1)|_BV(3)|_BV(5)|_BV(7); //Met les bits 1,3,5,7 à l'état haut
PORTB &=~(_BV(3)|_BV(5)); //Met les bits 3 et 5 à l'état bas
return 1;
}
===== Exemple 5: Utilisation de la bibliothèque sbit.h()=====
Cette petite bibliothèque est à télécharger. \\
Son utilisation va permettre de définir un bit d'un port\\
ex : #define LED3 SBIT (PORTA, 3)\\
ex : cette ligne définit que la LED numéro 3 est reliée au bit 3 du registre PORTA\\
ex : #define BP2 SBIT (PIND, 2)\\
ex : cette ligne définit que le bouton poussoir numéro 2 est relié au bit 2 du registre PIND\\
#include
#define LED3 sbit (PORTA, 3)
#define BP2 sbit (PIND, 2)
int main (void)
{
DDRA = 0xFF; //Met le port A en sortie
DDRD = 0x00;
LED3 =1; //Allume la led 3
// teste BP2 et éteint la LED 3
if (BP2 == 1)
{
LED3 =0;
}
return 1;
}