Guten morgen, na dann will ich mal zeigen wie ich das OLed 128x64 unter einen
AtMega8 zum laufen gebracht habe.
Als erstes erstmal die Const, zeige aber nur ein teil, sonst wird das posting zu lang.
Das ! brauche ich nicht und habe mit da ein Ohmzeichen einprogrammier.
Code
Const :
myarry : array[32..122,1..6] of byte =
(($00, $00, $00, $00, $00, $00) , // " " $20
($16, $19, $01, $19, $16, $00) , // ! $21 // Hier ist mein Ohmzeichen
usw.
($3e, $51, $49, $45, $3e, $00) , // 0 $30 6
($00, $42, $7f, $40, $00, $00) , // 1 $31 17---
($42, $61, $51, $49, $46, $00) , // 2 $32 8
usw
($7e, $11, $11, $11, $7e, $00) , // A $41
($7f, $49, $49, $49, $36, $00) , // B $42
($3e, $41, $41, $41, $22, $00) , // C $43
usw
($7e, $11, $11, $11, $7e, $00) , // A $41 33----
($7f, $49, $49, $49, $36, $00) , // B $42
($3e, $41, $41, $41, $22, $00) , // C $43
usw
Hier meine Init die ich aus dem Internet habe. (Zusammen gesucht habe)
Code
//------------------------------------------------------------------------------
// 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;
//------------------------------------------------------------------------------
// // 0111100 = $3C I2C Adresse
//------------------------------------------------------------------------------
Procedure Init_OLED;
var x : byte;
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;
Code
//------------------------------------------------------------------------------
// Setze Oled Adresse
//------------------------------------------------------------------------------
Procedure SetAddress(page, lowerAddr, higherAddr : Byte);
Begin
ssd1306_command(page);
ssd1306_command(lowerAddr);
ssd1306_command(higherAddr);
End SetAddress;
//------------------------------------------------------------------------------
// Function: ClearDisplay()
//------------------------------------------------------------------------------
Procedure ClearDisplay(data : Byte);
var page : Byte;
col : Byte;
begin
For Page := $B0 To $B8 do
SetAddress(page, $00 + OFFSET, $10);
For col := 0 To SCREEN_HOR_SIZE - 1 do
ssd1306_data(data);
endfor;
endfor;
end ClearDisplay;
//------------------------------------------------------------------------------
// Sende Char an Oled
//------------------------------------------------------------------------------
Procedure oledWriteChar1x(letter : char; page : Byte; column : Byte; invert : Boolean);
var
lx : string[3];
le : byte;
send : byte;
i : byte;
Begin
lx := IntToStr(Ord(letter));
le:= StrToint(lx);
for i:= 1 to 6 do
send:= myarry[le,i];
ssd1306_data(send);
endfor;
End oledWriteChar1x;
//------------------------------------------------------------------------------
// Prüfe Ausgabe
//------------------------------------------------------------------------------
Procedure oledString(text:String[16]; page:Byte; column:Byte; invert:Boolean);
var i, x : Byte;
Begin
If ((page > = 0) And (page < 8)) Then
i := column;
page := page + $B0; //Page Adresse B0 = page0 B1 = page1
x := 0;
ssd1306_command(page);
ssd1306_command($00 + (column And $0F));
ssd1306_command($10 + ((column shr 4)And $0F));
For x:= 1 to length(text) do
oledWriteChar1x(text[x], page, i, invert);
endfor;
EndIf;
End oledString;
Nach EnableInts; MUSS ein mDelay(350) rein, sonst gehts nicht
Code
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitPorts;
EnableInts;
mDelay(350); // Das muss so lange sein, sonst gehts nicht.
Init_OLED;
oledString('123ABCabc ' ,2,0,true);
Und wie gesagt, es läuft in ein AtMega 8 und ich habe noch genug Platz für meine
app. Chip ist gerade mal 60% voll mit ein paar anderen Proceduren.
Gruß Frank