SSD1306 OLED controller support
Posted: Thu Mar 07, 2013 7:21 am
Hi,
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.
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