SSD1306 DeviceGraphIOS

  • 1
  • 2
  • 3
  • Page 1 of 3
TheBeginner
Schreiberling
Avatar
Gender: n/a
Location: Wunsiedel Bayern
Age: 67
Posts: 768
Registered: 06 / 2013
Subject:

SSD1306 DeviceGraphIOS

 · 
Posted: 24.06.2015 - 16:30  ·  #1
Danke an Harry der mir dabei geholfen hat.

das einzige was ich noch nicht hinbekommen habe ist das ich $B0 LCD Adr vorher setzen muss
LCD_Adr:= $B0; // immer vor gDispRefresh setzen
gDispRefresh; // senden



Code

program gOLed;

{ $BOOTRST $03800}         {Reset Jump to $03800}
{$NOSHADOW}
{ $WG}                     {global Warnings off}

Device = mega32, VCC=5;

Import SysTick, LCDGraphic, I2Cport;

From System Import ;

From LCDGraphic Import CharSet;    {block CharSet, pixels}


Define
  ProcClock      = 14745600;       {Hertz}
  SysTick        = 10;             {msec}
  StackSize      = $0064, iData;
  FrameSize      = $0064, iData;

  LCDGraphic     = 128, 64, 8;        {x-pix, y-pix, accesswidth}
  GViewports     = 1, iData;          {logical ViewPorts, scalings}
  DefCharSet     = 'Graphchars.pchr'; {FileName}
  TGraphStr      = 21;                {Graphic Text String Length}
  LCDgraphMode   = column, iData;     // linear, column, readonly

  I2Cport        = PortB;
  I2Cdat         = 4;
  I2Cclk         = 3,0;
Implementation

{$IDATA}
{--------------------------------------------------------------}
{ Type Declarations }

type


{--------------------------------------------------------------}
{ Const Declarations }
Const

SCREEN_HOR_SIZE : byte = 128;
SCREEN_VER_SIZE : byte = 64;
SSD1306_SETCONTRAST                      : byte = $81;
SSD1306_DISPLAYALLON_RESUME              : byte = $A4;
SSD1306_DISPLAYALLON                     : byte = $A5;
SSD1306_NORMALDISPLAY                    : byte = $A6;
SSD1306_INVERTDISPLAY                    : byte = $A7;
SSD1306_DISPLAYOFF                       : byte = $AE;
SSD1306_DISPLAYON                        : byte = $AF;
SSD1306_SETDISPLAYOFFSET                 : byte = $D3;
SSD1306_SETCOMPINS                       : byte = $DA;
SSD1306_SETVCOMDETECT                    : byte = $DB;
SSD1306_SETDISPLAYCLOCKDIV               : byte = $D5;
SSD1306_SETPRECHARGE                     : byte = $D9;
SSD1306_SETMULTIPLEX                     : byte = $A8;
SSD1306_SETLOWCOLUMN                     : byte = $00;  
SSD1306_SETHIGHCOLUMN                    : byte = $10;  
SSD1306_SETSTARTLINE                     : byte = $40;  
SSD1306_MEMORYMODE                       : byte = $20;
SSD1306_COLUMNADDR                       : byte = $21; 
SSD1306_PAGEADDR                         : byte = $22; 
SSD1306_COMSCANINC                       : byte = $C0;
SSD1306_COMSCANDEC                       : byte = $C8;
SSD1306_SEGREMAP                         : byte = $A1;   
SSD1306_CHARGEPUMP                       : byte = $8D;
SSD1306_EXTERNALVCC                      : byte = $1;
SSD1306_SWITCHCAPVCC                     : byte = $2;

{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
var
  ii         :    word;
  LCD_Adr    :    byte;


procedure InitPorts;
begin
  PortA := %00000111;
  DDRA  := %00000000;     
  PortB := %00011000;
  DDRB  := %00011000;    
  PortC := %00000011;
  DDRC  := %00000011;     
  PortD := %00110000;
  DDRD  := %00110000;    
end InitPorts;


//$80 = Command
//$C0 = ein Datenbyte
//$40 = kontinuierlich Datenbytes
//------------------------------------------------------------------------------
//  Sende Command Oled
//------------------------------------------------------------------------------
Procedure ssd1306_command(cmd1 : byte);
Begin
   I2Cout($3C,$80,cmd1);
end ssd1306_command;

//------------------------------------------------------------------------------
// Sende Data Oled
//------------------------------------------------------------------------------
Procedure ssd1306_data(cmd1 : byte);
Begin
   I2Cout($3C,$40,cmd1);
end ssd1306_data;

//------------------------------------------------------------------------------
// Setze Oled Adresse
//------------------------------------------------------------------------------
Procedure SetAddress(page, lowerAddr,  higherAddr : Byte);
Begin
   ssd1306_command(page);
   ssd1306_command(lowerAddr);
   ssd1306_command(higherAddr);
End SetAddress;

//------------------------------------------------------------------------------
// // 0111100 = $3C   I2C Adresse
//------------------------------------------------------------------------------
Procedure Init_OLED;
Begin
  if I2Cstat($3C) then
// Init sequence for 128x64 OLED module
    ssd1306_command(SSD1306_DISPLAYOFF);                    // 0xAE
    ssd1306_command(SSD1306_SETDISPLAYCLOCKDIV);            // 0xD5
    ssd1306_command($80);                                   // the suggested ratio 0x80
// Multiplex Ratio
    ssd1306_command(SSD1306_SETMULTIPLEX);                  // 0xA8
    ssd1306_command($3F);                                   // alt 3F
// Display Offset
    ssd1306_command(SSD1306_SETDISPLAYOFFSET);              // 0xD3
    ssd1306_command($0);                                    // no offset
//Display Startline
    ssd1306_command(SSD1306_SETSTARTLINE);                  // $40
// Set Charge Pump
    ssd1306_command(SSD1306_CHARGEPUMP);                    // 0x8D
    ssd1306_command($14);
// Re-map
    ssd1306_command(SSD1306_SEGREMAP);                      // A1
// COM Output Scan Direction
    ssd1306_command(SSD1306_COMSCANDEC);                    // C8
// COM Pins Hardware Configuration
    ssd1306_command(SSD1306_SETCOMPINS);                    // 0xDA
    ssd1306_command($12);
// Contrast Control Register
    ssd1306_command(SSD1306_SETCONTRAST);                   // 0x81 Contrast
    ssd1306_command($CF);
// Set Pre Charge Period
    ssd1306_command(SSD1306_SETPRECHARGE);                  // 0xd9
    ssd1306_command($F1);                                   // alt 22 // $22 - External, $F1 - Internal
// Set VCOMH Deselect level
    ssd1306_command(SSD1306_SETVCOMDETECT);                 // 0xDB
    ssd1306_command($40);                                   // $40 $20
// Display OFF
    ssd1306_command(SSD1306_DISPLAYALLON_RESUME);           // 0xA4
    ssd1306_command(SSD1306_NORMALDISPLAY);                 // 0xA6
//--turn on oled panel
    ssd1306_command(SSD1306_DISPLAYON);                     // 0xAF
endif;
end Init_OLED;



{$D-}
UserDevice GraphIOS(cmd : byte; arg : byte);
// cmd=0 bedeutet RAM-Adresse auf oben links stellen
// cmd=1 bedeutet Datenausgabe
begin
  if cmd = 0 then
      SetAddress(LCD_Adr, $00, $10);
      ii:=0;
  else
      If ii < 128  then
          ssd1306_data(arg);
          Inc(ii);
          if ii > 127 then
            inc(LCD_Adr);
            SetAddress(LCD_Adr, $00, $10);
            ii:= 0;
          endif;
      EndIf;
  EndIf;
end;
{$D+}

{--------------------------------------------------------------}
{ Main Program }
{$IDATA}

begin
  EnableInts;
  InitPorts;

  mDelay(50);
  Init_OLED;
  mDelay(350);    // Muss rein sonst Display dunkel

   gClrScr(0);
   gDrawRect(0,0,127,63,$FF);
   gDrawString(10,30,2,2,TxtRot0,'Hello');
   gDrawString(10,50,1,1,TxtRot0,'hello !!!');
   LCD_Adr:= $B0;  // immer vor gDispRefresh setzen
   gDispRefresh;   // senden
  loop


  endloop;
end gOLed.
You must be logged in or your permissions are to low to see this Attachment(s).
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: SSD1306 DeviceGraphIOS

 · 
Posted: 24.06.2015 - 16:45  ·  #2
Hi Frank,

das LCD_adr wird normalerweise als Const deklariert ..... das ist doch die I2C-Adresse ?

Const
LCD_adr : byte = $B0;

Harry
TheBeginner
Schreiberling
Avatar
Gender: n/a
Location: Wunsiedel Bayern
Age: 67
Posts: 768
Registered: 06 / 2013
Subject:

Re: SSD1306 DeviceGraphIOS

 · 
Posted: 24.06.2015 - 17:26  ·  #3
Hallo Harry,
ne ne sorry das ist die erste Page Adresse, habe ich blöde gemacht.
Hätte PageAdr schreiben sollen.


PS. ich muss vorher immer die Var auf $B0 setzen.
ich weiß nicht wie man das anders machen könnte
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: SSD1306 DeviceGraphIOS

 · 
Posted: 24.06.2015 - 17:36  ·  #4
Hi Frank,

der SSD1306 kann maximal 128x64 Pixel, also gehe ich davon aus, daß der am Ende einer Page automatisch in die nächste Page springt. Du kannst dir also die Adressierung der Pages (bis auf die erste) sparen. Also cmd=0 auf oben links springen und dann die 8x128Byte übertragen.

Gruss
Harry

Das wird niemals ausgeführt ;) ..... doch wird es, ist aber unnötig. Laß es mal weg.
Code
          if ii > 127 then 
            inc(LCD_Adr); 
            SetAddress(LCD_Adr, $00, $10); 
            ii:= 0; 
          endif;
TheBeginner
Schreiberling
Avatar
Gender: n/a
Location: Wunsiedel Bayern
Age: 67
Posts: 768
Registered: 06 / 2013
Subject:

Re: SSD1306 DeviceGraphIOS

 · 
Posted: 24.06.2015 - 17:53  ·  #5
Harry wenn ich das raus nehme geht nichts mehr
rh
Administrator
Avatar
Gender:
Location: Germany
Age: 25
Homepage: e-lab.de
Posts: 5558
Registered: 03 / 2002
Subject:

Re: SSD1306 DeviceGraphIOS

 · 
Posted: 24.06.2015 - 18:26  ·  #6
@Harry, Frank,

so muss das gemacht werden:
Code
begin
  if cmd = 0 then
      LCD_Adr:= $B0;       // <<<<<<<<<<<<<<<<<<<
      SetAddress(LCD_Adr, $00, $10);
      ii:=0;
  else
      If ii < 128  then 

Dann kann man sich das weiter unten sparen!

rolf
TheBeginner
Schreiberling
Avatar
Gender: n/a
Location: Wunsiedel Bayern
Age: 67
Posts: 768
Registered: 06 / 2013
Subject:

Re: SSD1306 DeviceGraphIOS

 · 
Posted: 24.06.2015 - 19:36  ·  #7
Hallo Rolf, ne es geht nicht, schaue Code
auch wenn ich das wieder rein nehme gehts nicht
if ii > 127 then
inc(LCD_Adr);
SetAddress(LCD_Adr, $00, $10);
ii:= 0;
endif;


Code

{$D-}
UserDevice GraphIOS(cmd : byte; arg : byte);
begin
  if cmd = 0 then
      LCD_Adr:= $B0;
      SetAddress(LCD_Adr, $00, $10);
      ii:=0;
  else
      If ii < 128  then
          ssd1306_data(arg);
          Inc(ii);
          {
          if ii > 127 then
            inc(LCD_Adr);
            SetAddress(LCD_Adr, $00, $10);
            ii:= 0;
          endif;
          }
      EndIf;
  EndIf;
end;
{$D+}
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2135
Registered: 03 / 2003
Subject:

Re: SSD1306 DeviceGraphIOS

 · 
Posted: 24.06.2015 - 19:53  ·  #8
Hi Frank,

mach mal
Code

else
  SSD1306_Data(arg);
endif;

Wenn ich den Treiber richtig verstehe (und ich dachte das ist so :D) macht der beim Refresh 1x cmd=0 und sendet dann alle Daten in einem Rutsch mit cmd=1.

..... natürlich muß der SSD so konfiguriert sein, daß der bei den Daten autoincrementiert, d.h. daß er nachfolgende Daten automatisch in die nächste Display-Adresse schreibt.

Gruss
Harry
  • 1
  • 2
  • 3
  • Page 1 of 3
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 15 · Cache Hits: 14   138   152 · Page-Gen-Time: 0.034653s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI