Forum: Mikrocontroller und Digitale Elektronik Versuch ein Nokia Epson Display anzusteuern


von Brede Andreas (Gast)


Lesenswert?

Hallo Leute,

Ich habe ein grosses Problem, ich habe für ein Nokia 6100 Display von
Epson eine Ansteuerrungs routine in Bascom die auch 100% funktioniert!

Nun da ich aber nicht mit Bascom arbeite wollte ich den Code nach C
umsetzen, doch leider funktioniert mein Code nun nicht, und ich finde
einfach keinen Fehler. Ich würde euch bitten den Code mal anzuschauen
evt. fällt euch der Fehler auch, rein teoretisch habe ich den Code 1/1
übersetzt, jedenfalls dachte ich das!

Hier nun der Code und ich danke euch schonmal für eure Hilfe!



#include <avr/io.h>
#include <avr/pgmspace.h>

#ifndef F_CPU
#define F_CPU 8000000UL
#endif

#include <avr/delay.h>

#ifndef XTAL
#define XTAL                        8000000                // must be
changed
#endif

int Temp;
char Fontsize;
char Lcd_posx;
char Lcd_posy;
long Lcd_fcolor;
long Lcd_bcolor;
char Fontbreite, Fonthoehe, Xpixel, Ypixel;
int R;
char X1, X2, Y1, Y2, E;
int F;
long G;
char Zeichen;
char A, B, C, D;
int Befehl, Ausgabe;
int Xbit;

int Data[] = { 0x00, 0x02, 0x04, 0x06, 0x09, 0x0B, 0x0D, 0x0F, 0x00,
0x02, 0x04, 0x06, 0x09, 0x0B, 0x0D, 0x0F, 0x00, 0x04, 0x0B, 0x0F };

void Lcd_init(void);
void Lcd_cls(void);
void Lcd_sendbyte(void);

#define Lcd_Port  PORTA

#define  RS    0
#define CS     1
#define  Sdata     2
#define Sclk    3

const int Kommando = 0;
const int Parameter = 1;

#define Blau    00000011
#define Gelb    11111100
#define Weiss    11111111

int main (void)
{
DDRA = 0xff;
Lcd_init();
Lcd_cls();
  for(;;)
  {
  }
}

void Lcd_init (void)
{
  Lcd_Port &= ~(1 << RS);
  _delay_ms(10.00);
  Lcd_Port |= (1 << RS);

  Lcd_Port |= (1 << CS);
  Lcd_Port |= (1 << Sdata);
  Lcd_Port |= (1 << Sclk);
  Befehl = Kommando;
  Ausgabe = 0x20;
  Lcd_sendbyte();
  Befehl = Parameter;
  Ausgabe = 0x0F;
  Lcd_sendbyte();

  _delay_ms(40.00);
  Befehl = Kommando;
  Ausgabe = 0x94;
  Lcd_sendbyte();
  Ausgabe = 0xAF;
  Lcd_sendbyte();
  Ausgabe = 0xD1;
  Lcd_sendbyte();

  _delay_ms(40.00);

  Ausgabe = 0xBC;
  Lcd_sendbyte();
  Befehl = Parameter;
  Ausgabe = 0x04;

  Lcd_sendbyte();
  Ausgabe = 0x00;
  Lcd_sendbyte();
  Ausgabe = 0x01;
  Lcd_sendbyte();
  Befehl = Kommando;
  Ausgabe = 0xBB;
  Lcd_sendbyte();
  Befehl = Parameter;
  Ausgabe = 0x01;
  Lcd_sendbyte();
  Befehl = Kommando;
  Ausgabe = 0xA7;
  Lcd_sendbyte();

  Befehl = Kommando;
  Ausgabe = 0xCE;
  Lcd_sendbyte();

  for (int i=0; i<20; i++)
  {
    Temp = Data[i];
    Befehl = Parameter;
    Ausgabe = Temp;
    Lcd_sendbyte();
  }

}

void Lcd_sendbyte(void)
{
  Lcd_Port &= ~(1 << CS);
  Lcd_Port &= ~(1 << Sclk);

  if(Befehl == Kommando)
  {
    Lcd_Port &= ~(1 << Sdata);
  }
  else
  {
    Lcd_Port |= (1 << Sdata);
  }

  Lcd_Port |= (1 << Sclk);

  Xbit = Ausgabe & 128;
  if (Xbit > 0)
  {
    Lcd_Port |= (1 << Sdata);    //setze
  }
  else
  {
    Lcd_Port &= ~(1 << Sdata);    //lösche
  }
  Lcd_Port |= (1 << Sclk);
  Lcd_Port &= ~(1 << Sclk);

  Xbit = Ausgabe & 64;
  if (Xbit > 0)
  {
    Lcd_Port |= (1 << Sdata);    //setze
  }
  else
  {
    Lcd_Port &= ~(1 << Sdata);    //lösche
  }
  Lcd_Port |= (1 << Sclk);
  Lcd_Port &= ~(1 << Sclk);

  Xbit = Ausgabe & 32;
  if (Xbit > 0)
  {
    Lcd_Port |= (1 << Sdata);    //setze
  }
  else
  {
    Lcd_Port &= ~(1 << Sdata);    //lösche
  }
  Lcd_Port |= (1 << Sclk);
  Lcd_Port &= ~(1 << Sclk);

  Xbit = Ausgabe & 16;
  if (Xbit > 0)
  {
    Lcd_Port |= (1 << Sdata);    //setze
  }
  else
  {
    Lcd_Port &= ~(1 << Sdata);    //lösche
  }
  Lcd_Port |= (1 << Sclk);
  Lcd_Port &= ~(1 << Sclk);

  Xbit = Ausgabe & 8;
  if (Xbit > 0)
  {
    Lcd_Port |= (1 << Sdata);    //setze
  }
  else
  {
    Lcd_Port &= ~(1 << Sdata);    //lösche
  }
  Lcd_Port |= (1 << Sclk);
  Lcd_Port &= ~(1 << Sclk);

  Xbit = Ausgabe & 4;
  if (Xbit > 0)
  {
    Lcd_Port |= (1 << Sdata);    //setze
  }
  else
  {
    Lcd_Port &= ~(1 << Sdata);    //lösche
  }
  Lcd_Port |= (1 << Sclk);
  Lcd_Port &= ~(1 << Sclk);

  Xbit = Ausgabe & 2;
  if (Xbit > 0)
  {
    Lcd_Port |= (1 << Sdata);    //setze
  }
  else
  {
    Lcd_Port &= ~(1 << Sdata);    //lösche
  }
  Lcd_Port |= (1 << Sclk);
  Lcd_Port &= ~(1 << Sclk);

  Xbit = Ausgabe & 1;
  if (Xbit > 0)
  {
    Lcd_Port |= (1 << Sdata);    //setze
  }
  else
  {
    Lcd_Port &= ~(1 << Sdata);    //lösche
  }
  Lcd_Port |= (1 << Sclk);
  Lcd_Port &= ~(1 << Sclk);

  Lcd_Port |= (1 << CS);
}

void Lcd_cls(void)
{
   Befehl = Kommando;
   Ausgabe = 0x15;
//Spaltenadressierung
   Lcd_sendbyte();
   Befehl = Parameter;
   Ausgabe = 0;
//X-Position der linken oberen Ecke
   Lcd_sendbyte();
   Ausgabe = 131;
//y-Position der linken oberen Ecke
   Lcd_sendbyte();
   Befehl = Kommando;
   Ausgabe = 0x75;
//Seitenadressierung
   Lcd_sendbyte();
   Befehl = Parameter;
   Ausgabe = 0;
//X-Position der rechten unteren Ecke
   Lcd_sendbyte();
   Ausgabe = 131;
//y-Position der rechten unteren Ecke
   Lcd_sendbyte();

   Befehl = Kommando;
   Ausgabe = 0x5C;
   Lcd_sendbyte();

  for (int f=0; f<17424; f++)
  {
    Befehl = Parameter;
    Ausgabe = 0xff;
    Lcd_sendbyte();
  }
}

Mfg Andreas

von Jens D. (jens) Benutzerseite


Lesenswert?

??
keine main()??
warum nutzt du nicht das hardware SPI??

könntest du mal die bascom version posten??

Gruss Jens

von Thorsten L. (tlauf)


Lesenswert?

Ohne Main() Routine kann das garnicht klappen, da der Controller erst
immer die main() Routine "lädt", ohne diese "startet" er das
Programm garnicht.

Thorsten

von Sssssss (Gast)


Lesenswert?

also ich sehe dort definitiv eine main:

>int main (void)
>{
>DDRA = 0xff;
>Lcd_init();
>Lcd_cls();
>  for(;;)
>  {
>  }
>}

ganz oben ,)

von Brede Andreas (Gast)


Lesenswert?

Danke schonmal für eure Antworten!

Ich würde gere die Bascom Version posten aber diese ist nicht
Opensource und da ich sie nicht programmiert habe darf ich sie nicht
einstellen, ich darf sie aber in andere Sprachen umsetzen laut
programmierer!

Main Funktion ist doch oben tut derzeit nur nicht viel.

Bin mir jetzt nicht sicher aber ich dachte das das Epson das Hardware
SPI nicht unterstüzt!

Der Fehler muss irgendewo im code sitzen.

von C-Anfänger (Gast)


Lesenswert?

Hallo,

der Original Bascom Code stammt von Speedservice und ist nicht gerade
toll programmiert, aber anscheinend funktioniert er, und das ist die
Hauptsache.

Aber Hut ab vor Peter Küsters (Speedservice), vermarktet
semiprofessionellen Code und Platinen - aber warum auch nicht!
Peter Küsters nicht sauer sein. Finde es wirklich toll welchen Mut
(Unternehmergeist) Du hast! Mehr solcher Leute tun der Hobby-Szene gut
und die Profis nehmen die "Wasserträgerarbeit" gerne an - und das zu
durchaus akzeptablen Preisen.

Bin mir nicht sicher ob Du den, umgeschriebene Source (Bascom -> C)
publik machen darfst?

Mit dem AVR C-Compiler bin ich nicht vertraut, aber nach ANSI-C gibt es
leider keine Binärschreibweise.

#define Weiss    11111111
// Weiss hat nicht den Wert 0xFF sondern 0xA98AC7


Ob sonst noch was falsch ist weiß ich nicht, aber Deine Shiftroutine
ist sehr kompliziert.

von Jens D. (jens) Benutzerseite


Lesenswert?

hmmh ob HW oder SOFT SPI ist dem Display egal..
nur SOFT SPI unterstuetzt evtl nicht jeder controller aber in der regel
sollte es kein thema sein..

gruss jens

von Holger (Gast)


Lesenswert?

Schade Schade Schade,

das wäre genau so ein code wie ich ihn bräuchte simple und einfach,
aber auch ich konnte den fehler nicht finden. HW oder SOFT SPI sollte
keine rolle spielen, da es mit dem Bascom Progi ja so läuft wenn ich
das richtig verstehe.

Also wenn jemand von euch noch eine Ahnung für das Problem weis wäre es
wäre auch ich dankbar dafür!

Mfg Holger

von C-Anfänger (Gast)


Lesenswert?

Hallo,

habe den BASCOM-Code in C übersetzt, nicht für AVR sondern für C167.
Sollte aber leicht auf GCC-AVR portierbar sein (ANSI-C). Muss ihn nur
noch in den nächsten Tagen austesten. Ich denke, dass er auch besser
ist als der Original Speedservice Code.

Habe nur ein Problem, ich weiss nicht ob ich ihn offen legen darf.
Warte darauf, dass Peter Küsters eine Stellung dazu nimmt, hat ja die
Rechte darauf.

von Dirk M. (avr-nix)


Lesenswert?

C-Anfänger: 1 Wenn du das in c Umschreiben kannst bist du schon etwas
weiter als ein Anfänger.

2 Welchen BASCOM Code hast du dafür benutzt?
Könntest du es mal hier rein posten?

von C-Anfänger (Gast)


Lesenswert?

Hallo,

wie schon weiter oben geschrieben, ist der original Code von
Speedservice Alias Peter Küsters.

Nähere Infos unter www.display3000.com bzw. www.speedservice.de

Die Portierung von Brede Andreas ist eine identische Übersetzung der
Bascom Init-Routine.

Allerdings ist die ShiftRoutine extrem kompliziert gelöst. Als Beispiel
meine Routine. Der _rol Befehl ist nicht ANSI-Konform kann aber mit <<
implementiert werden. Alle dBefehle sind #defines also Macros z.B.
#define dSPI_Wait  _nop(); _nop(); _nop()

Alle original Speedservice Kommentare wurden aus rechlichen Gründen
entfernt - sorry.
1
void vLCD6100_SendData(byte bData)
2
{
3
  // Software SPI (manuelle Port-Ansteuerung)
4
  byte bIndex;
5
6
  for (bIndex=8; bIndex>0; bIndex--)    
7
  {
8
    if (bData & _rol(0x01,bIndex-1))  
9
      dSPI_DataHi;              
10
    else
11
      dSPI_DataLo;              
12
13
    dSPI_Wait;
14
    dSPI_CLK_LOW;    
15
    dSPI_Wait;
16
    dSPI_CLK_HIGH;                 
17
  }
18
}
19
20
void vLCD6100_SendByte(flag fKommando, byte bData)
21
{
22
  dLCD_Enable;                      
23
  dSPI_CLK_LOW;                     
24
25
  if fKommando
26
   dSPI_DataLo;                      
27
  else
28
   dSPI_DataHi; 
29
  
30
  dSPI_Wait;                    
31
  dSPI_CLK_HI;
32
  dSPI_Wait;  
33
             
34
  vLCD6100_SendData(bData);          
35
  dLCD_Disable;                       
36
}

von C-Anfänger (Gast)


Lesenswert?

Nachtrag im formatierten Source-Code fallen einem noch ein paar Fehler
auf  - also nochmal
1
void vLCD6100_SendData(byte bData)
2
{
3
  // Software SPI (manuelle Port-Ansteuerung)
4
  byte bIndex;
5
6
  for (bIndex=8; bIndex>0; bIndex--)    
7
  {
8
    if (bData & _rol(0x01,bIndex-1))  
9
      dSPI_DataHi;              
10
    else
11
      dSPI_DataLo;              
12
13
    dSPI_Wait;
14
    dSPI_CLK_LOW;    
15
    dSPI_Wait;
16
    dSPI_CLK_HI;                 
17
  }
18
}
19
20
void vLCD6100_SendByte(flag fKommando, byte bData)
21
{
22
  dLCD_Enable;                      
23
  dSPI_CLK_LOW;                     
24
25
  if (fKommando)
26
   dSPI_DataLo;                      
27
  else
28
   dSPI_DataHi; 
29
  
30
  dSPI_Wait;                    
31
  dSPI_CLK_HI;
32
  dSPI_Wait;  
33
             
34
  vLCD6100_SendData(bData);          
35
  dLCD_Disable;                       
36
}

von Dirk M. (avr-nix)


Lesenswert?

Aso - habe vorher das nicht gelesen, sorry. Aber gute arbeit!

von thkais (Gast)


Lesenswert?

Ich habe einen C-Code geschrieben, der dieses Display via Hardware-SPI
ansteuert, allerdings basiert die Initialisierung des Displays auch auf
dem Code von Speedservice, und da habe ich schon ein wenig Bauchweh, den
einfach weiterzugeben. Speedservice liegt der C-Source vor.

von C-Anfänger (Gast)


Lesenswert?

Hallo,

also Grundsätzlich ist eine Hardware-SPI vorzuziehen. Die Software SPI
ist nur für das erste Debuggen von Vorteil.

Im übriegen kann man obigen Code natürlich in einer Funktion
zusammenfassen, wenn gleich 9Bit (Kommando oder Parameter,
Data)geshiftet werden.

von Dirk M. (avr-nix)


Lesenswert?

soviel ich weiß stand das auf der Homepage das das umschretben erlaubt
ist. Einfach mal nachschauen.

von Holger (Gast)


Lesenswert?

Hallo C-Anfänger

dein Code ist sehr interessant, und vorallem kurz. Könntest du evt.
eine beispielprogramm posten wo, das Display programm angesteuert wird
und sich das Display einfach nur in einer Bestimmten Farbe löchen tut?
Ich wäre dir dafür sehr Dankbar!!

Mfg Holger

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.