Je vous propose un petit post concernant l'utilisation d'un écran TFT de 1.8 pouces sous MikroC. C'est un écran que vous pouvez trouver sur Ebay ici par exemple : Ecran TFT 1.8 SPI pour un peu plus de 3 €.
Vous trouverez son datasheet ici : Datasheet
Pour le faire fonctionner, je suis parti d'une librairie existante pour les PIC24 qui utilise le mode software (bit banging pour les intimes ) que l'on peut trouver sur libstock. Je l'ai portée (et j'ai corrigé quelques bugs) pour les PIC18 en mode SPI Hardware.
Pour vous en montrer l'utilisation, nous allons réaliser un thermomètre graphique. Il vous faudra comme matériels : une sonde DS18B20 de Maxim Dallas Datasheet sonde DS18B20, 1 résistance de 47 R, quelques fils, une alimentation en 5 V pour le Vcc et le BL du TFT (penser à mettre les masses en commun) ou un level converter. Pour terminer, de mon coté comme platine de test et programmateur, j'ai pris ma carte Easypic v7. Concernant le PIC, j'ai pris un 18F4620, pour le datasheet, c'est ici : http://ww1.microchip.com/downloads/en/DeviceDoc/39626e.pdf . Je lui ai accouplé un quartz à 20 Mhz.
Passons aux connexions, rien de compliqué :
Comme vous le voyez, avec ce pic en 40 broches, pas mal de broches sont encore libres. Pour les possesseurs de l'Easypic, il faut penser à mettre le jumper de la sonde DS18B20 sur la bonne broche, dans mon cas, j'ai choisi RE2.
En cas de changement du PIC, il faudra penser à connecter les bonnes broches SPI sur l'écran TFT. Ce sont les broches DIN et CLK de l'écran. Sur le datasheet du 18F4620 cela donne ça :
Cela donne coté TFT, la broche CLK relié à RC3 et DIN à RC5 (SPI Data Out du Pic)
Passons maintenant au code source.
Le code source du projet est zippé en pièce jointe à ce post :
Il est composé d'un fichier SPI_TFT.h. Dans ce fichier, vous trouverez les fonctions de bases pour faire fonctionner notre écran TFT. C'est également dans ce fichier que vous pouvez changer les connexions du TFT en ce qui concerne CS, RST, D/C.
Les connexions que j'ai choisies sont pour le Pic 18F4620, vous pouvez les adapter selon vos besoins et votre Pic:
Code : Tout sélectionner
// TFT module connections
sbit TFT_CS at LATC1_bit; //CS => PORTC RC1
sbit TFT_CS_Direction at TRISC1_bit;
sbit TFT_RST at LATC2_bit; //RST => PORTC RC2
sbit TFT_RST_Direction at TRISC2_bit;
sbit TFT_RS at LATC6_bit; //D/C => PORTC6
sbit TFT_RS_Direction at TRISC6_bit;
// End of TFT module connections
Dans ce fichier se trouve aussi la police de texte utilisée dans notre exemple.
Un fichier nommé Fonc_Graph.c. Ce fichier reprend les fonctions utilisées par la librairie. Vous y trouverez aussi les paramètres attendus par la fonction
Un fichier Thermometre_TFT.h qui est le corps du programme
Je vous ai remis les connections en entête pour mémoire :
Code : Tout sélectionner
/* TFT Connections
CLK => PORTC RC3 logique en 3.3 v
DIN => PORTC RC5 logique en 3.3 v
BL => + 5v avec Résistance de 47R
CS => PORTC RC1 logique en 3.3 v
RST => PORTC RC2 logique en 3.3 v
D/C => PORTC6 logique en 3.3 v
GND => GND
VCC => 5V
*/
5 fonctions son créées :
- Une pour formater la température de notre DS18B20 pour notre écran TFT : Display_Temperature()
- Une pour récupérer la température de la sonde : Dallas_Read()
- Une pour créer le squelette de notre thermomètre : Draw_Thermo()
- Une pour mettre à jour le segment qui représente la température pour notre thermomètre : Thermo_Graph()
- La dernière est notre fonction main()
Dans Dallas_Read(), rien d'extraordinaire, je passe donc
Dans Display_Temperature(), nous allons nous attarder un peu sur la fin :
Code : Tout sélectionner
// Convert temp_fraction to characters
DS18B20_Temp[4] = temp_fraction/1000 + 48; // Extract thousands digit
// on applique une résolution à 0.5 près
if (temp_fraction/1000 <5) {
DS18B20_Thermo[2] = 0 +48;
}
else {
DS18B20_Thermo[2] = 5 + 48;
}
Thermo_Temp = atoi(DS18B20_Thermo); //Conversion d'un Char en Int
New_Graph_Value = Thermo_Temp/5;
Display_ASCII8X16(70,70,DS18B20_Temp, WHITE);
}
Dans cette partie, j'affecte une résolution à 0.5°C près, la variable char DS18B20_Thermo contiendra pour 20.5°C la valeur 205.
Valeur que je divise par 5 et convertie en int avec atoi. Cette nouvelle valeur est stockée dans New_Graph_Value pour notre thermomètre graphique.
Code : Tout sélectionner
Thermo_Temp = atoi(DS18B20_Thermo); //Conversion d'un Char en Int
New_Graph_Value = Thermo_Temp/5;
La fonction Draw_Thermo() construit le squelette de notre thermomètre. J'ai placé ici tous les éléments graphiques qui ne changent pas.
La fonction Thermo_Graph() met à jour notre thermomètre. 1 barre de 1 pixel de haut est égale à 0.5°C.
Dans cette fonction, on analyse si l'ancienne valeur est supérieure ou inférieure à l'ancienne.
Après c'est une histoire de pixels, le pixel 0 est en haut à droite, tout en découle :
Code : Tout sélectionner
void Thermo_Graph() {
if (New_Graph_Value > Old_Graph_Value) {
int i;
for (i = (125 - Old_Graph_Value) ; i > (125 - New_Graph_Value); i--) {
fillRect(23, i , 4, 1, RED); //je rajoute un segment rouge
}
Old_Graph_Value = New_Graph_Value; //Mise à jour de Old_Graph_Value lorsque l'on sort de la boucle for
}
if (New_Graph_Value < Old_Graph_Value) {
int i;
for (i = (125 - Old_Graph_Value) ; i < (125 - New_Graph_Value); i++) {
fillRect(23, i , 4, 1, BLACK); //je rajoute un segment noir pour masquer le rouge
}
Old_Graph_Value = New_Graph_Value; //Mise à jour de Old_Graph_Value lorsque l'on sort de la boucle for
}
}
Nous arrivons à la fonction main :
- Configuration des ports du PIC
- Init du SPI et du TFT
- La fonction Draw_Thermo() est volontairement mise ici puisque le squelette du thermomètre n'est jamais mis à jour.
- La boucle while, qui ne contient que le strict minimum :
Code : Tout sélectionner
while(1) {
Display_ASCII8X16(70,70,DS18B20_Temp, BLACK);
Dallas_Read();
Thermo_Graph();
delay_ms(1000);
}
}
Je ne sais pas si vous avez remarqué, la première ligne de la boucle while permet d'effacer l'ancienne valeur en l'écrivant de nouveau mais cette fois çi en noir.
Précisions :
Le thermomètre ne prend pas en compte les valeurs négatives (sauf l'affichage de la température brute) et ne supporte pas les températures supérieures à 50. Si vous souhaitez utiliser ce code pour un thermomètre intérieur, il faut rajouter une condition if dans Thermo_Graph() pour ne mettre à jour que si New_Graph_Value est compris entre 0 et 50.
On peut augmenter l'amplitude en diminuant la résolution.
Le TFT doit être alimenté en 5V (Vcc et BL) mais la logique doit être en 3.3V. Il faut donc programmer son pic en 5V et le passer ensuite en 3.3V. Vous pouvez également intercaler un level converter entre votre PIC et votre TFT.
Les librairies MikroC à inclure dans votre projet sont : Conversions, C-Stdib, C_String, C_Type, One_Wire, SPI.
Si vous souhaitez utiliser cet écran TFT dans un autre projet, il faut enregistrer dans le dossier de votre projet SPI_TFT.h et le fichier Fonc_Graph.c.
Il faut ensuite ajouter ces deux fichiers à votre projet. Pour se faire, allez dans la fenêtre "Project Manager" puis pour ajouter Fonc_Graph.c, clic droit sur sources et choisissez "add Existing file"
Chercher votre fichier et valider par enregistrer.
Pour le fichier SPI_TFT.h, clic droit sur Header files et et choisissez "add Existing file", chercher votre fichier et valider par enregistrer.
Vous devriez obtenir cette arborescence :
Pour les fusibles, pensez à valider l'utilisation d'un quartz externe :
Conclusion :
Ceci est une manière de faire, je pense qu'il y en a d'autres et peut être mieux codées. De la clémence, je suis autoditacte
Voilà un écran pas cher qui permet pas mal de chose (enfin je trouve )
On peut facilement se créer des boutons supplémentaires (du style check button, radio button, etc..)
On a plus de place que sur un écran de 4*20 lignes
On a de la couleur
En espérant que j'aurai été clair, si besoin de précisions, je suis à votre disposition.
Résultat en vidéo :
https://youtu.be/fT2Ri6A5bWk
A ++ Sylvain