0% ont trouvé ce document utile (0 vote)
4 vues2 pages

31 Programmation Machine Etat

Le document explique comment programmer une machine d'état en C en utilisant des structures de contrôle pour représenter un graphe d'état. Il présente deux approches : la première utilise des boucles while pour gérer les états, tandis que la seconde, plus lisible, utilise une instruction switch pour chaque état avec des transitions basées sur des conditions logiques. La programmation d'une machine d'état est simplifiée en utilisant des variables pour mémoriser l'état du système.

Transféré par

akamourshop
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
4 vues2 pages

31 Programmation Machine Etat

Le document explique comment programmer une machine d'état en C en utilisant des structures de contrôle pour représenter un graphe d'état. Il présente deux approches : la première utilise des boucles while pour gérer les états, tandis que la seconde, plus lisible, utilise une instruction switch pour chaque état avec des transitions basées sur des conditions logiques. La programmation d'une machine d'état est simplifiée en utilisant des variables pour mémoriser l'état du système.

Transféré par

akamourshop
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Programmation d'une machine d'état en C

Les structures de contrôle d'un langage de programmation, telles que les if et les while, permettent
d'écrire un programme dont le fonctionnement est décrit par un graphe d'état. Reprenons l'exemple
simple de la perceuse semi-automatique, dont voici le graphe d'état :

Arrêt
0 0
Start
Haut

Montée Bas Descente


1 0 0 1

L'organigramme suivant réalise la machine d'état.

Le programme correspondant en C est très simple:


Initialisations
#include <avr/io.h>
int main() {
Avance=0, Recule=0 PORTB|=(1<<PB0)|(1<<PB1)|(1<<PB2);
DDRC|=(1<<PC5)|(1<<PC4);
while(1) {
Start PORTC&=~((1<<PC5)|(1<<PC4);
while(PINB&(1<<PB0));
PORTC|=(1<<PC5);
Avance=1, Recule=0
while(PINB&(1<<PB1));
PORTC&=(1<<PC5);
PORTC|=(1<<PC4);
Bas while(PINB&(1<<PB2));
}
}
Avance=0, Recule=1
Avec cette manière de procéder, l'état du système est
en fait mémorisé dans le compteur ordinal
Haut (PC=programm counter) du processeur. Par exemple,
l'état descente correspond à l'exécution des instructions
liées aux troisième while du programme. Il faut bien
noter que dans ce programme, le boucle infinie
while(1) correspond au parcours complet du graphe d'état.

Lorsqu'un graphe d'état devient complexe, il devient très vite compliqué de trouver l'organigramme
et d'écrire le programme correspondant. De plus, une petite modification du graphe d'état peut avoir
une grande incidence sur le programme. On préfèrera alors utiliser une technique très simple,
utilisant une variable pour mémoriser l'état du système. Dans notre exemple, voici le programme
correspondant. Seule la partie principale du programme est présentée:
char etat = 0;
while (1) {
switch (etat) {
case 0: PORTC&=~((1<<PC5)|(1<<PC4));
if (!(PINB&(1<<PB0))) etat = 1; break;
case 1: PORTC&=~(1<<PC4); PORTC|=(1<<PC5);
if (!(PINB&(1<<PB1))) etat = 2; break;
case 2: PORTC&=~(1<<PC5); PORTC|=(1<<PC4);
if (!(PINB&(1<<PB2))) etat = 0; break;
}
}
On notera que, contrairement au programme précédent, aucune boucle while ne se trouve à
l'intérieur de la boucle infinie while(1). Cela signifie que cette boucle s'exécute un très grand
nombre de fois par seconde (quelques centaine de milliers avec un processeur AVR à 8 MHz).
Marche à suivre : La programmation d'une machine d'état, à partir d'un graphe d'état même très
compliqué, peut s'écrire de la manière suivante:
- après les initialisations (direction des ports, pull-up, etc), une boucle infinie while(1) contient
une instruction switch avec un case correspondant à chaque état.
- dans chaque case, on programme les valeurs des sorties du système associés à cet état.
- chaque transition partant d'un état est ensuite réalisée en plaçant dans le case correspondant une
instruction if avec la condition logique sur les entrées associées à cette transition, suivie de
l'assignation de la variable etat avec sa nouvelle valeur.
La lisibilité des programmes présentés n'est pas bonne. En effet, l'utilisation directe des ports
d'entrée et de sortie rend la lecture difficile. Voici le même programme, qui produira le même code,
mais écrit de manière plus lisible:
#define PinStart PINB
#define BitStart PB0
#define PullUpStart PORTB
#define PinBas PINB
#define BitBas PB1
#define PullUpBas PORTB
#define PinHaut PINB
#define BitHaut PB2
#define PullUpHaut PORTB
#define PortAvance PORTC
#define BitAvance PC5
#define DdrAvance DDRC
#define PortRecule PORTC
#define BitRecule PC4
#define DdrRecule DDRC
enum {Arret, Descente, Montee};
int main() {
PullUpStart|=(1<<BitStart); PullUpBas|=(1<<BitBas);
PullUpHaut=(1<<BitHaut);
DdrAvance|=(1<<BitAvance); DdrRecule|=(1<<BitRecule);
char etat = Arret;
while (1) {
switch (etat) {
case 0: PortAvance&=~(1<<BitAvance); PortRecule&=~(1<<BitRecule);
if (!(PinStart&(1<<BitStart))) etat = Descente; break;
case 1: PortRecule&=~(1<<BitRecule); PortAvance|=(1<<BitAvance);
if (!(PinBas&(1<<BitBas))) etat = Montee; break;
case 2: PortAvance&=~(1<<BitAvance); PortRecule|=(1<<BitRecule);
if (!(PinHaut&(1<<BitHaut))) etat = Arret; break;
}
}
}

Vous aimerez peut-être aussi