From e931eb2b9d373fa6c49d0dcfc9444c80045c5a44 Mon Sep 17 00:00:00 2001 From: Geoffrey Frogeye Date: Mon, 22 May 2017 18:38:46 +0200 Subject: [PATCH] Réorganisation du CR --- CR.md | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------- 1 file changed, 77 insertions(+), 75 deletions(-) diff --git a/CR.md b/CR.md index 27171f5..f9f0426 100644 --- a/CR.md +++ b/CR.md @@ -116,6 +116,83 @@ En effet, nous avons dit précédemment que pour économiser l'énergie, toutes L'algorithme étant assez lourd et redondant, on ne présentera que les principes clefs et quelques exemples d'astuces utilisés. Le code complet (et les outils utilisés pour l'ensemble du projet) sont disponibles à l'adresse suivante : (`Files` > `principal.txt`). +## Interruptions + +Les fonctions que nous avons vues jusqu'à lors sont appelées uniquement par les interruptions, étant donné qu'il n'y a pas de programme principal. Voici les différentes interruptions qui sont déclenchées. + +### Timer + +Déclenchée toutes les ~4 ms, elle change le digit de l'afficheur 4 × 7 segments actuellement affiché en modifiant la configuration du port C, et cenvoie sur le port A les données du registre `dX` correspondant. + +```avrasmplus +timer: + ; Notre composant requiert d'envoyer 0 sur PC7-4 + ; afin d'activer le digit qui y est connecté + + ; Affiche le digit suivant sur l'afficheur 7seg + temp <- PORTC@IO ; On lis l'état précédent du port + lsr temp ; On change de digit + ; Il y a 4 digits et 8 bits, on doit donc boucler plus tôt + si temp < 0b00001111 alors temp <- 0b11110111 + PORTC@IO <- temp + ; On envoie le registre correpspondant + si temp = 0b11110111 alors PORTA@IO <- d3 + si temp = 0b01111011 alors PORTA@IO <- d2 + si temp = 0b00111101 alors PORTA@IO <- d1 + si temp = 0b00011110 alors PORTA@IO <- d0 +``` + +### Watchdog + +Le watchdog ne fonctionnant pas, nous avons utilisé le timer, et un registre supplémentaire, `tt`, qui est incrémenté à chacune de ses interruptions. Le timer ayant une fréquence exacte de $\frac{16 MHz}{256^2}=244.140625 Hz$, dès que `tt` a depassé `244` on appelle donc `agir1s`. + +D'un point de vue énergétique, cette approche est beacoup moins efficace car elle rajoute des instructions supplémentaires à l'interruption du timer, qui est la fonction « critique » du système car appelée 244 fois par seconde. + +### ADC + +Cette interruption est déclenchée à chaque fois qu'une conversion analogique→numérique est terminée. Elle est donc déclenchée à peu près toutes les 10 secondes car les conversions ne sont demandées que depuis la fonction `agir10s`. Elle s'occupe d'activer ou de désactiver la chaudière en fonction de la température récupérée lors de la conversion, en se basant sur le registre `reference`. Par exemple, la chaudière est éteinte si la température dépasse de plus de 0,5 degrés la température de référence. Dans le code, on vérifiera si `ADCH > reference + 5`, car 0,1°C correspond à une unité. On remarque que l'on peut obtenir un dépassement si jamais `reference > 250`, ce qui n'est pas censé arriver car on ne propose à l'utilisateur que de choisir une température entre 5,5 et 30,0°C, `reference` est donc compris entre 5 et 250. Si jamais la température est comprise dans l'intervalle, le port G conserve l'état de la chaudière actuel. + +*Note : Vous pourrez constater dans le code que cette interruption en déclenche une autre afin d'avoir un retour immédiat sur nos actions. Cela n'a été fait que pour simplifier la présentation orale.* + +### Boutons + +À chaque bouton est associé une interruption, et chacun d'entre elle appelle une fonction d'état selon la valeur actuelle de compteur. Par exemple, si l'état actuel est `veilleHeure` et que le bouton Valider est pressé, la fonction `etatMenuAssoc` est appelée. Pour les boutons Incrémenter et Décrémenter, le registre `compteur` est incrémenté ou décrémenté respectivement avant d'appeler la fonction d'état. + +Voici par exemple la fonction appelée par le bouton Incrémenter : + +```avrasmplus +incrementer: + inc compteur + si etat = 0 saut etatVeilleTemp + si etat = 1 saut etatVeilleHeur + si etat = 2 saut etatMenuTJour + si etat <= 9 saut etatMenuJoursC + si etat <= 16 saut etatParaJoursC + si etat = 17 saut etatMenuTNuit + si etat = 18 saut etatParaTJourC + si etat = 19 saut etatMenuHorloge + si etat = 20 saut etatParaTNuitC + si etat = 21 saut etatMenuAssoc + si etat = 22 saut etatMenuHHeur + si etat = 23 saut etatMenuHMinu + si etat = 24 saut etatMenuHJour + si etat = 25 saut etatParaHJourC + si etat = 26 saut etatParaHHeurC + si etat = 27 saut etatParaHMinuC + reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts +``` + +## Fonction d'agissement + +Ces fonctions permettent de réaliser des actions en fonction du temps. + +- `agir1s` : déclenchée toutes les secondes, elle met à jour les registres de temps, et appelle les fonctions `agir10s` et `agirHeure` +- `agir10s` : déclenchée toutes les dix secondes, elle change l'état de veille (affichage de l'heure ou température) si l'appareil est en veille. Dans tous les cas, elle déclenche une conversion analogique numérique pour lire le capteur de température. +- `agirHeure` : elle recharge depuis la RAM le mode actuel, et met à jour le registre `reference` contenant la température à utiliser. + +*Note : On a laissé la possibilité à l'utilisateur de changer de mode de veille avec les boutons Incrémenter / Décrémenter, mais `agir10s` ne prend pas en compte ce changement. Il est donc possible que l'utilisateur change d'état de veille et que le système revienne juste après à l'état précédent.* + + ## Gestion des états Chacun des boutons provoque une interruption qui modifie l'affichage et les valeurs nécessaires en fonction de celui qui a été appuyé et de l'état précédent du menu. Il faut alors stocker dans quel état est le menu en mémoire. On utilisera pour cela un registre `etat`, qui prendra les valeurs suivantes : @@ -204,81 +281,6 @@ boundHeur: On utilise le fait qu'une décrémentation depuis la valeur 0 effectue un dépassement et remet le registre à 255. On aurait pas pu utiliser le flag indiquant qu'un dépassement a eu lieu car l'incrémentation / la décrémentation de compteur s'effectue beaucoup plus tôt que la remise en borne. Pour faciliter la vie de l'utilisateur, lorsque l'on dépasse une des deux bornes, la valeur prend la borne opposée. -## Fonction d'agissement - -Ces fonctions permettent de réaliser des actions en fonction du temps. - -- `agir1s` : déclenchée toutes les secondes, elle met à jour les registres de temps, et appelle les fonctions `agir10s` et `agirHeure` -- `agir10s` : déclenchée toutes les dix secondes, elle change l'état de veille (affichage de l'heure ou température) si l'appareil est en veille. Dans tous les cas, elle déclenche une conversion analogique numérique pour lire le capteur de température. -- `agirHeure` : elle recharge depuis la RAM le mode actuel, et met à jour le registre `reference` contenant la température à utiliser. - -*Note : On a laissé la possibilité à l'utilisateur de changer de mode de veille avec les boutons Incrémenter / Décrémenter, mais `agir10s` ne prend pas en compte ce changement. Il est donc possible que l'utilisateur change d'état de veille et que le système revienne juste après à l'état précédent.* - -## Interruptions - -Les fonctions que nous avons vues jusqu'à lors sont appelées uniquement par les interruptions, étant donné qu'il n'y a pas de programme principal. Voici les différentes interruptions qui sont déclenchées. - -### Timer - -Déclenchée toutes les ~4 ms, elle change le digit de l'afficheur 4 × 7 segments actuellement affiché en modifiant la configuration du port C, et cenvoie sur le port A les données du registre `dX` correspondant. - -```avrasmplus -timer: - ; Notre composant requiert d'envoyer 0 sur PC7-4 - ; afin d'activer le digit qui y est connecté - - ; Affiche le digit suivant sur l'afficheur 7seg - temp <- PORTC@IO ; On lis l'état précédent du port - lsr temp ; On change de digit - ; Il y a 4 digits et 8 bits, on doit donc boucler plus tôt - si temp < 0b00001111 alors temp <- 0b11110111 - PORTC@IO <- temp - ; On envoie le registre correpspondant - si temp = 0b11110111 alors PORTA@IO <- d3 - si temp = 0b01111011 alors PORTA@IO <- d2 - si temp = 0b00111101 alors PORTA@IO <- d1 - si temp = 0b00011110 alors PORTA@IO <- d0 -``` - -### Watchdog - -Le watchdog ne fonctionnant pas, nous avons utilisé le timer, et un registre supplémentaire, `tt`, qui est incrémenté à chacune de ses interruptions. Le timer ayant une fréquence exacte de $\frac{16 MHz}{256^2}=244.140625 Hz$, dès que `tt` a depassé `244` on appelle donc `agir1s`. - -D'un point de vue énergétique, cette approche est beacoup moins efficace car elle rajoute des instructions supplémentaires à l'interruption du timer, qui est la fonction « critique » du système car appelée 244 fois par seconde. - -### ADC - -Cette interruption est déclenchée à chaque fois qu'une conversion analogique→numérique est terminée. Elle est donc déclenchée à peu près toutes les 10 secondes car les conversions ne sont demandées que depuis la fonction `agir10s`. Elle s'occupe d'activer ou de désactiver la chaudière en fonction de la température récupérée lors de la conversion, en se basant sur le registre `reference`. Par exemple, la chaudière est éteinte si la température dépasse de plus de 0,5 degrés la température de référence. Dans le code, on vérifiera si `ADCH > reference + 5`, car 0,1°C correspond à une unité. On remarque que l'on peut obtenir un dépassement si jamais `reference > 250`, ce qui n'est pas censé arriver car on ne propose à l'utilisateur que de choisir une température entre 5,5 et 30,0°C, `reference` est donc compris entre 5 et 250. Si jamais la température est comprise dans l'intervalle, le port G conserve l'état de la chaudière actuel. - -*Note : Vous pourrez constater dans le code que cette interruption en déclenche une autre afin d'avoir un retour immédiat sur nos actions. Cela n'a été fait que pour simplifier la présentation orale.* - -### Boutons - -À chaque bouton est associé une interruption, et chacun d'entre elle appelle une fonction d'état selon la valeur actuelle de compteur. Par exemple, si l'état actuel est `veilleHeure` et que le bouton Valider est pressé, la fonction `etatMenuAssoc` est appelée. Pour les boutons Incrémenter et Décrémenter, le registre `compteur` est incrémenté ou décrémenté respectivement avant d'appeler la fonction d'état. - -Voici par exemple la fonction appelée par le bouton Incrémenter : - -```avrasmplus -incrementer: - inc compteur - si etat = 0 saut etatVeilleTemp - si etat = 1 saut etatVeilleHeur - si etat = 2 saut etatMenuTJour - si etat <= 9 saut etatMenuJoursC - si etat <= 16 saut etatParaJoursC - si etat = 17 saut etatMenuTNuit - si etat = 18 saut etatParaTJourC - si etat = 19 saut etatMenuHorloge - si etat = 20 saut etatParaTNuitC - si etat = 21 saut etatMenuAssoc - si etat = 22 saut etatMenuHHeur - si etat = 23 saut etatMenuHMinu - si etat = 24 saut etatMenuHJour - si etat = 25 saut etatParaHJourC - si etat = 26 saut etatParaHHeurC - si etat = 27 saut etatParaHMinuC - reti ; Ne devrait pas arriver, mais permet d'éviter les dégâts -``` # Conclusion -- libgit2 0.21.2