Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

SSD1306 SPI - Bascom wyświetlanie Fontów

MAREK MRK 13 Kwi 2016 12:18 1845 2
  • #1 13 Kwi 2016 12:18
    MAREK MRK
    Poziom 18  

    Witam, z racji że mam kilka wyświetlaczy OLED SSD1306 z komunikacją po SPI które leżą już kilka lat, postanowiłem zapoznać się z nimi bliżej. Wszystko działa fajnie tylko mam problem z wyświetlaniem fontów. Chciał bym przykładową grafikę wyświetlić ale za nic nie udaje mi się to. Może ktoś ma jakiś pomysł, albo przykład żeby podpatrzeć jak to jest zrobione po SPI w Bascom? Niestety nic nie mogłem wygooglować. Obecnie przedstawiam program testowy który działa:

    Code:

    $regfile = "m644pdef.dat"
    $crystal = 8000000
    $hwstack = 150
    $swstack = 150
    $framesize = 250

    Config Portd.7 = Output                                     'DISPLAY_SS CS
    Lcd_cs Alias Portd.7
    Lcd_cs = 1

    Config Porta.0 = Output                                     'DISPLAY_RS  DC
    Lcd_rs Alias Porta.0

    Config Portd.3 = Output                                     'Spi_mosi   D1
    Data_out Alias Portd.3

    Config Portd.4 = Output                                     'SPI_SCK    D0
    Lcd_clk Alias Portd.4
    Lcd_clk = 1

    Config Porta.6 = Output                                     'DISPLAY_Reset
    Lcd_rst Alias Porta.6

    Config Porta.4 = Output                                     'OLED ON
    Oled_on Alias Porta.4
    Oled_on = 1

    Declare Sub Lcd_init()
    Declare Sub Lcd_data_out(byval Data1 As Byte)
    Declare Sub Lcd_comm_out(byval Comm As Byte)
    Declare Sub Lcd_clear(byval Colo As Byte)
    Declare Sub Lcd_show()

    Declare Sub Lcd_text(byval S As String , Byval Xoffset As Byte , Byval Yoffset As Byte , Byval Fontset As Byte)
    Declare Sub Lcd_set_pixel(byval Xp As Byte , Byval Yp As Byte , Byval Colo As Byte)

    Const White = &HFF
    Const Black = &H00
    Dim Ddata(1024) As Byte                                     'Display Data Buffer

    Const Driver_typ = 0
    Call Lcd_init()                                             'Init Display

    Dim Zab As Byte
    Dim Text11 As String * 20

    '*******************************************************************************




    Do
       Call Lcd_text( "TEST" , 32 , 9 , 3)                      'Draw Text to Buffer
       Call Lcd_text( "OLED" , 26 , 30 , 2)                     'Draw Text to Buffer
       Call Lcd_text( "SSD1306" , 0 , 55 , 1)                   'Draw Text to Buffer
       Call Lcd_show()
       Wait 2
    Call Lcd_clear(black)                                       'Clear black
    Wait 2
    Call Lcd_clear(white)                                       'Clear white
    Wait 2
    Loop

    End
    '*******************************************************************************

    $include "My6_8.font"
    $include "My12_16.font"
    $include "Font.font"

    Sub Lcd_set_pixel(byval Xp As Byte , Byval Yp As Byte , Byval Colo As Byte)
       Local B1 As Byte , Zeiger As Word , Bitnr As Byte
       Decr Yp
       B1 = Yp / 8
       Zeiger = B1 * 128
       Zeiger = Zeiger + Xp

       Bitnr = Yp Mod 8
       If Colo = Black Then
          Ddata(zeiger).bitnr = 0
       Else
          Ddata(zeiger).bitnr = 1
       End If
    End Sub

    Sub Lcd_show()
       Local Page As Byte , Zab1 As Byte , Zab2 As Byte
       Local Point As Word
       Point = 1
       Page = &HB0                                              'Page Address + 0xB0
       Call Lcd_comm_out(&H40)                                  'Display start address + 0x40

       For Zab1 = 0 To 7
          Call Lcd_comm_out(page)                               'send page address
          Call Lcd_comm_out(&H10)                               'column address upper 4 bits + 0x10
       #if Driver_typ = 1
          Call Lcd_comm_out(&H00)                               'column address lower 4 bits + 0x00
       #else
          Call Lcd_comm_out(&H02)
       #endif
          Lcd_cs = 0
          Lcd_rs = 1
          For Zab2 = 1 To 128                                   '128 columns wide
             Shiftout Data_out , Lcd_clk , Ddata(point) , 1 , 8 ', 2
             Incr Point
          Next
          Lcd_cs = 1
          Incr Page                                             'after 128 columns, go to next page
       Next

    End Sub

    Sub Lcd_clear(byval Colo As Byte)
       Local Page As Byte , Zab1 As Byte , Zab2 As Word

       Page = &HB0                                              'Page Address + 0xB0
       Call Lcd_comm_out(&H40)                                  'Display start address + 0x40

       For Zab1 = 0 To 7
          Call Lcd_comm_out(page)                               'send page address
          Call Lcd_comm_out(&H10)                               'column address upper 4 bits + 0x10
       #if Driver_typ = 1
          Call Lcd_comm_out(&H00)                               'column address lower 4 bits + 0x00 H02 for SH1106
       #else
          Call Lcd_comm_out(&H02)
       #endif
          Lcd_cs = 0
          Lcd_rs = 1
          For Zab2 = 1 To 128                                   '128 columns wide
             Shiftout Data_out , Lcd_clk , Colo , 1 , 8         ', 2
          Next
          Lcd_cs = 1
          Incr Page                                             'after 128 columns, go to next page
       Next

       For Zab2 = 1 To 1024
          Ddata(zab2) = 0                                       'Clear Display Data Buffer
       Next

    End Sub

    Sub Lcd_data_out(byval Data1 As Byte)
       Lcd_cs = 0
       Lcd_rs = 1
       Shiftout Data_out , Lcd_clk , Data1 , 1 , 8              ', 10
       Lcd_cs = 1
    End Sub

    Sub Lcd_comm_out(byval Comm As Byte)
       Lcd_rs = 0
       Lcd_cs = 0
       Shiftout Data_out , Lcd_clk , Comm , 1 , 8               ', 10
       Lcd_cs = 1
    End Sub

    Sub Lcd_init()
       Lcd_rst = 0
       Waitms 100                                               'Reset Display
       Lcd_rst = 1
       Waitms 100

       Call Lcd_comm_out(&Hae)                                  'DISPLAYOFF
       Call Lcd_comm_out(&Hd5)                                  'SETDISPLAYCLOCKDIV
       Call Lcd_comm_out(&H80)                                  'ratio 0x80
       Call Lcd_comm_out(&Ha8)                                  'SETMULTIPLEX
       Call Lcd_comm_out(&H3f)                                  '  1f 128x32
       Call Lcd_comm_out(&Hd3)                                  'SETDISPLAYOFFSET
       Call Lcd_comm_out(&H00)

       Call Lcd_comm_out(&H8d)                                  'CHARGEPUMP
       Call Lcd_comm_out(&H14)                                  'vccstate 14
       Call Lcd_comm_out(&H20)                                  'MEMORYMODE
       Call Lcd_comm_out(&H00)                                  '
       Call Lcd_comm_out(&Ha1)                                  'SEGREMAP  a0
       Call Lcd_comm_out(&Hc8)                                  'COMSCANDEC

       Call Lcd_comm_out(&Hda)                                  'SETCOMPINS
       Call Lcd_comm_out(&H12)                                  ' 02 128x32  12
       Call Lcd_comm_out(&H81)                                  'SETCONTRAST
       Call Lcd_comm_out(85)                                    'value 1-->256
       Call Lcd_comm_out(&Hd9)                                  'SETPRECHARGE
       Call Lcd_comm_out(&Hf1)                                  'vccstate  f1
       Call Lcd_comm_out(&Hdb)                                  'SETVCOMDETECT

       Call Lcd_comm_out(&Ha4)                                  'DISPLAYALLON_RESUME
       Call Lcd_comm_out(&Ha6)                                  'NORMALDISPLAY

       Call Lcd_comm_out(&Haf)

       Waitms 100
    End Sub

    Sub Lcd_text(byval S As String , Xoffset As Byte , Yoffset As Byte , Fontset As Byte)
       Local Tempstring As String * 1 , Temp As Word
       Local A As Byte , Pixels As Byte , Count As Byte , Carcount As Byte , Lus As Byte
       Local Row As Byte , Block As Byte , Byteseach As Byte , Blocksize As Byte , Dummy As Byte
       Local Colums As Byte , Columcount As Byte , Rowcount As Byte , Stringsize As Byte
       Local Xpos As Byte , Ypos As Byte , Pixel As Word , Pixelcount As Byte
       Local Offset As Word

       Stringsize = Len(s) - 1                                  'Size of the text string -1 because we must start with 0
       Select Case Fontset
          Case 1 :
             Block = Lookup(0 , My6_8)                          'Add or remove here fontset's that you need or not,
             Byteseach = Lookup(1 , My6_8)
             Blocksize = Lookup(2 , My6_8)
             Dummy = Lookup(3 , My6_8)
          Case 2 :
             Block = Lookup(0 , My12_16)
             Byteseach = Lookup(1 , My12_16)
             Blocksize = Lookup(2 , My12_16)
             Dummy = Lookup(3 , My12_16)
          Case 3 :
             Block = Lookup(0 , Font)
             Byteseach = Lookup(1 , Font)
             Blocksize = Lookup(2 , Font)
             Dummy = Lookup(3 , Font)
       End Select
       Colums = Blocksize / Block                               'Calculate the numbers of colums
       Row = Block * 8                                          'Row is always 8 pixels high = 1 byte, so working with row in steps of 8.
       Row = Row - 1                                            'Want to start with row=0 instead of 1
       Colums = Colums - 1                                      'Same for the colums
       For Carcount = 0 To Stringsize                           'Loop for the numbers of caracters that must be displayed
          Temp = Carcount + 1                                   'Cut the text string in seperate caracters
          Tempstring = Mid(s , Temp , 1)
          Offset = Asc(tempstring) - 32                         'Font files start with caracter 32
          Offset = Offset * Blocksize
          Offset = Offset + 4
          Temp = Carcount * Byteseach
          Temp = Temp + Xoffset
          For Rowcount = 0 To Row Step 8                        'Loop for numbers of rows
             A = Rowcount + Yoffset
             Xpos = Temp
             For Columcount = 0 To Colums                       'Loop for numbers of Colums
                Select Case Fontset
                   Case 1 : Pixels = Lookup(offset , My6_8)
                   Case 2 : Pixels = Lookup(offset , My12_16)
                   Case 3 : Pixels = Lookup(offset , Font)
                End Select
                Ypos = A

                For Pixelcount = 0 To 7                         'Loop for 8 pixels to be set or not
                   Pixel = Pixels.0                             'Set the pixel (or not)
                   If Pixel = 1 Then
                      Call Lcd_set_pixel(xpos , Ypos , White)
                   Else
                      Call Lcd_set_pixel(xpos , Ypos , Black)
                   End If
                   Shift Pixels , Right                         'Shift the byte 1 bit to the right so the next pixel comes availible
                   Incr Ypos                                    'Each pixel on his own spot
                Next Pixelcount

                Incr Offset
                Incr Xpos                                       'Do some calculation to get the caracter on the correct Xposition
             Next Columcount
          Next Rowcount
       Next Carcount
    End Sub

    0 2
  • #2 13 Kwi 2016 20:23
    373522
    Użytkownik usunął konto  
  • #3 13 Kwi 2016 21:04
    MAREK MRK
    Poziom 18  

    No więc tak. Program udało mi się zlepić po przeczytaniu kilku przykładów. Program oczywiście działa. Mam zaimplementowane 3 czcionki i mogę wyświetlić dowolny tekst. Chodzi mi o wyświetlenie grafiki dajmy przykład Bateria albo coś innego np logo jakieś. Oczywiście jeśli się da to może być grafika BGF. Niestety nie mogę tego opanować na OLED, ale powoli rozgryzam więc był bym wdzięczny za każdą pomoc, nawet coś co dla innych może być oczywiste, dla mnie nie koniecznie bo to moje pierwsze OLED'y.
    ______________
    Chcąc wyświetlić grafikę BGF przy kompilacji wyrzuca błąd 5 na instrukcji SHOWPIC.
    ______
    11.05.2016
    Przerobiłem wyświetlacz na I2C i zrobiłem upgrade Bascom do najnowszej wersji i wszystko śmiga tak jak się należy. Bardzo pomocny był kolega z portalu kaktusa dodam że warto tam zajrzeć nie tylko ze względu na ten OLED.

    1