Cours:TPS 2103 tp deElec

De troyesGEII
Aller à : navigation, rechercher

Éléments de correction du dé


Principe de programmation

Nous utiliserons toujours eclipse pour programmer le dé électronique. Si pour une raison quelconque vous rencontrez des problèmes avec Eclipse, il est possible de travailler directement en ligne de commandes :

avr-gcc -Wall -g -Os -mmcu=attiny10 -o test.o test.c
avr-objcopy -j .text -j .data -O ihex  test.o test.hex
avrdude -c avrisp2 -P usb -p t10 -U flash:w:"test.hex"

Si vous avez besoin de modifier les fusibles, la commande avrdude sera :

avrdude -c avrisp2 -P usb -p t10 -U fuse:w:0xFE:m -U flash:w:"ProgDe.hex"

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 ...)

La valeur du fusible doit être : 0xFE

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

SchemaDe.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 PB1
PB3 PB2 PB3
PB1 PB0

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.

Valeurs du dé

L'objectif étant de réaliser un dé électronique, il s'agit désormais d'afficher sur les leds les valeurs possibles ( de 1à 6 !) et également de prévoir un cas dans lequel aucune led n'est allumée.

Vous utiliserez donc un tableau permettant le transcode comme suit :

unsigned char etatLeds [7]= { ... };

Question.jpg Écrire un programme qui utilisera ce tableau et représentera successivement les nombres de 1 à 6 puis éteindra toutes les leds pendant 3s avant de recommencer.

Et l'entrée ?!

Principe

Vous constaterez sur le schéma électrique que la seule interaction disponible avec l'utilisateur est un bouton, qui est partagé avec une led.

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

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 le bouton

Nous allons remplacer le "delay" utilisé dans le programme précédent (qui permettait de rythmer le comptage) par le bouton :

A chaque appui sur le bouton, la valeur doit augmenter.

Vous allez vous appuyer sur l'algorithme suivant dans un "main()" :

  • initialisation
  • boucle infinie
    • passer PB2 en entrée sans pullup SVP
    • attendre 1 ms
    • si bouton appuyé (PB2 à l'état 1 !!)
      • boucle qui attend le relâchement (autrement dit : tant que le bouton est appuyé ne rien faire)
      • incrémenter i mais pas n'importe comment
    • On revient avec PB3..PB0 en sortie
    • attente d'une ms
    • on sort l'affichage du dé
    • attente de 10 ms
  • fin boucle infinie


Question.jpg Écrire le programme correspondant

Un peu de hasard

Principe et Timer0

Un dé électronique doit permettre d'obtenir une valeur aléatoire à chaque nouveau lancé. Le plus simple est de mesurer un événement extérieur (donc une grandeur physique caractérisant cet événement).

Nous allons utiliser ce principe en utilisant la durée d'appui sur le bouton par l'utilisateur:

  • A l'appui sur le bouton, on met en route le TIMER0 (choix d'une valeur de prédiviseur)
  • On arrête le TIMER au relâchement du bouton
  • On récupère la valeur du TIMER0 grâce au registre TCNT0

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

Mise en œuvre

Question.jpg Faire un programme qui utilise ce principe pour qu'à chaque appui sur le bouton, un nouveau nombre aléatoire soit généré.


Quelques améliorations

Question.jpg Améliorer l'utilisation du dé électronique en :

  • éteignant les leds au bout de 10s
  • faisant clignoter les leds (par exemple) tant que le bouton est appuyé

Consommation

Principe

Afin de limiter la consommation de la carte, nous allons utiliser les modes d'économie d'énergie disponibles sur le µcontrôleur utilisé.

Le principe sera le suivant :

  1. On place le µcontrôleur dans le mode d'économie d'énergie choisi -> le programme s'arrête et il faut un événement pour sortir de ce mode faible consommation
  2. Le bouton déclenche une interruption externe permettant de sortir du mode d'économie d'énergie
  3. On affiche un nombre aléatoire
  4. Retour au mode faible consommation après quelques secondes

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

Mise en œuvre

Question.jpg Utilisez ce mode faible consommation tel que décrit précédemment.