Der Nachfolger des WDR-Computerclub mit Wolfgang Back und Wolfgang Rudolph - ...und immer ein Bit übrigbehalten!


Das Forum zur C-Control-1
Welche C-Control-Varianten existieren?
Übersicht - Suchen - Neueste 50 Beiträge - Neuer Beitrag - Login - Registrieren
INFO - FAQ - CC2-Forum - CCPro-Forum 

 Demoprogramm: Linien und Kreise auf dem Display Kategorie: Open-Micro/Open-Mini/Open-Midi/Open-Macro/Open-Maxi (von Dietmar, Homepage - 26.08.2019 21:39)
 Als Antwort auf Re: OLED-I2C-Grafikdisplay für 5,99 EUR von das |_ Team - 8.08.2019 16:43
Dietmar nutzt:  Open-Micro, Open-Mini, Open-Midi, Open-Macro, Open-Maxi, Open-Mini M-Unit, Open-Mini Station


' ============================================================================
' Das preiswerte 0.96 Inch OLED-I2C-Display von AZ-Delivery ansprechen.
' Dieses Programm zeichnet Linien und Kreise per Bresenham-Algorithmus.
' In OCBASIC 1.12a_e1 auf der Open-Maxi von Dietmar Harlos am 25. August 2019
' ============================================================================

' Das Display ist grafikfähig und besitzt eine Auflösung von 128 mal 64 Pixel.
' Es kann über Amazon bezogen werden und kostet zur Zeit nur 5,99 EUR bei
' kostenlosem Versand:

' https://www.amazon.de/dp/B01L9GC470

' Das Display basiert auf der Controllertype SSD1306 und verfügt über einen
' I²C-Bus. Es wird an den I²C-Bus der Open-Maxi angeschlossen. Die Betriebs-
' spannung darf 3 bis 5 Volt betragen.

' Zum Erstellen der Demoprogramme zum Display habe ich diverse Quellen aus dem
' Internet verwendet. Unter anderem die folgende Diskussion in einem Forum:

' https://www.mikrocontroller.net/topic/415651

' Erst Betriebsspannung am Display anlegen, dann Open-Maxi-UB anlegen. Zum
' Resetten müssen beide Versorgungsspannungen getrennt werden.

' Der Bresenham-Algorithmus ist ein Algorithmus in der Computergrafik zum
' Zeichnen (Rastern) von Geraden oder Kreisen auf Rasteranzeigen:

' https://de.wikipedia.org/wiki/Bresenham-Algorithmus

' An dieser Stelle möchte ich mich bei Norbert Klein und bei Dirk vom L-Team
' für ihre Unterstützung bedanken.

' --- Definitionen für das System -------------------------------------------

INCLUDE "omax.def"         'Definitionen für die Open-Maxi

' --- Definitionen des Anwenders --------------------------------------------

DEFINE bitarrayaddr &h02aa 'Startadresse des Buffers (1024 Byte)

DEFINE OLED_I2C_ADDR  &h78 'Konstanten für OLED-I2C-Display
DEFINE OLED_DISP_OFF  &hAE
DEFINE OLED_DISP_ON   &hAF
DEFINE DISPLAY_WIDTH   128
DEFINE DISPLAY_HEIGHT   64
DEFINE DISPLAYSIZE    1024

DEFINE maxx DISPLAY_WIDTH-1 'Bildschirmgröße
DEFINE maxy DISPLAY_HEIGHT-1

DIM a,b,c,data,x,y BYTE    'einige Variablen definieren
DIM w WORD

DIM x0,y0,x1,y1,dx,dy,sx,sy,e1,e2 INT 'Variablen für Bresenham-Algorithmus

DEFINE radius x1           'Variablen für Kreis
DEFINE f y1                '(belegen den gleichen Speicher)
DEFINE ddF_x dx            '(x1 hat jetzt den Alternativnamen radius, usw.)
DEFINE ddF_y dy
DEFINE xc sx
DEFINE yc sy

' --- Das Hauptprogramm -----------------------------------------------------

End2Host=ON                'nach Programmende in den Host-Modus

PRINT "OLED-I2C-Display: Grafik"

POKE i2cdelay,1            'Schnellerer I²C-Bus

i2c_init                   'I2C-Bus initialisieren
oled_init                  'OLED-I2C-Display initialisieren

'line 0,0,maxx,maxy         'Linien im Buffer zeichnen
'line 0,maxy,maxx,0

FOR a=0 TO 130 STEP 10
  b=a*64/130

  line 0,b,a,maxy          'Linien im Buffer zeichnen
  line a,maxy,maxx,63-b
  line maxx,63-b,127-a,0
  line 127-a,0,0,b

  oled_refresh             'Buffer auf Display ausgeben
NEXT a

FOR a=5 TO 20 STEP 5
  circle 64,32,a           'Kreis im Buffer zeichnen
  oled_refresh             'Buffer auf Display ausgeben
NEXT a

END                        'Programmende, Neustart mit der Enter-Taste

' ----------------------------------------------------------------------------

' Bresenham-Algorithmus zum Linienzeichnen

PROCEDURE line(x0, y0, x1, y1)
  dx =  ABS(x1-x0)
  IF x0<x1 THEN sx=1 ELSE sx=-1
  dy = -ABS(y1-y0)
  IF y0<y1 THEN sy=1 ELSE sy=-1
  e1 = dx+dy

  WHILE TRUE
    pset x0,y0
    if x0=x1 AND y0=y1 THEN GOTO line_break
    e2 = 2*e1
    if e2>dy THEN ADD e1,dy : ADD x0,sx
    if e2<dx THEN ADD e1,dx : ADD y0,sy
  WEND
  #line_break

  RETURN
END PROCEDURE

' ----------------------------------------------------------------------------

' Bresenham-Algorithmus zum Zeichnen von Kreisen

PROCEDURE circle(x0, y0, radius)
  f = 1 - radius
  ddF_x = 0
  ddF_y = -2 * radius
  xc = 0
  yc = radius

  pset x0, y0 + radius
  pset x0, y0 - radius
  pset x0 + radius, y0
  pset x0 - radius, y0

  WHILE (xc < yc)
    IF f >= 0 THEN
      SUB yc,1
      ADD ddF_y,2
      ADD f,ddF_y
    END IF

    ADD xc,1
    ADD ddF_x,2
    ADD f,ddF_x + 1

    pset x0 + xc, y0 + yc
    pset x0 - xc, y0 + yc
    pset x0 + xc, y0 - yc
    pset x0 - xc, y0 - yc
    pset x0 + yc, y0 + xc
    pset x0 - yc, y0 + xc
    pset x0 + yc, y0 - xc
    pset x0 - yc, y0 - xc
  WEND

  RETURN
END PROCEDURE

' ----------------------------------------------------------------------------

' Punkt im Buffer abfragen

FUNCTION point(x,y)
  IF x<0 OR x>maxx OR y<0 OR y>maxy THEN RETURN OFF
  RETURN bitarray_get(((y SHR 3) SHL 10)+(y AND 7)+(x SHL 3))
  'RETURN bitarray_get(y/8*1024+(y MOD 8)+x*8)
END FUNCTION

' Punkt im Buffer setzen

PROCEDURE pset(x,y)
  IF x<0 OR x>maxx OR y<0 OR y>maxy THEN RETURN
  bitarray_set(((y SHR 3) SHL 10)+(y AND 7)+(x SHL 3))
  RETURN
END PROCEDURE

' Punkt im Buffer löschen

PROCEDURE pclear(x,y)
  IF x<0 OR x>maxx OR y<0 OR y>maxy THEN RETURN
  bitarray_clear(((y SHR 3) SHL 10)+(y AND 7)+(x SHL 3))
  RETURN
END PROCEDURE

' ---------------------------------------------------------------------------
' Subroutinen für das OLED-I2C-Display
' ---------------------------------------------------------------------------

PROCEDURE oled_init
  PAUSE 2                  'etwas warten

  i2c_start
  IF i2c_write(OLED_I2C_ADDR)=0 THEN
    PRINT "OLED-I2C-Display reagiert nicht!"
    END
  END IF

  i2c_write &h00           '0x00 for command, 0x40 for data
  FOR a=0 TO 26
    i2c_write LOOKTABBYTE(init_sequence,a)
  NEXT a
  i2c_stop

  oled_command(OLED_DISP_ON)
  RETURN
END PROCEDURE

PROCEDURE oled_command(c)
  i2c_start
  i2c_write OLED_I2C_ADDR
  i2c_write &h00           '0x00 for command, 0x40 for data
  i2c_write c
  i2c_stop
  RETURN
END PROCEDURE

PROCEDURE oled_data(data)
  i2c_start
  i2c_write OLED_I2C_ADDR
  i2c_write &h40           '0x00 for command, 0x40 for data
  i2c_write data
  i2c_stop
  RETURN
END PROCEDURE

' x von 0 bis 127, y von 0 bis 63 (in 8-er Schritten)

PROCEDURE oled_gotoxy(x,y)
  i2c_start
  i2c_write OLED_I2C_ADDR
  i2c_write &h00           '0x00 for command, 0x40 for data
  i2c_write &hb0+(y SHR 3)
  i2c_write &h21
  i2c_write x
  i2c_write &h7f
  i2c_stop
  RETURN
END PROCEDURE

PROCEDURE oled_refresh
  oled_gotoxy 0,0

  i2c_start
  i2c_write OLED_I2C_ADDR
  i2c_write &h40           '0x00 for command, 0x40 for data

  FOR w=0 TO 1023
    i2c_write PEEK(bitarrayaddr+w)
  NEXT w

  i2c_stop
  RETURN
END PROCEDURE

' ---------------------------------------------------------------------------
' Tabellen
' ---------------------------------------------------------------------------

' Initialization Sequence für OLED-I2C-Display
' nach lcd_text.zip

TABLE init_sequence BYTE
    OLED_DISP_OFF, ' Display OFF (sleep mode)
    &h20, &h00,   ' Set Memory Addressing Mode
                  ' 00=Horizontal Addressing Mode; 01=Vertical Addressing Mode;
                  ' 10=Page Addressing Mode (RESET); 11=Invalid
    &hB0,         ' Set Page Start Address for Page Addressing Mode, 0-7
    &hC8,         ' Set COM Output Scan Direction
    &h00,         ' --set low column address
    &h10,         ' --set high column address
    &h40,         ' --set start line address
    &h81, &h3F    ' Set contrast control register
    &hA1,         ' Set Segment Re-map. A0=address mapped; A1=address 127 mapped.
    &hA6,         ' Set display mode. A6=Normal; A7=Inverse
    &hA8, 63      ' DISPLAY_HEIGHT-1    ' Set multiplex ratio(1 to 64)
    &hA4,         ' Output RAM to Display
                  ' &hA4=Output follows RAM content; &hA5,Output ignores RAM content
    &hD3, &h00    ' Set display offset. 00 = no offset
    &hD5,         ' --set display clock divide ratio/oscillator frequency
    &hF0,         ' --set divide ratio
    &hD9, &h22    ' Set pre-charge period
    &hDA, &h12    ' Set com pins hardware configuration
    &hDB,         ' --set vcomh
    &h20,         ' &h20,0.77xVcc
    &h8D, &h14    ' Set DC-DC enable
END TABLE

' ---------------------------------------------------------------------------
' Die I2C-Routinen einbinden
' ---------------------------------------------------------------------------

INCLUDE "omax_i2c.pro"

' ---------------------------------------------------------------------------
' Die Bit-Feld-Routinen einbinden
' ---------------------------------------------------------------------------

INCLUDE "bitarray.pro"

' ---------------------------------------------------------------------------
' Die Firmware-Routinen einbinden
' ---------------------------------------------------------------------------

INCLUDE "om_fw.pro"

' --- Programmende ---------------------------------------------------------


Passender Link: Demoprogramm mit allen INCLUDE-Dateien als ZIP-Archiv

Meine Homepage: http://ccintern.dharlos.de

 Antwort schreiben

Bisherige Antworten:

Text und Grafik mischen (von Dietmar - 7.09.2019 1:54)
    Demoprogramm: Zufällige Kreise auf dem Display (von Dietmar - 12.09.2019 20:28)
    Re: Text und Grafik mischen (von das |_ Team - 7.09.2019 21:18)
        Re: Text und Grafik mischen (von Dietmar - 7.09.2019 22:14)