# Micro contrôleurs AVR/Travail pratique/Utilisation du shield LCD keypad

Dans ce TP, nous allons utiliser le shield LCD keypad permettant d'afficher sur un LCD de deux lignes de 16 caractères. L'objectif du TP est de réaliser un réveil. Toute la programmation se fera en C et ne nécessitera aucune librairie extérieure.

## Gestion du LCD

La gestion du LCD se fera à l'aide d'une librairie de très bas niveau écrite par Michel Doussot à laquelle nous avons ajouté quelques fonctions et surtout que nous avons adapté pour l'Arduino UNO.
Voici la librairie :

### Exercice 1

Écrire un programme d'exemple d'utilisation de cette librairie.
Ce programme fonctionne si la librairie donnée est ajoutée avant le main.
Ajouter le code de la librairie de départ avant le main se fera systématiquement dans toute la suite de ce TP même si cela n'est pas rappelé.
Tous les sous-programmes qui vous seront demandés dans la suite auront la même destination.

### Exercice 2

Écrire un sous-programme capable d'afficher un nombre de 8 bits en décimal sur l'afficheur LCD.
Un exemple d'utilisation est :

### Exercice 3

Écrire un sous-programme capable d'afficher un nombre de 8 bits, déjà en format BCD, en décimal sur l'afficheur LCD.
Un exemple d'utilisation est :
qui affichera 78 sur l'écran

### Exercice 4

On vous donne un sous-programme capable de gérer l'incrémentation d'une variable 16 bits en format représentant des heures et minutes.
Essayer ce sous programme et réaliser la décrémentation des heures et minutes sur le même principe. Préparer alors un programme d'affichage des heures et minutes pour un essai.
Un exemple d'utilisation est :

### Ressources

Pour ceux qui désireraient une variation par rapport aux exercices proposés nous proposons quelques sous-programmes à essayer.
Il s'agit d'une incrémentation et décrémentation BCD sur 4 digits (donc 16 bits) :

## Gestion de la conversion analogique numérique

La particularité de ce shield est de proposer une gestion des boutons avec une seule broche de l'ATMega328. Pour réaliser cela, il faut naturellement utiliser une conversion analogique numérique comme nous l'avons déjà présenté dans le chapitre correspondant.

### Exercice 5

On vous demande de préparer un sous-programme capable d'afficher le résultat de la conversion analogique numérique (CAN dans la suite).
Indication : on rappelle que la CAN est sur 10 bits et peut donc retourner un nombre entre 0 et 1023.
L'indication ci-dessus nous explique que pour un nombre sur 10 bits sa valeur décimale peut varier entre 0 et 1023 ce qui fait 4 digits. Il faut donc prévois l'affichage de 4 chiffres sur le LCD.

### Exercice 6

Réaliser la conversion analogique numérique en cherchant comment sont montés les boutons poussoirs. Utiliser le résultat de l'exercice 5 pour faire vos tests. Ce travail doit être séparé en deux sous-programmes :
* un sous programme de configuration du CAN
* un sous-programme de lecture du CAN proprement dit
* Voici maintenant le sous programme de lecture du CAN
* Voici maintenant un programme d'utilisation de tout cela avec affichage de la valeur du CAN

### Exercice 7

Utiliser l'expérimentation de l'exercice 6 pour écrire un programme qui affiche en clair sur le LCD le bouton parmi {SELECT,LEFT,RIGHT,UP,DOWN} qui a été appuyé.
Indications :
* Évidemment ce travail se fait à partir des résultats obtenus dans l'exercice 6. En effet il est possible de calculer des seuils de tension entre les boutons.
* On vous propose d'abord de réaliser une fonction qui retourne un uint8_t avec les valeurs suivantes :
** pas de touche appuyée : valeur 0,
** touche LEFT appuyée, mettre b0 à 1
** touche SELECT appuyée mettre b1 à 1
** touche UP appuyée mettre b2 à 1
** touche DOWN appuyée mettre b3 à 1
** touche RIGHT appuyée mettre b4 à 1
Son prototype est :
et elle retourne l'information d'appui comme ci-dessous, dans une variable 8 bits :
| b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
| 0 | 0 | 0 | RIGHT | DOWN | UP | SELECT | LEFT |
* Réaliser ensuite un sous-programme responsable d'afficher le nom de la touche appuyée.

## Gestion d'un réveil

Nous allons maintenant utiliser les sous-programmes que l'on a réalisé précédemment pour réaliser un réveil. Nous allons commencer par le réglage de l'heure de réveil avec les boutons.

### Exercice 8

Réaliser un réglage de l'heure de réveil avec les deux boutons "UP" et "DOWN".
Indications :
* une vitesse lente peut être réalisée en détectant un appui sur un bouton "UP" ou "DOWN"
* une vitesse plus lente de défilement put être réalisée en restant appuyé sur "UP" ou "DOWN"
* option : envisager un incrément qui augmente en fonction du temps d'appui
Voici une solution partielle :
On commence par le sous-programme responsable de l'affichage de l'heure réveil.
On continue ensuite pour afficher l'heure courante et l'heure réveil en même temps ainsi que la possibilité de régler l'heure réveil.

### Exercice 9

Réaliser un mécanisme d'armement du réveil (avec la touche "SELECT") lui permettant de sonner quand l'heure courante est égale à l'heure réveil.
Indications : comme le montre le dessin, la gestion d'un mécanisme de gestion de sonnerie peut se faire avec 3 états. La terminologie du dessin empruntée d'un wikibook sur VHDL est assez différente de celle de la présente section :
* KEY sera à remplacer par SELECT
* TRIP sera l'égalité entre l'heure courante et l'heure réveil (qui ne dure qu'une minute)
* L'action RING <= '1' déclenche la sonnerie
* On pourra utiliser un type enum pour gérer l'automatisme du réveil :