Cours:TPS 2103 1 : Différence entre versions
(→{{Rouge|Ex 4: Changement d'état}}) |
(→{{Bleu|ou mieux ...}}) |
||
Ligne 223 : | Ligne 223 : | ||
{{Todo|Commencer par comprendre et exécuter [[Cours:Atmega328p#Exemple|le code donné en exemple]]}} | {{Todo|Commencer par comprendre et exécuter [[Cours:Atmega328p#Exemple|le code donné en exemple]]}} | ||
+ | |||
+ | {{Question|Modifier le programme pour que la led ne change d'état qu'à l'appui sur le bouton poussoir, et non à chaque changement d'état}} | ||
+ | |||
+ | {{Aide|EICRA}} | ||
+ | |||
+ | |||
+ | Il suffit pour cela de choisir le bon mode de déclenchement dans le registre EICRA | ||
+ | {{finAide}} |
Version du 24 mars 2014 à 20:47
Nous avons abordé la programmation des cartes arduino au premier semestre en utilisant des fonctions de haut niveau ce qui, bien que pouvant simplifier certaine tâche, présente un certain nombre de limitation.
L'objectif de ces TPs est de découvrir le fonctionnement du µcontrôleur Atmega328p et d'en explorer les possibilités.
Nous commencerons simplement de façon analogue au premier TP du module M1102 en configurant des e/s (il est sans doute utile de jeter un coup d’œil au lien précédent !).
Sommaire
Ex 1: mise en jambe !
On considère la led f5. La patte correspondante (PB5) sera donc une sortie (commande) pour le µcontrôleur. On configure donc le registre de direction de la façon suivante :
DDRB bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
Valeur | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Compléter le programme suivant pour que la led s'allume et s'éteigne pendant 500ms
Remarque : On utilisera astucieusement l'opérateur ^
void setup()
{
DDRB = 0x?? ; // configuration des e/s (registre de direction DDRx) sur le port D.
}
void loop()
{
PORTB ???? ; // on modifie en conséquence l'état de la sortie
.... // il faudra utiliser la fonction delay !
}
void setup()
{
DDRB = 0x01 ; // configuration des e/s (registre de direction DDRx) sur le port D.
}
void loop()
{
PORTB = 0x00 ; // mise à zéro de la sortie
delay(500);
PORTB = 0x01 ; // mise à un de la sortie
delay(500);
}
|
Ex 2: sans délais ...
Plusieurs leds simultanées
Modifier le programme précédent pour ajouter une deuxième led (f1) s'allumant et s'éteignant au même rythme
Faire un sorte que les 2 leds soient allumées en alternance
Les limites ...
On souhaite avoir 2 rythmes différents pour le clignotement. L'un des leds aura une période de 1s (2x500ms), et l'autre led de 200ms (2x100ms).
On constate aisément que le rapport entre les périodes est de 5, on choisira un "delay" de boucle de 100ms et il suffira de ne changer l'état de la 2ème led que toutes les 5 itérations, suivant le principe suivant :
unsigned char i;
void setup()
{
...
i=0;
}
void loop()
{
i++;
if (i==Nb) // toutes les Nb itérations
{
...
i=0;
}
...
}
Écrire le programme répondant au cahier des charges
Essayer ensuite de modifier le programme pour avoir une période de 225ms pour l'une des leds et 190ms pour l'autre.
Une autre possibilité
Plutôt que d'utiliser des "delay", nous allons utiliser une montre (le temps depuis le démarrage du µcontrôleur en fait).
Le principe est donné dans le programme suivant :
unsigned long dateActuelle, dateModification;void setup()
{
}
void loop()
{
dateActuelle = millis();
if ( (dateActuelle - dateModification) > dureeSouhaitee ) // la condition est vraie si le dernier changement est trop vieux
{
... // on modifie alors les sorties
dateModification=dateActuelle; // et on mémorise l'heure du dernier changement
}
}
Autre explication : Si on lance la cuisson des pâtes à 20h15 et que celle ci dure 10 minutes il faut les sortir à 20h25 !
Sur cette base, écrire un programme répondant à la question précédente.
Ex 3: bouton et led
Nous considérons pour le moment le bouton A et la led de droite (p0).
Complétez le programme suivant pour que la led s'allume si le bouton est appuyé
void setup()
{
DDRD = 0x?? ; // configuration des e/s (registre de direction DDRx) sur le port D.
}
void loop()
{
if ( (PIND & 0x?? ) != 0 ) // on observe l'état de l'entrée
PORTD = 0x??; // on modifie en conséquence l'état de la sortie
else
PORTD = 0x??;
}
Il faut apprendre à debugger un programme. Le plus simple est de se servir de la liaison série : void setup()
{
Serial.begin(9600);
DDRD = 0x?? ; // configuration des e/s (registre de direction DDRx) sur le port D.
}
void loop()
{
unsigned char res;
res = PIND & 0x??;
Serial.print("res = ");
Serial.println(res,BIN);
if ( (res) != 0 )
{
Serial.println("le test est vrai.");
PORTD = 0x??; // on modifie en conséquence l'état de la sortie
}
else
{
Serial.println("le test est faux.");
PORTD = 0x??;
}
delay(200); // indispensable pour ne pas avoir un affichage trop rapide !
}
|
On peut simplifier le programme précédent en utilisant l'opérateur décalage : il suffit de "recopier" l'état du bouton poussoir (PD2) sur la led (PD6) en décalant de 4 bits (PD6-PD2) vers la gauche
void setup()
{
DDRD = 0x?? ; // configuration des e/s (registre de direction DDRx) sur le port D.
}
void loop()
{
PORTD = (PIND&0x??)<<4;
}
Ex 4: Changement d'état
passé et présent
On souhaite maintenant changer l'état de la led (p0) à chaque appui sur le bouton poussoir A (PD2).
On rappelle comme vu en module M1103 que l'une des méthodes repose sur la notion de présent et passé.
Le code suivant (à compléter) répond à ce cahier des charges
char etatPresent=0,etatPasse=0;
unsigned char etatSortie=0;
void setup()
{
DDRD= 0x??; // configuration des e/s
}
void loop()
{
etatPasse=etatPresent;
etatPresent = (PIND & ...)>>2; // 2 valeurs possibles pour etatPresent : 0 ou 1
if ((etatPresent==1)&&(etatPasse==0)) PORTD^=0x??; // modifier la sortie associée à la led p0
}
ou mieux ...
Nous allons utiliser une interruption, dont vous devez comprendre le fonctionnement !
Commencer par comprendre et exécuter le code donné en exemple
Modifier le programme pour que la led ne change d'état qu'à l'appui sur le bouton poussoir, et non à chaque changement d'état
|