Comment écrire un menu LCD pour AVR

Détecteurs, alarmes, etcs...
Répondre
Avatar du membre
Doc
Site Admin
Messages : 211
Enregistré le : 21 avr. 2021, 00:14
Localisation : Partout où le vent me porte

Comment écrire un menu LCD pour AVR

Message par Doc »

Cours & Explications :
Source : scienceprog

Comment écrire un menu LCD pour AVR en C
Pour Microcontrôleurs AVR
( Comme pour le TRITON sous ATMEGA8-16 )

Écrivons un menu LCD simple pour AVR.
J'utilise quatre boutons : 2 pour faire défiler le menu vers le haut et vers le bas et deux pour modifier les paramètres du sous-menu.

Comme indicateur de sortie, j'utilise trois LED qui clignotent selon les paramètres du menu. Les états des boutons sont capturés à l'aide des interruptions de débordement timer0.
5BBC2B99-DCF5-4FFF-950C-777CEA5242FB.png
5BBC2B99-DCF5-4FFF-950C-777CEA5242FB.png (12.91 Kio) Vu 741 fois
Le circuit est élémentaire :

Circuit LCD AVR avec boutons et LED

J'ai exclu le circuit d'alimentation pour plus de simplicité, juste laissé les pièces principales : LCD, LED,etboutons. Ce circuit fonctionne bien avec le simulateur Proteus tel quel. Le circuit

Proteus est attaché à l'archive du projet.

Mon idée est de stocker les chaînes de menu dans la mémoire Flash sans occuper la RAM MCU. De cette façon, les éléments de menu ne sont limités que par la mémoire Flash, pas par la RAM.

Comme vous pouvez le voir dans le code, la structure du menu est simple et il existe de nombreuses façons de l'optimiser. Sentez-vous à l'aise de le faire.
Tout d'abord, décidons du nombre d'éléments de menu que nous allons avoir. Selon mon exemple, il y a quatre éléments de menu :

//Menu Strings in flash
//menu 1
const uint8_t MN100[] PROGMEM="<<One Led>>\0";
//menu 2
const uint8_t MN200[] PROGMEM="<<All ON/OFF>>\0";
//menu 3
const uint8_t MN300[] PROGMEM="<<Auto scroll>>\0";
//menu 4
const uint8_t MN400[] PROGMEM="<<Blink All>>\0";
Ensuite, nous devons décrire les sous-menus :

//SubMenu Strings in flash
//menu 1 submenus
const uint8_t MN101[] PROGMEM="R ON\0";
const uint8_t MN102[] PROGMEM="G ON\0";
const uint8_t MN103[] PROGMEM="B ON\0";
//Submenus of menu 2
const uint8_t MN201[] PROGMEM="All ON\0";
const uint8_t MN202[] PROGMEM="All OFF\0";
//Submenus of menu 3
const uint8_t MN301[] PROGMEM="Left\0";
const uint8_t MN302[] PROGMEM="Right\0";
//submenus of menu 4
const uint8_t MN401[] PROGMEM="Blink Fast\0";
const uint8_t MN402[] PROGMEM="Blink Slow\0";
Ensuite, nous créons des pointeurs de tableau vers des chaînes de menu stockées en un éclair :

const uint8_t *MENU[] ={
MN100, //menu 1 string
MN200, //menu 2 string
MN300, //menu 3 string
MN400 //menu 4 string
//add more if more menu items are used
};
const uint8_t *SUBMENU[] ={
MN101, MN102, MN103, //submenus of menu 1
MN201, MN202, //submenus of menu 2
MN301, MN302, //submenus of menu 3
MN401, MN402 //submenus of menu 4
//continue with other menu submenu strings
};
Ces pointeurs sont utilisés pour appeler la chaîne de menu lorsque l'élément de menu/sous-menu est modifié.

Ensuite, nous devons décrire la structure du menu avec des constantes numériques indiquant le nombre de menus et d'éléments de sous-menu :

const uint8_t MSTR2[] PROGMEM ={
4, //number of menu items
3, //Number of submenu items of menu item 1
2, //of menu item 2
2, //of menu item 3
2 //of menu item 4
//enter further submenu items
};
Ce tableau est également stocké dans la mémoire Flash .

La dernière chose sont les fonctions. J'ai utilisé le pointeur pour fonctionner avec des noms similaires :

//Functions for each menu item
void func101(void);
void func102(void);
void func103(void);
void func201(void);
void func202(void);
void func301(void);
void func302(void);
void func401(void);
void func402(void);
//...add more functions if more menu items are used
Il est facile d'utiliser un pointeur de fonction, qui peut être modifié lors du changement d'élément de menu. Pour rendre les choses plus faciles à gérer, j'ai créé un tableau de pointeurs de fonction dans Flash

const FuncPtr FuncPtrTable[] PROGMEM=
{ func101, func102, func103, //functions for submenus of menu 1
func201, func202, //functions for submenus of menu 2
func301, func302, //functions for submenus of menu 3
func401, func402 //functions for submenus of menu 4
//further functions...
};
En utilisant ce tableau de fonctions, je peux facilement pointer vers la fonction requise avec une seule ligne de code :

FPtr=(FuncPtr)pgm_read_word(&FuncPtrTable[MFIndex(MN.menuNo, MN.subMenuNo)]);
La fonction MFIndex(MN.menuNo, MN.subMenuNo) renvoie l'index du tableau en fonction du numéro de menu et de sous-menu.

Téléchargez les fichiers de projet (avec hexadécimal pré-compilé) et le modèle Proteus ici
LCD_menu.zip
(33.1 Kio) Téléchargé 185 fois
Image
Adhérant à la Fédération Française de Détection de Métaux - GECKO - TRITON - XP DEUS - ORX - TEKNETICS - GARRETT - QUEST - Lézard Magnétomètre - CRIQUET PI -
Répondre