Cours:TPS 2103 tp jeuDeMemoire : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
Ligne 1 : Ligne 1 :
 
+
 +
<accesscontrol>Acces:Prof</accesscontrol>
 
[[Cours:TPs_2103|{{Rouge|<big>'''Retour à la liste des Tps'''</big>}}]]
 
[[Cours:TPs_2103|{{Rouge|<big>'''Retour à la liste des Tps'''</big>}}]]
  

Version du 11 juin 2019 à 14:26

Il s’agit d’une page protégée.

Retour à la liste des Tps

Éléments de correction

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!!!!! Alimenter les programmateurs en 3.3V !!!!!

!!!!! pour utiliser les boutons !!!!!

!!!!! Mettre en 5v pour reprogrammer !!!!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


Principe de programmation et fusible

Le µcontrôleur utilisé est un attiny10, cadencé à 1MHz.

Il convient de modifier les fusibles du µcontrôleur (configuration du composant : type d'horloge, mode de programmation, verrouillage ...)

Todo.jpg La valeur du fusible doit être : 0xFE

  • soit graphiquement dans eclipse
  • soit en ligne de commande
avrdude -c avrisp2 -P usb -p t10 -U fuse:w:0xFE:m

Remarques : Une bonne base de programme est donné ci-dessous.

//           +====+
//  PWMA/PB0 |*   | PB3 (RESET)
//       GND |    | Vcc
//  PWMB/PB1 |    | PB2 (CLKO)
//           +====+

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int main(void)
{

  while (1)
  {
  }
}

Explorons les sorties

Schéma électrique

Les schémas suivants vous permettent :

  • de comprendre sur quel état logique les leds s'allument
  • de trouver la liste des sorties
  • d'associer chaque led avec un numéro de patte

Simonsay.png

ATTINY10-pinout.jpg

Le tableau donne la correspondance entre patte de sortie du µcontrôleur et position de(s) led(s) sur le dé :


PB0 haut droite
PB1 haut gauche
PB2 bas gauche
PB3 bas droite

Commandez les sorties

Dans cette partie, on demande à avoir le même état sur toutes les leds (allumées ou éteintes).

Question.jpg Écrire un programme qui change l'état de toutes les leds toutes les secondes.

générons une séquence

L'objectif est d'afficher une séquence sur les leds (led0 puis led3 puis led0 ....), on utilisera un tableau.

Plus le niveau atteint sera élevé, plus la séquence sera longue.

#define niveauMax 10
unsigned char sequence [niveauMax]= {1,3,1,3,2,0...};

Question.jpg Utiliser ce tableau pour allumer successivement les leds dans l'ordre indiqué.

motif gagné

On souhaite générer une séquence particulière lorsque le joueur gagne :

les leds s'allument successivement en "tournant" en rond (on fera plusieurs "tours").

Question.jpg Implémenter la fonction gagne, dont le prototype est donné ci-dessous :

inline void gagne () __attribute__((always_inline));

void gagne()
{
}

motif perdu

On souhaite générer une séquence particulière lorsque le joueur perd :

les leds s'allument toutes puis s'éteignent plusieurs fois.

Question.jpg Implémenter la fonction perdu, dont le prototype est donné ci-dessous :

inline void perdu () __attribute__((always_inline));

void perdu()
{
}

Et l'entrée ?!

Principe

Vous constaterez sur le schéma électrique que les broches du µcontrôleur sont partagées entre bouton et led.

Il faudra donc modifier la valeur du registre DDRB lorsque l'on souhaitera observer l'état des boutons.

On rappelle le rôle du registre PORTx suivant la valeur de DDRx :

état d'un bit de DDRx rôle du bit de PORTx bit de PORTx à '0' bit de PORTx à '1'
'0' Activer/Désactiver la résistance de PULL-UP pas de PULL-UP PULL-UP
'1' Modifier l'état de la sortie sortie à '0' sortie à '1'

Ici, pour que le bouton fonctionne correctement, il ne doit pas y avoir de résistance de PULL-UP activée.

Utilisons les boutons

On souhaite dans un premier temps juste vérifier que les boutons fonctionnent.

Question.jpg Écrire un programme qui attend qu'un bouton soit appuyé et alors affiche le motif "gagné".

Remarques :

  • il est possible que certains boutons ne fonctionnent pas très bien sur le support de programmation !
  • on attendra le relâchement de tous les boutons avant de recommencer.

Associons bouton et led

L'objectif étant de reproduire la séquence générée sur les leds, il convient de regarder lequel des boutons est appuyé.

Une variable bp devra correspondre au numéro du bouton appuyé. Il convient sans doute d'utiliser un "switch case".

Question.jpg Utiliser cette variable ch, et faire clignoter la led associée au bouton sur lequel on appuie.

Jeu de mémoire

Toutes les briques ou presque sont en place. Il ne manque qu'un peu d'aléatoire que nous ajouterons par la suite.

Réexpliquons le principe du jeu :

  • on affiche une séquence aléatoire dont la longueur correspond au niveau
    • une seule led si niveau 1
    • séquence de 2 leds pour le niveau 2
    • séquence de 10 leds pour le niveau 10
  • le joueur doit reproduire la séquence
  • s'il gagne on augmente le niveau
  • s'il perd on recommence au niveau 1

Question.jpg Écrire un programme qui répond à ce cahier des charges

Remarques

  • attention, des boutons peuvent fonctionner difficilement sur le support
  • il faut attendre quelques (30 par ex) ms après appui/relâchement des boutons pour éviter les rebonds (plusieurs appuis)

L'algorithme suivant peut vous aider à écrire votre programme :

  • broches en sortie
  • répéter tout le temps
    • répéter de 0 à niveau
      • allumer la led en fonction du tableau de séquence
      • attendre 500ms
    • broches en entrée pas de pull-up
    • variable sequenceOk à 1
    • répéter de 0 à niveau
      • attendre pas de bouton
      • attendre qques ms
      • attendre appui
      • attendre qques ms
      • trouver valeur de bp
      • si mauvaise touche
        • variable sequenceOk à 0
    • broches en sortie
    • si sequenceOk
      • afficher gagner
      • incrementer niveau
    • sinon
      • afficher perdu
      • mettre niveau à 0
    • attendre 500ms


Un peu de hasard

Il suffit maintenant de choisir de façon aléatoire le numéro de la led au lieu d'avoir une valeur prédéfinie.

On utilisera pour cela le timer, qu'il suffira de démarrer et ensuite de lire sa valeur (avec un modulo !).

Pour information, le TIMER0 est un timer 8 bits.

Le tableau donne les valeurs et modes de comptage suivant l'état des bits CS0(0/1/2) du registre TCCR0B

CS02 CS01 CS00 Mode Fréquence de comptage
0 0 0 Arrêt Sans objet
0 0 1 recopie de l'horloge Fcpt = Fq
0 1 0  %8 Fcpt=Fq/8
0 1 1  %64 Fcpt=Fq/64
1 0 0  %256 Fcpt=Fq/256
1 0 1  %1024 Fcpt=Fq/1024
1 1 0 Externe Comptage sur front montant
1 1 1 Externe Comptage sur front descendant

L'algorithme précédent est modifié de la sorte :

  • lire la valeur du timer (TCNT0)
  • écrire la valeur dans le tableau de séquence
  • afficher la led correspondante

Question.jpg Apporter les modifications à votre programme

Terminé ?

Parfait, vous avez un jeu qui fonctionne. Ne reste plus qu'à limiter la consommation lorsque l'on n'utilise plus le jeu.

Vous vous servirez des fonctions disponibles dans le fichier avr/sleep.h pour passer en économie d'énergie.

Les différents modes sont détaillés Attiny10.pdf dans la partie 7. Le tableau donne la correspondance entre le mode de consommation et la valeur à utiliser dans les fonctions du fichier avr/sleep.h.

Sleep Mode valeur programme c
idle SLEEP_MODE_IDLE
ADC Noise Reduction SLEEP_MODE_ADC
Standby SLEEP_MODE_STANDBY
Power-Down SLEEP_MODE_PWR_DOWN

Vous configurerez l'interruption associée au bouton poussoir, ce qui permettra de sortir du mode faible consommation. Pour gérer cette interruption, vous regarderez la documentation, parties 9.2 et 9.3.

Indication 1 : Cette interruption INT0 est utilisable pour les quatre modes SLEEP_MODE_IDLE, SLEEP_MODE_ADC, SLEEP_MODE_STANDBY et SLEEP_MODE_PWR_DOWN. Mais elle ne fonctionne que sur un changement de niveau pour les trois derniers modes ! Ne cherchez donc pas à détecter un front.

Indication 2 : Le passage en mode économie d'énergie se fait à l'aide de deux instructions :

#include <avr/sleep.h>
....
set_sleep_mode(SLEEP_MODE_IDLE); // sleep mode is set here
sleep_mode(); // le programme s'arrête

Question.jpg Compléter votre programme pour placer votre µcontrôleur dans un mode d'économie d'énergie le plus élevé (plus faible consommation) possible.