Stoppt die Vorratsdatenspeicherung! Jetzt klicken && handeln!Willst du auch bei der Aktion teilnehmen? Hier findest du alle relevanten Infos und Materialien:
 
Nokia Display
von Plapperkatze am 9.Mai 2007 um 20:09
zurück zur Kategorie "Tutorials"

Hi ihr,

Vielleicht interessiert es jemanden, wie man mit einem Atmega8 ein Bitmap auf einem alten Nokia-3310-Display anzeigt. Diese Schwarzweiss-Displays haben 84*48 Pixel und werden mit max. 3,3V betrieben.

Die Beschaltung habe ich von http://www.microsyl.com/nokialcd/nokialcd.html beinahe 1:1 übernommen, nur der data/command-pin hängt bei mir auf PB7. Ausserdem muss man Spannungsteiler vorsehen, wenn man (wie ich) den mega8 mit 5V betreibt:


Mit dem Code von der microsyl-Seite lässt sich das Display sehr einfach ansteuern, man muss nur im Header ein define ändern
#define LCD_DC_PIN                 0x80  //  PB7

und noch eine main-funktion in der c-Datei hinzufügen
int main(void)
{
 unsigned char buffer[]="ein text";
 LcdInit       ();
 //LcdContrast   (64); //hier koennte man den kontrast regeln
 LcdGotoXY     (1,1);
 LcdStr(1,buffer);
 LcdUpdate     ();
 for(;;);
 return 0;
}


Man kann auch schön Pixel setzen oder Linien malen:
 LcdLine(0,0,83,47,1);
 LcdPixel(5,5,1);
 LcdUpdate();


Das display muss mit LcdInit() initialisiert werden, bevor es verwendet werden kann. Alle Zeichendaten werden (mit LcdPixel, LcdLine, LcdStr) zuerst in einen Puffer im atmega geschrieben und erst durch LcdUpdate() auf das Display übertragen.

Ich wollte eigentlich mit sprintf etwas in einen Puffer schreiben, aber sobald ich stdio.h include, hängt sich mein AVRstudio (bzw. winAVR?) komplett auf. Wenn jemand weiß, woran das liegen könnte, bitte hilfe.

Wenn man allerdings bitmaps abbilden will, empfiehlt es sich, nicht alle Pixel einzeln zu setzen, sondern den RAM des Displays direkt vollzuschreiben. dazu sind 2 Dinge zu beachten:
1. der Display-Ram-Zeiger muss gesetzt werden, bevor man reinschreiben kann
2. während in Windows-Bitmaps die Bilddaten Zeile für Zeile gespeichert sind (bei schwarzweiss also ein Byte 8 horizontale Pixel sind) sind es im Display-Ram 8 vertikale pixel.

3. ein Schwarz-Weiss-Windows-Bitmap enthält Headerdaten vor den Bilddaten, ausserdem ist die Länge einer Zeile (in Byte) immer durch 4 teilbar. Das führt dazu, dass statt 84 Pixel (10,5 Byte) 96 Pixel (12 Byte) gespeichert werden. Angezeigt werden die übrigen 12 Pixel im zeichenprogramm nicht.

Folgender Code konvertiert ein Schwarzweiss-Bitmap (für das 3210-Display muss es 84*48pixel gross sein) in das nokia format. Erzeugt wird eine Textdatei, die direkt in den AVR-code gecopypastet werden kann.
/*----------------------------------------------------------------
width*height schwarz-weiss bitmap in nokia 3310 format wandeln
compiler: bcc32
OS: XP
robocat, 16.04.07
----------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

#include <conio.h> // fuer getch()

// define glcd size here
unsigned int width=128;
unsigned int height=64;

int main()
{

 FILE *pDatei;
 unsigned int size,i,x,y,realwidth;
 unsigned char buf[64],*file1,*file2;
 long pos1,pos2;

 realwidth=width/8;
 while(realwidth%4!=0)realwidth++;  

 pDatei = fopen("J: est.bmp", "rb");

 if(pDatei == NULL)
 {
   printf("Fehler beim Oeffnen der Quell-Datei!
");
   printf("Programm beendet.
");
   exit(1);
 }

 fseek(pDatei,0,SEEK_END);
 pos2=ftell(pDatei);
 fseek(pDatei,10,SEEK_SET);
 fread(&pos1,4,1,pDatei);
 fseek(pDatei,pos1,SEEK_SET);

 size=pos2-pos1;
 file1=malloc(size);
 fread(file1,1,size,pDatei);
 fclose(pDatei);

 printf("size: %u (should be %u)
",size,realwidth*height);

 file2=(unsigned char*)malloc(width*height/8);
 memset(file2,0,width*height/8);

 for(x=0;x<width;x++)
 {  
   for(y=0;y<height;y++)
   {  
     if((*(file1+(y*realwidth*8+x)/8)>>(7-(x%8))&1)!=1)
     {
       *(file2+((height-y-1)/8)*width+x)|~~2?3~~lt;<(7-(y%8));
     }
   }
 }

 pDatei = fopen("J: est.txt", "w");
 if(pDatei == NULL)
 {
   printf("Fehler beim Oeffnen der Ziel-Datei!
");
   printf("Programm beendet.
");
   free(file1);
   free(file2);
   exit(1);
 }
 sprintf(buf,"unsigned char picture[]={");        
 fwrite (buf,strlen(buf),1,pDatei);
 for(i=0;i<width*height/8;i++)
 {
   if(i%8==0)fwrite("
",1,1,pDatei);
   sprintf((char*)buf,"%u,",*(file2+i));        
   fwrite(buf,strlen(buf),1,pDatei);
 }
 fseek(pDatei,-1,SEEK_END);
 fwrite ("};
",3,1,pDatei);
 fclose(pDatei);
 free(file1);
 free(file2);

 printf("Programm erfolgreich beendet.
");
 getch();

 return 0;
}


Damit hat man das Bitmap auf dem Display:


Bei Fragen helfe ich gern.

Gruesse von der katze

zurück zur Kategorie "Tutorials"
[1 Kommentare]

Till (Gast) schrieb am 10. September 2008 um 10:13
Hallo,

ich habe die Schaltung aus einzelnen Widerständen aufgebaut, messe aber über R12 eine Spannung von nur knapp 1,5V (das sollte eigentlich die Versorgungsspannung von 3V sein, oder?) und über R6(!) eine Spannung von 3V. Das Display zeigt nichts. Das Problem liegt nicht im Code, denn mit 3V Versorgung am ATMega8 und Display funktioniert's wunderbar. Ich will die Prozessorversorgung aber auf 5V erhöhen. Mache ich einen blöden Fehler??

Gruß aus Hamburg
Till

Name


Kommentar




Bitte abtippen


 
(C) 2006-20012 Plapperkatze - 220706 Besucher seit dem 23.01.2012 Login