Hello,
Pour m'amuser, je fais joujou avec du C++ sur un MCU 16 bits avec 16k bytes de ROM et 500 bytes de RAM. En ce moment, je gère un LCD avec deux lignes de 16 caractères, comme ceux gérer par CrystalLiquid d'Arduino. Ces écrans ont deux modes, un avec une interface 8 bits, l'autre avec une interface 4 bits. J'ai commencé par la version 8 bits et je suis arrivé à une classe LCD donc le listing des fonctions peut se résumer à ça :
init() est une succession d'appels à writeCommand(), c'est une fonction d'assez haut niveau. writeCommand() et writeData() sont très semblables, sont des fonctions de niveau intermédiaire, et elles font toutes les deux appel à setRegisterSelect(), pulseEnable() et write(). Ces 3 dernières fonctions sont des fonctions de bas niveau, en faisant bouger des GPIO sur MCU.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 void init(); void writeCommand(uint8_t command); void writeData(uint8_t data); void setRegisterSelect(RegisterSelect selection); void pulseEnable(); void write(uint8_t value);
J'aimerais maintenant passer en mode 4 bits, ce qui me permet d'économiser 4 GPIOs et sur un MCU avec 20 pins, c'est énorme.
Mon idée était de passer init() en paramètre du constructeur du LCD, mais il fait appel à des méthodes de la classe, ce n'est pas pratique. Comme il n'existe que 2 initialisations possibles, je me suis dit que je pouvais gérer ça facilement avec un constructeur prenant en paramètre le mode (4 ou 8 bits) et fait un simple if / else dans init().
write() écrit 8 bits (sur 8 GPIOs d'un coup) et pour gérer le mode 4 bits, il me faut aussi une fonction write4bits(), mais ça ne change pas fondamentalement mon problème que je vais enfin vous exposer
Mon problème est que j'aimerai ben extraire ces 3 (ou 4) fonctions de bas niveau de ma classe LCD puisque leur implémentation varie considérablement en fonction de la manière donc l'écran est raccordé au MCU. J'ai un temps pensé à extraire ça dans une classe LCDLowLevel et donner à manger à LCD une référence vers une instance de LCDLowLevel. Sauf que dés que j'utilise de la virtualité, le linker me dit que je n'ai pas assez de place en ROM. Visiblement, la virtualité semble coûter 15k...
Une classe LCD template parait tentant, mais comme tout template, je ne peux plus passer de LCD en paramètre d'une fonction, puisque ce sera LCD<truc>...
Ma dernière solution est de ne pas implémenter ces 3 (ou 4) fonctions mais de laisser leurs déclarations dans ma classe et dans chaque projet où j'utiliserai cette classe / bibliothèque LCD, j'implémenterai différemment ces fonctions.Ce n'est pas très C++esque, mais ça marche bien ^^
Au final, je me demandais si vous aviez d'autres idées sur la questions
Mârchi !
Bktero
Partager