Table des matières

Utiliser les entrées sorties

Exemple 1

#include <avr/io.h>
 
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

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 <avr/io.h>
 
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 <avr/io.h>
 
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 <avr/io.h>
 
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 <util/sbit.h>
 
#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;
}