![]() ![]() INFO - FAQ - CC2-Forum - CCPro-Forum |
|
' ============================================================================ ' 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 |