Pour effacer l'écran, il faut le remplir de 0 tout simplement.
-----
Pour effacer l'écran, il faut le remplir de 0 tout simplement.
J'ai essayé de lancer une séquence de reset en début d'initialisation mais toujours pareil...
Code:#DEFINE RESAFF PORTC,0 ; Horloge
Code:bsf RESAFF call Tempo100us bcf RESAFF call Tempo100us bsf RESAFF
Oui c'est ce que je m'étais dit pour effacer l'écran. Je me demandais juste si on ne pouvait pas se servir du display clear mais apparemment non
Je vais faire un bout de code qui va s'en charger
Il me reste encore un souci sur l'adressage de la SGRAM...
Si je rentre ce code :
Ça écrit qu'à partir de la colonne 5 et ligne 0, on dirait qu'il ne tient pas compte de mon adresse verticale et remplace mon adresse verticale par mon adresse horizontale...Code:INSTAFF ; movlw 0x80 ; Set Graphic Display RAM Adress movwf PORTD ; bsf E ; bcf E ; call Tempo100us ; ; INSTAFF ; movlw 0x85 ; movwf PORTD ;Set Graphic Display RAM Adress bsf E ; bcf E ; call Tempo100us ;
Et si j'enlève la tempo entre les deux pour écrire les deux adresses bien à la suite comme ceci :
Ça écrit à partir le la colonne 0 mais aussi sur la ligne 0.Code:INSTAFF ; movlw 0x80 ; Set Graphic Display RAM Adress movwf PORTD ; bsf E ; bcf E ; ; call Tempo100us ; ; INSTAFF ; movlw 0x85 ; movwf PORTD ;Set Graphic Display RAM Adress bsf E ; bcf E ; call Tempo100us ;
Dernière modification par damien8024 ; 04/05/2020 à 19h43.
Je vous suit et c'est très intéressant ! par contre, je vois que vous négligez la temporisation (ou tempo courte), un contrôleur d'afficheur LCD c'est lent à réagir ! entre la commande et la data, faut prendre son temps... a la vitesse du Pangolin
Dernière modification par Qristoff ; 04/05/2020 à 20h09.
Tout existe, il suffit de le trouver...!
Oui effectivement, ça valait le coup d'essayer... Au moins pour l'adressage de la SGRAM car il n'y a plus que ça qui ne fonctionne pas.
En adressant la SGRAM avec ma tempo de 250ms, ce coup ci il écrit sur la colonne 5 et la ligne 5 !
Si je laisse ma tempo entre les deux, on a une écriture en colonne 5, ligne 0Code:INSTAFF ; movlw 0x80 ; Set Graphic Display RAM Adress movwf PORTD ; bsf E ; bcf E ; ; call Tempo250ms ; ; INSTAFF ; movlw 0x85 ; movwf PORTD ;Set Graphic Display RAM Adress bsf E ; bcf E ; call Tempo250ms ;
1 - Tu as relié le RST à PORTC,0 mais as-tu bien défini le TRISC,0 en sortie (il était en entrée jusqu'à présent)
2 - J'ai regardé un programme en C, il faut envoyer la ligne en premier et la colonne en second. Je comprends le contraire en lisant le datasheet et ton programme semble le prouver. En ce qui concerne les tempos, ne les enlève surtout pas, les 100 µs sont supérieures à ce qui est précisé dans le datasheet (si on peut s'y référer).
Effectivement je te confirme ! Il faut bien pointer l'adresse horizontale d'abord puis l'adresse verticale en second.
Si on regarde le protocole de la page 12 du datasheet, j'ai l'impression qu"ils ont aussi traduit horizontal et vertical à l'inverse !
De plus, il faut bien le faire en deux temps donc la tempo entre les deux est comme tu le dis, indispensable.
Il faut aussi savoir que le mappage de la GDRAM et de la HGROM n'est pas comme sur le datasheet mais comme ceci (suivant un correctif que j'avais trouvé) :
Donc pour résumé et pour les prochains qui galèrent avec cet afficheur, voici l'initialisation correcte :
Code:; Initialisation Afficheur ; ------------------------ BANK0 bsf RESAFF ; call Tempo100us ; bcf RESAFF ; Reset de l'afficheur (actif sur niveau bas (PIN n°16) call Tempo100us ; bsf RESAFF ; bcf E call Tempo250ms ; Tempo nécessaire à l'initialisation INSTAFF ; movlw 0x30 ; Ouvre Fonctions basiques (RE=0) + Interfaçage 8 bits movwf PORTD ; bsf E ; bcf E ; call Tempo100us ; INSTAFF ; movlw 0x30 ; Ouvre Fonctions basiques (RE=0) + Interfaçage 8 bits movwf PORTD ; bsf E ; bcf E ; call Tempo100us ; INSTAFF ; movlw 0x0D ; Display Control movwf PORTD ; Display ON, Cursor OFF, Blink OFF bsf E ; bcf E ; call Tempo100us ; INSTAFF ; movlw 0x01 ; Display Clear movwf PORTD ; bsf E ; bcf E ; call Tempo250ms ; INSTAFF ; movlw 0x02 ; Return Home movwf PORTD ; bsf E ; bcf E ; call Tempo100us ; ; Séquence permettant de passer en mode Graphic Display ON INSTAFF ; movlw 0x30 ; Ouvre Fonctions basiques (RE=0) + Interfaçage 8 bits movwf PORTD ; bsf E ; bcf E ; call Tempo100us ; INSTAFF ; movlw 0x34 ; Extended Function Set movwf PORTD ; Graphic Display OFF bsf E ; bcf E ; call Tempo100us ; INSTAFF ; movlw 0x36 ; Extended Function Set movwf PORTD ; Graphic Display ON bsf E ; bcf E ; call Tempo100us ;
Si on veut sortir du mode graphique :
Code:INSTAFF ; movlw 0x30 ; Ouvre Fonctions basiques (RE=0) + Interfaçage 8 bits movwf PORTD ; bsf E ; bcf E ; call Tempo100us ;
Et pour l'adressage de la GDRAM (permettant de définir la position du pixel de départ où on veut écrire) puis l'envoie des données :
En tenant compte qu'il faut écrire des données toujours par deux octets et que l'adresse verticale s'incrémente toute seule apparemment (et non l'adresse horizontale)Code:INSTAFF ; movlw 0x85 ; Set Graphic Display RAM Adress movwf PORTD ; Horizontal Ligne 5 par exemple bsf E ; bcf E ; call Tempo100us ; INSTAFF ; movlw 0x8A ; Set Graphic Display RAM Adress movwf PORTD ; Vertical Colonne A par exemple bsf E ; bcf E ; call Tempo100us ; WRAFF movlw 0x55 ; WRITE RAM movwf PORTD ; On écrit 0x55 bsf E ; bcf E ; call Tempo100us ; WRAFF ; movlw 0x55 ; WRITE RAM movwf PORTD ; on écrit 0x55 bsf E ; bcf E ; call Tempo100us ;
Voilà voilà...
Il me reste plus qu'à écrire ma routine pour effacer l'écran en envoyant des 0 partout pour cemode parallèle 8 bits...
Un grand merci à vous tous pour m'avoir permis de maîtriser en partie les protocoles de cet afficheur et maintenant qu'ils sont opérationnels, je vais pouvoir me concentrer uniquement sur ma liaison SPI !!!
Dernière modification par damien8024 ; 04/05/2020 à 23h35.
Content que ça fonctionne.
J'ai lu sur un doc que la séquence d'init suivante est suffisante pour initialiser ton afficheur et entrer en mode graphique.
0x30
0x30
0x34
0x36
Voici un bout de code que je viens d'écrire, tu peux t'en inspirer. Tu remarqueras que je suis toujours dans le registre instruction, sauf quand j'ai besoin d'aller dans le registre data, mais j'en ressors dès que j'ai terminé.
Je n'ai bien entendu pas testé ce code.
Je crois qu'il est également possible de couper l'affichage avec l'instru 34 et de le remettre avec l'instru 36.Code:CBLOCK 0X20 colonne : 1 ; code de la colonne sur laquelle travaille l'afficheur (soit 0x80 + le numéro de la colonne) ligne : 1 ; code de la ligne sur laquelle travaille l'afficheur (soit 0x80 + le numéro de la ligne) macro send_data data movlw data ; data -> W bsf RS ; passe sur le registre data call send_byte ; envoie l'octet bcf RS ; retourne dans le registre instruction endm macro send_instru instru movlw instru ; instru -> W call send_byte ; envoie l'octet endm init bcf RS ; On se positionne dans le registre instruction send_instru 0x30 ; je ne commente plus ces lignes send_instru 0x30 send_instru 0x34 send_instru 0x36 call clear_screen ; efface ecran ... ... ... clear_screen movlw 0x80 ; on place 0x80 dans W movwf ligne ; pour sélectionner la première ligne movwf colonne ; et la première colonne bcl_ligne movf ligne,w ; se positionne au début de la ligne à effacer call send_byte movf colonne,w call send_byte bsf RS ; Registre data bcl_colonne clrw ; 0 -> w call send_byte ; Envoie 0x00 pour effacer incf colonne,f btfss colonne,4 ; 16 fois. Le test se fait sur le bit 4 de la variable colonne goto bcl_colonne bcf colonne,4 ; remet 0x80 dans colonne en mettant le bit 4 à 0 bcf RS : retourne dans le registre instru incf ligne,f ; une fois la ligne terminée, on passe à la suivante. btfss ligne,6 ; les 64 lignes sont effacées ? goto bcl_ligne ; non : on passe à la ligne suivane bcf ligne,6 ; oui, on remet 0x80 dans ligne en mettant le bit 6 à 0 return send_byte ; L'octet à envoyer est dans W movwf PORTD ; octet -> Port D bsf E ; Pulse sur Enable bcf E goto Tempo100us ; goto remplace call suivi de return
Bonjour.
J'ai préparé le code en SPI, au cas où.
Merci à toi
Je vois que tu fais du code pour t'endormir le soir
Je l'avais déjà préparé et il est exactement comme le tien... Donc je suis pas trop nul !
Ceci-dit l'effacement prend 0.5 à 1 seconde. Je sais pas ce que ça donnera en SPI...
Pour la liaison SPI, oui je vais m'y remettre car je ne peux pas me permettre de monopoliser autant de broches sur mon PIC.
A ce propos tu sais, si je peux commander mon afficheur en SPI et mon EEPROM en I2C (jamais mis en place de communication I2C encore) ? Vu qu'on utilise la même broche SDO et SCK.
Sinon oui j'ai gardé en tête que tu m'as écrit ton code pour la liaison SPI et ça va bien me servir
Dernière modification par damien8024 ; 05/05/2020 à 12h05.
L'EEPROM servira à crééer et stocker tous mes caractère 5X8. A moins qu'une bibliothèque exploitable pour ce type d'afficheur existe déjà ?
Dernière modification par damien8024 ; 05/05/2020 à 12h11.
Je remarque quand même que ton code est un peu mieux optimisé que le mien ! Je vais corriger ça !
Ce me paraît beaucoup une demi-seconde, le soft doit écrire 1024 fois et donc tancer autant de fois la tempo, mais ça ne fait qu'une centaine de ms (100us x 1024). Les autres instructions ne doivent pas engendrer un temps processeur énorme, même si elles sont elles aussi exécutées jusqu'à 1024 fois. Je ferai une simu dans un moment. Tu peux essayer de baisser un peu la tempo, à 80us par exemple, tu gagneras un petit peu.
En SPI, ce sera forcément beaucoup plus long. Ce serait intéressant d'essayer ce que j'ai écrit plus tôt, à savoir envoyer une instru 34 pour désactiver l'affichage, puis lancer l'effacement d'écran et enfin lancer l'instru 36 pour remettre affichage en route. Ça éviterait de voir le défilement de l'effacement. Mais je ne sais pas si ça fonctionne.
Pour l'EEPROM, tu peux utiliser une SPI aussi, tu n'auras besoin que d'une broche en plus pour son CS. Tu peux peut-être également utiliser la mémoire du PIC selon la taille nécessaire.
Je viens de faire une simulation de ma routine clear_screen après correction du code car il ne faut pas écrire
maisCode:macro send_data data
et la même chose pour send_instru.Code:send_data macro data
J'ai légèrement baissé la tempo de 100µs de façon à ce que le temps entre la fin du pulse et la modification du port D soit d'au moins 80µs (le datasheet demande une durée >72µs), la routine s'exécute en 100ms. En laissant les 100µs, la durée est de 128ms.
Dernière modification par MathSACO ; 05/05/2020 à 20h50.
Bonjour MathSaco,
Pas eu le temps de revenir dessus, un peu de boulot le matin et avec ce soleil, je suis sur mon potager l'après-midi !
Je lancerai une simulation de mon code juste pour comparer le temps d'exécution de la routine au tien.
Mais je crois que je me servirai de ton code, il est plus joli et mieux optimisé je pense
J'essaierai également l'effacement d'écran par les instrus 34 et 36 que tu mentionnais mais j'y crois pas trop... Normalement dès qu'on lance l'instru 36, ça mets les pixels à l'écran !
Je te dirai ça quand-même...
Oui faudra que je calcule pour l'eeprom du pic, c'est juste pour mes caractères mais il y a majuscules, minuscules et chiffres
Bonjour.
Aucun souci, je ne poste plus de message non plus car je suis au travail.
J'ai pensé à 2 choses en lisant ton message hier :
- Si tu n'as besoin que de 62 caractères (26 majuscules, 26 minuscules et 10 chiffres) et que chaque caractère mesure 5x8 pixels, ça ne prendra que 310 octets de mémoire et ça devrait largement rentrer dans ton PIC si ton programme n'est pas trop gros (attention à la gestion du PCLATH). Il faudra faire un peu de gymnastique pour utiliser 5 octets pour chaque caractère. J'ai trouvé une méthode en une quinzaine de lignes de code pour passer de ces 5 octets de 8 bits aux 8 octets correspondant aux 8 lignes de ton caractère.
- Concernant le fonctionnement en SPI , même si le micro doit transférer 24 bits pour 1 octet utile, le temps total ne sera pas si allongé qu'on aurait pu le croire. Si on se fie au datasheet du ST7920 et à celui du 16F877, ton bus SPI devrait pouvoir tourner à 1MHz dans ton montage actuel et la transmission de la donnée sur le bus SPI serait alors 'relativement' petite par rapport à la tempo utilisée pour le temps de traitement du ST7920 (les fameuses 100µs).
Bonjour,
Alors je n'arrive pas à mesurer le temps de ma propre séquence d'effacement d'écran en simulation MPLab car même en mettant mon breakpoint à la fin de la séquence il s'arrête à chaque fois que la Tempo100us est appelé. Peut-être un réglage pour pas qu'il s'arrête à chaque sous-programme appelé... Je vais essayer de gratter sur le net pour savoir.
Sinon pour ce que tu me disais, à savoir lancer une 34 puis la sous-routine d'effacement d'écran puis une 36, ça fonctionne. Et c'est plus joli quand c'est invisible
J'ai poussé mes essais et j'ai remarqué que tu pouvais effacer l'écran après avoir écrit des choses juste avec une séquence 30 - 01 - 36. Ce qui est plus rapide !
En revanche elle ne fonctionne pas à l'initialisation quand tous les pixels s'affichent... Étrange... Donc obligé de passer par la sous-routine de tous les pixels à 0
En ce qui concerne la méthode pour l'alphabet, je t'avoue que je n'y ai pas trop réfléchi encore. Si ça te dérange pas et si je galère je te demanderai plus de précisions sur ta méthode.
Je sais pas si l'alphabet rentrera dans la mémoire programme de mon pic car je me sers de l'afficheur pour une gestion de menus et j'ai peur quand codant chaque phrase, mon programme soit déjà lourd !
Malheureusement l'eeprom du 16f877 est limitée à 256 octets et d’après ton calcul, ça ne rentre pas.
Déjà dans un premier temps, il faut que je me repenche sur cette liaison SPI...
Dernière modification par damien8024 ; 07/05/2020 à 22h26.
Salut,
Je ne comprends pas bien ce que tu veux faire. La banque de caractères est déjà dans l'afficheur ! il faut juste appeler le code correspondant.
Tout existe, il suffit de le trouver...!
Il y a juste à envoyer le code ASCII du caractère à l'afficheur. En assembleur, tu peux écrire
movlw 'R' pour envoyer la lettre R majuscule ou movlw 'r' pour envoyer le r minuscule.
Pour écrire un mot, il faut envoyer lettre par lettre à la suite...
Tout existe, il suffit de le trouver...!
Pour plus de clarté dans ton code, tu peux utiliser une macro:
dans ton code, tu auras par exemple:Code:;********************************************************************* ; MACRO * ;********************************************************************* ; envoyer un caractére à l'afficheur Aff macro string movlw string call LCD_DAT endm
Aff 'H'
Aff 'e'
Aff 'l'
Aff 'l'
Aff 'o'
C'est quand même plus lisible !
et ensuite une routine pour envoyer l'octet à l'afficheur.
Tout existe, il suffit de le trouver...!
Salut Qristoff,
J'avais écrit un code dans ce sens pour tester mon afficheur avec les caractères ASCII.
Mais si je veux l'utiliser en mode graphique, c'est parce que les caractères implantés dans l'afficheur sont trop gros. C'est pour ça que je vais me créer une bibliothèque de caractères 5x7
Je retire ce que j'ai écrit précédemment pour effacer l'afficheur. On est bien obligé d'écrire que des bits à 0...
J'ai cru que ça fonctionnait par ma méthode mais en fait il ne faisait que désactiver l'affichage !
Sinon victoire pour la liaison SPI, ça fonctionne !
Pour les futurs lecteurs, j'ai utilisé une vitesse de bus à la fréquence du quartz divisée par 4 (fréquence max possible) et il faut bien envoyé les 3 octets (Instruction + Octet poids fort + Octet poids faible) à la suite. Comme on avait évoqué les jours précédents.
Il faut juste savoir que si on divise l'afficheur en 4 zones horizontales avec la n°1 en haut, il écrit d'abord sur la 1 puis continue sur la 3. Mais rien de méchant, il suffira juste d'en prendre compte dans l'écriture du code.
Un grand merci à tous, maintenant je vais réfléchir pour mon alphabet et mes phrases !
Dernière modification par damien8024 ; 08/05/2020 à 15h26.
tu n'utilises pas l'instruction CLEAR du contrôleur ?Je retire ce que j'ai écrit précédemment pour effacer l'afficheur. On est bien obligé d'écrire que des bits à 0...
Tout existe, il suffit de le trouver...!
J'ai essayé mais j'y arrive pas...
J'ai envoyé l’instruction 0x30 pour repasser en mode "Basic Instructions" (voir même deux fois à la suite au cas où) puis un Display Clear mais ça ne fait que me mettre l'afficheur en standby.
Comme Display Clear et Standby ont la même instruction, je n'arrive pas donc pas à passer en mode "Basic Instructions" et je ne comprends pas pourquoi...
la commande CLEAR, c'est 00000001. à découper en deux quartet, comme d'hab et ça dure 1,6ms (trés long)
Tout existe, il suffit de le trouver...!
Je ne comprends pas ce que tu veux dire dans cette phrase.
En ce qui concerne le stockage de tes caractères dans le PIC, tu peux utiliser la mémoire programme libre, je pourrai te donner des exemples si tu le souhaites.