after few days trying, polishing, testing.... the code found in article in digital-diy.com forum, I suceed to run this little beautiful OLED graphic display 128x64 pixels, with SSD1306 controller, available in ebay for 5-6 USD.
I am sharing the working code with you, hoping that someone will put effort to incorporate this into GLCD.BAS, so the display become available to all.
Code: Select all
Program MINI_LCD
Device = 18F2520
Clock = 20
Dim oledWR As PORTC.0
Dim oledRD As PORTC.1
Dim oledCS As PORTC.4
Dim oledRESET As PORTC.2
Dim oledD_C As PORTC.3
Dim oledRESET_TRIS As TRISC.2
Dim oledCS_TRIS As TRISC.4
Dim oledRD_TRIS As TRISC.1
Dim oledWR_TRIS As TRISC.0
Dim oledD_C_TRIS As TRISC.3
Dim oledBus_TRIS As TRISB
Dim oledBus As LATB
Dim oledBus_PORT As PORTB
Dim count As Word
Const OFFSET = 2
Const SCREEN_HOR_SIZE = 128
Const SCREEN_VER_SIZE = 64
// OLED font 8x6 pixels
Public Const _font8x6() As Byte =
(
$00, $00, $00, $00, $00, $00 , // " " $20
$00, $00, $4f, $00, $00, $00 , // ! $21
$00, $07, $00, $07, $00, $00 , // " $22
$14, $7f, $14, $7f, $14, $00 , // # $23
$24, $2a, $7f, $2a, $12, $00 , // $ $24
$23, $13, $08, $64, $62, $00 , // % $25
$36, $49, $55, $22, $50, $00 , // & $26
$00, $05, $03, $00, $00, $00 , // ' $27
$00, $1c, $22, $41, $00, $00 , // ( $28
$00, $41, $22, $1c, $00, $00 , // ) $29
$14, $08, $3e, $08, $14, $00 , // * $2A
$08, $08, $3e, $08, $08, $00 , // + $2B
$00, $50, $30, $00, $00, $00 , // , $2C
$08, $08, $08, $08, $08, $00 , // - $2D
$00, $60, $60, $00, $00, $00 , // . $2E
$20, $10, $08, $04, $02, $00 , // / $2F
$3e, $51, $49, $45, $3e, $00 , // 0 $30
$00, $42, $7f, $40, $00, $00 , // 1 $31
$42, $61, $51, $49, $46, $00 , // 2 $32
$21, $41, $45, $4b, $31, $00 , // 3 $33
$18, $14, $12, $7f, $10, $00 , // 4 $34
$27, $45, $45, $45, $39, $00 , // 5 $35
$3c, $4a, $49, $49, $30, $00 , // 6 $36
$01, $71, $09, $05, $03, $00 , // 7 $37
$36, $49, $49, $49, $36, $00 , // 8 $38
$06, $49, $49, $29, $1e, $00 , // 9 $39
$00, $36, $36, $00, $00, $00 , // : $3A
$00, $56, $36, $00, $00, $00 , // ; $3B
$08, $14, $22, $41, $00, $00 , // < $3C
$14, $14, $14, $14, $14, $00 , // = $3D
$00, $41, $22, $14, $08, $00 , // > $3E
$02, $01, $51, $09, $06, $00 , // ? $3F
$32, $49, $79, $41, $3e, $00 , // @ $40
$7e, $11, $11, $11, $7e, $00 , // A $41
$7f, $49, $49, $49, $36, $00 , // B $42
$3e, $41, $41, $41, $22, $00 , // C $43
$7f, $41, $41, $22, $1c, $00 , // D $44
$7f, $49, $49, $49, $41, $00 , // E $45
$7f, $09, $09, $09, $01, $00 , // F $46
$3e, $41, $49, $49, $7a, $00 , // G $47
$7f, $08, $08, $08, $7f, $00 , // H $48
$00, $41, $7f, $41, $00, $00 , // I $49
$20, $40, $41, $3f, $01, $00 , // J $4A
$7f, $08, $14, $22, $41, $00 , // K $4B
$7f, $40, $40, $40, $40, $00 , // L $4C
$7f, $02, $0c, $02, $7f, $00 , // M $4D
$7f, $04, $08, $10, $7f, $00 , // N $4E
$3e, $41, $41, $41, $3e, $00 , // O $4F
$7f, $09, $09, $09, $06, $00 , // P $50
$3e, $41, $51, $21, $5e, $00 , // Q $51
$7f, $09, $19, $29, $46, $00 , // R $52
$46, $49, $49, $49, $31, $00 , // S $53
$01, $01, $7f, $01, $01, $00 , // T $54
$3f, $40, $40, $40, $3f, $00 , // U $55
$1f, $20, $40, $20, $1f, $00 , // V $56
$3f, $40, $38, $40, $3f, $00 , // W $57
$63, $14, $08, $14, $63, $00 , // X $58
$07, $08, $70, $08, $07, $00 , // Y $59
$61, $51, $49, $45, $43, $00 , // Z $5A
$00, $7f, $41, $41, $00, $00 , // [ $5B
$02, $04, $08, $10, $20, $00 , // "\" $5C
$00, $41, $41, $7f, $00, $00 , // ] $5D
$04, $02, $01, $02, $04, $00 , // ^ $5E
$40, $40, $40, $40, $40, $00 , // _ $5F
$00, $01, $02, $04, $00, $00 , // ` $60
$20, $54, $54, $54, $78, $00 , // a $61
$7f, $48, $44, $44, $38, $00 , // b $62
$38, $44, $44, $44, $20, $00 , // c $63
$38, $44, $44, $48, $7f, $00 , // d $64
$38, $54, $54, $54, $18, $00 , // e $65
$08, $7e, $09, $01, $02, $00 , // f $66
$0c, $52, $52, $52, $3e, $00 , // g $67
$7f, $08, $04, $04, $78, $00 , // h $68
$00, $44, $7d, $40, $00, $00 , // i $69
$20, $40, $44, $3d, $00, $00 , // j $6A
$7f, $10, $28, $44, $00, $00 , // k $6B
$00, $41, $7f, $40, $00, $00 , // l $6C
$7c, $04, $18, $04, $78, $00 , // m $6D
$7c, $08, $04, $04, $78, $00 , // n $6E
$38, $44, $44, $44, $38, $00 , // o $6F
$7c, $14, $14, $14, $08, $00 , // p $70
$08, $14, $14, $18, $7c, $00 , // q $71
$7c, $08, $04, $04, $08, $00 , // r $72
$48, $54, $54, $54, $20, $00 , // s $73
$04, $3f, $44, $40, $20, $00 , // t $74
$3c, $40, $40, $20, $7c, $00 , // u $75
$1c, $20, $40, $20, $1c, $00 , // v $76
$3c, $40, $30, $40, $3c, $00 , // w $77
$44, $28, $10, $28, $44, $00 , // x $78
$0c, $50, $50, $50, $3c, $00 , // y $79
$44, $64, $54, $4c, $44, $00 , // z $7A
$00, $08, $36, $41, $00, $00 , // { $7B
$00, $00, $7f, $00, $00, $00 , // | $7C
$00, $41, $36, $08, $00, $00 , // } $7D
$02, $01, $02, $04, $02, $00 , // ~ $7E
$00, $00, $00, $00, $00, $00 , // -- filler --
//----------------------------------------------------------//
// custom characters, mostly unuseful //
//----------------------------------------------------------//
$00, $7f, $45, $45, $45, $47 , // $80 - left half of folder
$44, $44, $44, $44, $7c, $00 // $81 - right half of folder
)
Include "Convert.bas"
Include "string.bas"
Public Sub Nop()
ASM
Nop
End ASM
End Sub
{*********************************************************************
* Function: WriteCommand()
* Overview: Writes command Word To the display controller. A delay
* is inserted at the End To meet the controller requirements
* on selected commands.
* Input: Command Byte To send To Device
* Output: none
********************************************************************}
Public Sub WriteCommand(cmd As Byte)
oledBus_TRIS = %00000000
oledBus = cmd // data on bus
oledRD = 1 // set RD
oledWR = 1 // set WR
oledD_C = 0 // clear DC(A0)
oledCS = 0 // clear CS (select device)
oledWR = 0 // clear WR (clock WR)
Nop()
oledWR = 1 // set WR (clock WR)
oledCS = 1 // set CS (
oledBus_TRIS = $FF
End Sub
{*********************************************************************
* Function: WriteData()
* Overview: Writes data word to the display controller. A delay
* is inserted at the end to meet the controller requirements
* on selected commands.
* Input: Data byte to send to device
* Output: none
********************************************************************}
Public Sub WriteData( data As Byte)
oledBus_TRIS = $00
oledBus = data
oledRD = 1
oledWR = 1
oledD_C = 1
oledCS = 0
oledWR = 0
Nop()
oledWR = 1
oledCS = 1
oledBus_TRIS = $FF
End Sub
Public Sub SetAddress(page As Byte, lowerAddr As Byte, higherAddr As Byte)
WriteCommand(page)
WriteCommand(lowerAddr)
WriteCommand(higherAddr)
End Sub
{*********************************************************************
* Function: FillDisplay()
* Overview: Fill the display with data. Use this to clear or set all
* display.
* Input: $ff(white display) or $00(clear display)
* Output: none
********************************************************************}
Public Sub FillDisplay(data As Byte)
Dim page As Byte
Dim col As Byte
For Page = $B0 To $B8
SetAddress(page, $00+OFFSET, $10)
For col = 0 To SCREEN_HOR_SIZE - 1
WriteData(data)
Next
Next
End Sub
{*********************************************************************
* Function: void ResetDevice()
* Input: none
* Output: none
* Overview: resets And initialize OLED
********************************************************************}
Public Sub ResetDevice()
Dim i As Byte
// Configure control pins
oledRESET_TRIS = 0
oledWR = 0
oledWR_TRIS = 0
oledRD = 0
oledRD_TRIS = 0
oledCS = 1
oledCS_TRIS = 0
oledD_C = 0
oledD_C_TRIS = 0
//Reset the device
oledRESET = 0
For i = 1 To 100
Next
oledRESET = 1
For i = 1 To 100
Next
// Setup Display
WriteCommand($ae)
WriteCommand($d5)
WriteCommand($80)
// Multiplex Ratio
WriteCommand($a8)
WriteCommand($3f)
// Display Offset
WriteCommand($d3)
WriteCommand($00)
// Display Start Line
WriteCommand($40)
// Set Charge Pump
WriteCommand($8d)
WriteCommand($14)
// Re-map
WriteCommand($a1)
// COM Output Scan Direction
WriteCommand($c8)
// COM Pins Hardware Configuration
WriteCommand($da)
WriteCommand($12)
// Contrast Control Register
WriteCommand($81)
WriteCommand($cf) // $9f - External, $CF - Internal
// Set Pre Charge Period
WriteCommand($d9)
WriteCommand($F1) // $22 - External, $F1 - Internal
// Set VCOMH Deselect level
WriteCommand($db)
WriteCommand($40)
// Display OFF
WriteCommand($a4)
//Normal or Inverse Display
WriteCommand($a6) // Normal display
// Display ON
WriteCommand($af)
//DelayMS(10)
End Sub
Public Sub oledWriteChar1x(letter As Char, page As Byte, column As Byte, invert As Boolean)
Dim b, i As Byte
Dim ix As Word
WriteCommand(page)
column = column + OFFSET
WriteCommand($00 + (column And $0F))
WriteCommand($10+((column>>4)And $0F))
ix = (StrToDec(letter) - StrToDec(" ")) * 6
For i = 0 To 5
b = _font8x6(ix + i)
If (invert) Then
b = Not(b)
EndIf
WriteData(b)
Next
End Sub
{*********************************************************************
* Function: oledPutROMStringInvertOption()
* Overview: Prints ROM stored strings.
* Input: pointer to ROM stored string, page, column and invert option
* Output: print the string on OLED
********************************************************************}
Public Sub oledPutROMStringInvertOption(ByRefConst RomString() As Byte, page As Byte, column As Byte, invert As Boolean)
Dim i, x As Byte
If((page>=0) And (page<8))
Then
i=column
page = page + $B0
//While(romstring())
For x = 0 To Bound(RomString())
oledWriteChar1x(romstring(x), page, i, invert)
//inc(ptr)
i=i+6
//Wend
Next
End If
End Sub
{*********************************************************************
* Function: oledPutImage()
* Overview: Puts on display ROM stored images.
* Input: pointer to ROM stored image array,
* Output:
********************************************************************}
Public Sub oledPutImage( ByRefConst RomString() As Byte, sizex As Byte, sizey As Byte, startx As Byte, starty As Byte)
Dim i, j, mask As Byte
Dim count As Integer
count=0
startx = startx + OFFSET
For i = $B0+starty To $B0+sizey
WriteCommand(i)
WriteCommand(startx And $0F)
WriteCommand($10 Or ((startx>>4) And $0F))
For j = 0 To sizex
Inc(count)
WriteData(Romstring(j+1))
Next
Next
End Sub
Public Sub oledWriteChar1x(letter As Byte, page As Byte, column As Byte, invert As Boolean)
Dim b, i As Byte
Dim ix As Word
ix = (letter - Byte(" ")) * 6 // Adjust character to table that starts at $20
For i = 0 To 5
b = _font8x6(ix + i)
If (invert) Then
b = Not(b)
EndIf
WriteData(b)
Next
End Sub
Public Sub oledPutString(text As String, page As Byte, column As Byte, invert As Boolean = false)
Dim i, x As Byte
If ((page>=0) And (page<8)) Then
i = column
page = page + $B0
x = 0
While(Byte(text(x))<>0)
oledWriteChar1x(text(x), page, i, invert)
Inc(x)
i = i+6
Wend
End If
End Sub
main:
ADCON1 = $0f
TRISA=0
LATA =0
DelayMS(10)
ResetDevice()
FillDisplay($FF)
DelayMS(200)
FillDisplay($00)
oledPutString("Line 1",0,0)
oledPutString("Line 2",1,0,TRUE)
oledPutString("Line 3",2,0)
oledPutString("Line 4",3,0,TRUE)
oledPutString("Line 5",4,0)
oledPutString("Line 6",5,0,TRUE)
oledPutString("Line 7",6,0)
oledPutString("Line 8",7,0,TRUE)
DelayMS(1500)
count=0
FillDisplay(0)
oledPutString("Count: ",0,0)
oledPutString("TEST PROG",7,0)
While true
Inc(count)
oledPutString(DecToStr(count),1,60)
delayms(100)
Wend