Cours:Lo11Final
Gestion du temps par µcontrôleur
Les timers sont des périphériques matériels qui permettent à un µcontrôleur une gestion précise du temps.
Il s'agit tout simplement d'un compteur(avec plus ou moins de fonctions annexes) dont la période de comptage est connue.
Il suffit ensuite de jouer sur les valeurs du compteur pour obtenir le temps souhaité.
Si le µcontrôleur Attiny861 que nous utilisons dispose de timers dans sa version commerciale, ils n'existent pas dans la description matérielle que nous utilisons.
Vous allez donc en créer un de toute pièce, dans une version simplifiée !
Sommaire
Préparation du timer
Le pseudoTimer sera décomposé en plusieurs modules qui sont détaillés ci dessous.
La liste des entrées et sorties de l'entité est donnée ci dessous.
Compteur
Commençons par réaliser un compteur 8 bits avec valeur max (remise à zero lorsque le compteur atteint la valeur max) et signal d'autorisation de comptage en.
library ieee;
use ieee.std_logic_1164.all;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity pseudoTimer is
Port ( clk : in STD_LOGIC;
max : in STD_LOGIC_VECTOR (7 downto 0);
s : out STD_LOGIC);
end pseudoTimer;
architecture Behavioral of pseudoTimer is
signal en : STD_LOGIC;
signal cpt : STD_LOGIC_VECTOR (7 downto 0);
begin
comptage:process(clk,en)
begin
end process comptage;
end Behavioral;
Remarquons que le signal en est un signal interne (qui sera appelé enable dans la suite).
Si vous souhaitez tester le fonctionnement d'une partie avant d'avoir décrit le signal en, il faudra le mettre à '1'.
Décrire le process comptage en implémentant les fonctions valeurs maximum et enable synchone
Prédivision
Limitons maintenant la vitesse de comptage à l'aide du signal enable (qui ne sera donc plus forcé à '1' comme pour le test de la question précédente).
On utilise pour ce faire un prédiviseur de fréquence :
- décrivez un compteur modulo N(en l'occurrence modulo 512)
- le signal enable est à '1' toutes les N (ici 512) périodes d'horloge
- le compteur s'incrémentera donc toutes les 512 périodes d'horloge => Fcomptage=Fclk/512
prediv:process(clk)
begin
end process prediv;
Décrire ce fonctionnement en utilisant le process prediv pour la partie comptage modulo N
Sortie
Le signal de sortie doit tout simplement : changer d'état à chaque débordement (passage à 0) du timer.
Remarque : pensez à utiliser le signal en. (la sortie change d'état à la remise à zéro du timer et si en est actif
Compléter votre programme avec cette sortie
Tests
Vérifier le fonctionnement en utilisant les interrupteurs pour la valeur maximum et B6 comme sortie. Valider le fonctionnement à l'oscilloscope.
la fréquence ( Fs=Fclk/((2*512)*max) varie entre
- Fs=Fclk/((2*512)*256)
- Fs=Fclk/((2*512))
Ajoutons le au µcontrôleur
Registre SFR
On ajoute un registre SFR dans le µcontrôleur qui permettra de modifier la valeur maximale de comptage du TIMER.
On utilisera le nom MAXT à l'adresse 0x02
On ajoutera bien évidemment le code nécessaire notamment dans le process iowr
Faire ces modifications et compiler
Utilisons ce module
Ecrire un programme qui fait varier la valeur maximum du timer toute les 100ms.
#include "avr/io.h"
....
int main(void)
{
....
}
Notes de musique
Le buzzer que nous utilisons et capable de jouer les notes suivantes :
Touche | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | * | # |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Note | Do | Do# | Ré | Ré# | Mi | Fa | Fa# | Sol | Sol# | La | La# | Si |
Fréquence (Hz) | 261,63 | 277,18 | 293,66 | 311,13 | 329,63 | 349,23 | 369,99 | 392 | 415,3 | 440 | 466,16 | 493,88 |
Période (µs) | 3822 | 3608 | 3405 | 3214 | 3037 | 2863 | 2703 | 2551 | 2408 | 2273 | 2145 | 2025 |
Bien entendu, à chaque note correspondra une valeur maximum du timer.
Déclarer un tableau avec la valeur maximum associée à chaque note
Utiliser ce tableau pour jouer une mélodie
#include "avr/io.h"
....
#define Do 0
#define Dod 1
#define Re 2
#define Red 3
#define Mi 4
#define Fa 5
#define Fad 6
#define Sol 7
#define Sold 8
#define La 9
#define Lad 10
#define Si 11
#define Noire 200
uint8_t tabNotes[12]={....}; // valeur maximale du timer pour jouer une note donnée
Éventuellement, vous pouvez jouer une mélodie en définissant un tableau de notes. Il suffit ensuite de parcourir ce tableau :
// durée des notes en ms
#define blanche 1000
#define noire 500
#define croche 250
#define nbNotes 10
notes melodie[nbNotes]={Do,Do,Re,Re,Do,Do,Mi,Do,Do,Mi};
int durees[nbNotes]={blanche,noire,noire,noire,noire,noire,noire,noire,noire,noire};