- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.
--- L’équipe FantasPic ---
Modérateur : mazertoc
satinas a écrit :Source du message 0
satinas a écrit :Source du message Pour écrire on spécifie un numéro de page, puis la première colonne à écrire.
Pous définir la page (0 à 7), on envoie :
- la commande 0b10110ppp
Pour définir la première colonne (0 à 127) on envoie :
- la commnande 0b0000LLLL (lower nibble -> 4 bits de poids faible, nibble = quartet)
- la commnande 0b0001hhhh (higher nibble -> 4 bits de poids fort)
Bon je viens de relire ce que tu as écrit, c'est ce que j'ai fait dans mon code, sans comprendre pourquoi ça fonction.
Avec des exemple simple on comprends mieux, j'ai fait l'essai en affichant un 'A'
quand j'écris ceci
Code : Tout sélectionner
movlw 0xB1 ; page 2
rcall command_ssd1306
movlw B'00000000' ; 0x00
rcall command_ssd1306
movlw B'00010000' ; 0x00
rcall command_ssd1306
movlw 'A' ; code clavier
rcall lettre_ssd1306
J’obtiens ceci
quand j'écris ceci
Code : Tout sélectionner
movlw 0xB1 ; page 2
rcall command_ssd1306
movlw B'00001111' ; 0x0F
rcall command_ssd1306
movlw B'00010000' ; 0x00
rcall command_ssd1306
movlw 'A' ; code clavier
rcall lettre_ssd1306
J’obtiens ceci
quand j'écris ceci
Code : Tout sélectionner
movlw 0xB1 ; page 2
rcall command_ssd1306
movlw B'00000000' ; 0x00
rcall command_ssd1306
movlw B'00011111' ; 0x1F
rcall command_ssd1306
movlw 'A' ; code clavier
rcall lettre_ssd1306
J’obtiens ceci
quand j'écris ceci
Code : Tout sélectionner
movlw 0xB1 ; page 2
rcall command_ssd1306
movlw B'00001111' ; 0x0F
rcall command_ssd1306
movlw B'00011111' ; 0x1F
rcall command_ssd1306
movlw 'A' ; code clavier
rcall lettre_ssd1306
J’obtiens ceci
La lettre 'A' est bien à sa place, car elle fait 5 pixels, ce qui explique de débordement en fin de ligne.
Conclusion, ta déduction était la bonne satinas
Bon, ça veut dire qu'il faut que je retouche le code, car il y a pas mal de bug, maintenant que j'ai bien compris je vais optimiser le code, arrivé à ce
stade, ça devient un vrai plaisir d'écrire le programme... ouf...
A+
Le mode adressage par page est expliqué au chapitre 10.1.3, notamment on peut lire ou écrire la mémoire graphique du lcd. Le mode lecture n'est pas possible en SPI et I2C. Lorsqu'on arrive en fin d'écran à droite le curseur revient à la première colonne déclarée. Il faut calculer son coup pour pas sortir du lcd.
Pour s'affranchir des pages, et faire des fonctions travaillant au pixel, 2 solutions :
- soit prévoir un buffer ram de 8*128 octets dans le pic pour stocker tous les pixels, et on envoie que les octets modifiés.
- soit utiliser le read pixel, pour dessiner un pixel, on lit l'octet, on le modifie, puis on le renvoie au lcd. Mais pas possible en SPI.
J'avais fait la version avec buffer pic, pas performante du tout, une version optimisée est prévue pour la Saint Glinglin.
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
du beau boulot !
mais je trouve bizarre ton mode d'adressage des caracteres au vu des resultats de positionnement obtenu
avec 0x1F soit 31 tu devrais etre loin du bord droit de l'ecran
La façon d'afficher le caractere lui meme interfere aussi dans la notion du positionnement XY
pour moi , les pages , ce sont les lignes de caracteres
sur mon OLED de 128x32 , je n'ai que 4 pages 0, à 3
donc sur le tien 0 à 7
comme le precise Satinas, dans le sens Y , on ne peut etre que modulo 8
j'utilise une matrice 8x8 et donc pour me positionner sur une ligne Y , j'utilise 0 à 3
et coté X , par contre c'est bien au pixel pres .. ymaxi=3 et X maxi=127-8
apres, si on veut un positionnement au pixel pres, sens Y , on peu utiliser un mapping tableau de 128x64 pixel
ecrire dans ce tableau et envoyer le tout sur l'OLED
..comme pour le BMP
test ecriture sens Y (modulo page) et sens X au pixel pres
Code : Tout sélectionner
UART1_Write_CText(" Affiche lettres A B C ...Q \r\n");
UART1_Write_CText(" Write_Char_At(X en pixel (0 à 127), ligne Y (0 à 3),code ascii char)\r\n");
Write_Char_At(0,0,'A');
Write_Char_At(8,1,'B');
Write_Char_At(16,2,'C');
Write_Char_At(24,3,'D');
Write_Char_At(32,3,'E');
Write_Char_At(40,2,'F');
Write_Char_At(48,1,'G');
Write_Char_At(56,0,'H');
Write_Char_At(56,1,'I');
Write_Char_At(64,2,'J');
Write_Char_At(72,3,'K');
Write_Char_At(80,3,'L');
Write_Char_At(88,3,'M');
Write_Char_At(96,2,'N');
Write_Char_At(104,1,'O');
Write_Char_At(112,0,'P');
Write_Char_At(120,1,'Q');
satinas a écrit :Source du message Pour s'affranchir des pages, et faire des fonctions travaillant au pixel, 2 solutions :
- soit prévoir un buffer ram de 8*128 octets dans le pic pour stocker tous les pixels, et on envoie que les octets modifiés.
- soit utiliser le read pixel, pour dessiner un pixel, on lit l'octet, on le modifie, puis on le renvoie au lcd. Mais pas possible en SPI.
C'est la première solution que je prendrais, (modification du buffer dans le pic), et c'est celle là qui mais venu en idée.
paulfjujo a écrit :Source du message mais je trouve bizarre ton mode d'adressage des caractères au vu des résultats de positionnement obtenu
avec 0x1F soit 31 tu devrais être loin du bord droit de l'écran
Ce que j'ai compris
poids fort : 128, 64, 32, 16 poids faible : 8, 4, 2, 1
Tout dépends de la page choisis, j'ai pris la méthode 1
Méthode 1
Méthode 2
Méthode 3
J'ai vu sur ton site, dans ta source en MikroC, que tu as pris la méthode 2, je vais voir si c'est plus pratique pour ce que je veux faire.
Oui effectivement, j'ai bien 8 pages de 0 à 7 (le zéro est compris dedans).
j'ai compté les pixels avec le microscope binoculaire, j'ai bien 128 pixels x 64 pixels (c'est pas une blague, c'est du réelle)
Aussi petit qu'il soit, il est d'une grande complexité.
A+
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
poids fort : 128, 64, 32, 16 poids faible : 8, 4, 2, 1 (1 pixel fait peut être 2 bits) faut que je refasse des essais.
le poids fort 128 n'est pas utilisé car on la position X 0 à 127
memory adressing mode :
j'ai effectivement pris ce mode 2
Code : Tout sélectionner
WriteCmd(0x20); //Set Horizontal Memory Addressing Mode
//A[1:0] = 00b, Horizontal Addressing Mode
//A[1:0] = 01b, Vertical Addressing Mode
//A[1:0] = 10b, Page Addressing Mode (RESET)
//A[1:0] = 11b, Invalid
WriteCmd(0x02); // Page Addressing Mode (RESET)
si j'ecris
Code : Tout sélectionner
strConstRamCpy(txt,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
OLED_ShowStr(0 ,2,txt,1);
debordement de l'ecran , continue sur la page (ligne) de dessous
j'ai bien sur l'ecran OLED
Code : Tout sélectionner
0 1ere Ligne
1 2em Ligne
2 3em ligne ABCDEFGHIJKLMNOPQRSTU
3 4em ligne VWXYZ
une petite difference aussi..je le pilote en I2C , pas en SPI .
paulfjujo a écrit :Source du message le poids fort 128 n'est pas utilisé car on la position X 0 à 127
Effectivement, je viens de contrôler, si je fais ça
Code : Tout sélectionner
movlw B'00001111' ; 0x0F
rcall command_ssd1306
movlw B'00010111' ; 0x1F + 0x07
rcall command_ssd1306
movlw B'11111111' ; envoie nune ligne de 8 pixels
rcall donner_ssd1306 ;
c'est la même chose que ça
Code : Tout sélectionner
movlw 0xB1 ; page 2
rcall command_ssd1306
movlw B'00001111' ; 0x0F
rcall command_ssd1306
movlw B'00011111' ; 0x1F + 0x0F
rcall command_ssd1306
movlw B'11111111' ; envoie nune ligne de 8 pixels
rcall donner_ssd1306 ;
1 bits du poids fort qui ne sert à rien..... encore un datasheet fait pour multiple écran... je vais voir dans la macro comment modifier tous cela.
paulfjujo a écrit :Source du message une petite différence aussi..je le pilote en I²C , pas en SPI .
Oui, mais ça reste similaire dans les registres de l'écran, bon j’avoue que tu utilises 4 fils en I²C, contre 6 pour un mode SPI
De toute façon quand j'aurais fini mes fonctions, je teste l'écran I²C.
A+
Je comprends pas pourquoi ça fonction pas, d'après la documentation de l'écran Oled 128x64 fourni ci-dessous,
on devrait se positionner à la hauteur souhaité, qui est de 0 à 63, et ben non ça fonction pas avec le code si dessous.
Alors je demande à tous hasard, si quelqu'un pourrais me dire, pourquoi ça ne fonction pas ?
Code : Tout sélectionner
;-------------------------------- "position de y et x sans page" -------------------------------
pixel_ssd1306
movf posy,W ; hauteur de l'écran 0 à 63 (64 pixels)
bsf WREG,6
rcall command_ssd1306
movf posx,W ; longueur de l'écran 0 à 127 (128 pixels(colonnes))
andlw B'00001111' ;
rcall command_ssd1306 ; envoi du poid faible
movf posx,W ;
swapf WREG,W ;
andlw B'00000111' ;
bsf WREG,4 ;
rcall command_ssd1306 ; envoi du poid fort
movlw B'10000000' ; 1 pixel
rcall donner_ss1306 ;
return
Merci
A+
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
D'apres moi, cette valeur 0 à 63 sert à positionner un DEPART DE LIGNE, pas un pixel ..
en particulier pour faire du scrolling vertical entre les pages
le positionnement vertical Y est modulo 8
Y varinat de 0 à 7 pour ton LCD
0 à 3 pour le mien .
il faudra passer par le BitMAP si tu veux afficher au pixel pres sens Y .
ou via un caractere modifiable. (donc par 8 pixels verticaux à la fois)
C'est ma comprenette .. à voir d'autres avis .
Il faut comme dit Paul envoyer un bitmap constitué de segments de 8 pixels.
Ou alors pour faire un tracé pixel par pixel, envoyer :
- sa page (y/8)
- sa colonne (x)
- sa position 2^(y%8) -> par exemple si y=0,8,16,... on envoie 0b00000001, si y=3,11,19,... on envoie 0x00001000
Problème on a envoyé 8 pixels, donc on a effacé les 7 autres pixels, et c'est pourquoi il faut passer par un buffer intermédiaire qui mémorise avant envoi.
Code : Tout sélectionner
pixel_ssd1306 ; exemple écriture pixel y=63, donc 7ème pixel de la page 7
movf posx,W ; longueur de l'écran 0 à 127 (128 pixels(colonnes))
andlw B'00001111' ;
rcall command_ssd1306 ; envoi du poid faible
movf posx,W ;
swapf WREG,W ;
andlw B'00000111' ;
bsf WREG,4 ;
rcall command_ssd1306 ; envoi du poid fort
movf posy,W ; hauteur de l'écran 0 à 63 (64 pixels)
andlw B'00111000' ; 00111000 si pixel 63 -> page 7
rrncf WREG ; 00011100
rrncf WREG ; 00001110
rrncf WREG ; 00000111
iorlw B'10110000' ; 10110111
rcall command_ssd1306 ; envoi page 7 -> 10110111
movf posy,W ; hauteur de l'écran 0 à 63 (64 pixels)
andlw B'00000111' ; si pixel 63 -> W = 7 pour 7ème pixel (de la page 7)
incf WREG ; W = 8
clrf data ; octet à envoyer au lcd (octet du buffer pic contenant le pixel)
bsf STATUS,C ; data=00000000 et C=1
:bcl rlcf data
decsz WREG
bra bcl
movf data,W ; data=10000000 et C=0 (après 8 décalages rlcf)
rcall donner_ss1306 ; envoi du pixel (et effacement des 7 autres pixels si pas de buffer pic)
return
C'est ce genre de code qui manque dans mon programme C pour optimiser, mais même en asm cela ne sera pas ultra rapide, à moins de trouver des astuces de programmation ou utiliser des tables de données prédéfinies (pour éviter la boucle).
paulfjujo a écrit :Source du message D’après moi, cette valeur 0 à 63 sert à positionner un DEPART DE LIGNE, pas un pixel ..
Oui c'est exacte, j'ai appelé cette fonction pixel_ssd1306, mais elle n'a jamais était fini, à cause des problèmes énoncé ci-dessus.
satinas a écrit :Source du message et c'est pourquoi il faut passer par un buffer intermédiaire qui mémorise avant envoi.
oui avec le buffer on est sur de ce qu'on fait, et je le comprends aisément,
satinas a écrit :Source du message utiliser des tables de données prédéfinies
c'est ce que j'ai fait, car c'est ce qu'il y a de plus rapide, et moins embêtant à mettre œuvre, cette méthode est très gourmand en taille programme.
cette méthode est valable si on réécrit les données, sans se soucier d'effacé les donnée existante sur l'écran.
La meilleur méthode est l'utilisation d'un buffer, ou les données afficher à l'écran corresponde au données mise en sdram, ce qui permets de savoir
ce qu'on fait, ça fait 1024 octets qui représente 5 bank,
Code : Tout sélectionner
movf posy,W ; hauteur de l'écran 0 à 63 (64 pixels)
andlw B'00111000' ; 00111000 si pixel 63 -> page 7
rrncf WREG,F ; 00011100
rrncf WREG?F ; 00001110
rrncf WREG,F ; 00000111
iorlw B'10110000' ; 10110111
rcall command_ssd1306 ; envoi page 7 -> 10110111
Division par 8 pour trouver la page, pas idiot cette méthode.......
à vous deux pour votre aide,
A+
Retourner vers « Langage ASM »
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 141 invités