Projekte
BirgerT
nibo2_fork#01
bt_lib_grafix.c
Projekte
Forum
Doku
Öffentliche Projekte
Startseite
Beispielprogramme
Projekte von anderen
Welcome
Username
Passwort
Eingeloggt bleiben
Zugangsdaten vergessen?
Registrieren
Projektverwaltung
⇨ Please choose! ⇦
——————————————————
✎ Create new project...
★ Browse existing projects...
——————————————————
⚬ MotorTest#1
⚬ C Tutorial 8#1
⚬ NIBO2 C Project#1
⚙ C Tutorial 15#1
⚬ 2010_11_18_el_test001#1
nibo2_fork#01
BSD_license.h
bt_lib_debugutil.c
bt_lib_debugutil.h
bt_lib_glcd.c
bt_lib_glcd.h
bt_lib_grafix.c
bt_lib_grafix.h
bt_lib_terminal.c
bt_lib_terminal.h
bt_lib_uart.c
bt_lib_uart.h
bt_lib_utils.h
lumpylumpy.h
main.c
nibo2_audio.c
nibo2_audio.h
nibo2_copro.c
nibo2_copro.h
nibo2_copro_cmd.h
nibo2_font.h
nibo2_global.h
nibo2_main_menu.h
nibo2_pwm_leds.c
nibo2_pwm_leds.h
nibo2_register.c
nibo2_register.h
nibo2_sensors.c
nibo2_sensors.h
test_debugutil.h
test_gfx_draw.h
xmas1.h
Project details
Compiler settings
Nachrichten
Sie sind nicht eingeloggt.
Neuigkeiten
★
NiboRoboLib 3.6
2017-01-17: Neue Version 3.6
★
NiboRoboLib 3.4.1
2016-04-16: Neue Version 3.4.1
★
Coding Tutorial
2015-11-22: Jetzt auch für den NIBO burger!
Site-Statistic
7426 private projects
385 public projects
16180353 lines compiled
58212 builds
NIBO
@
nibo2_fork_01/bt_lib_grafix.c [read only]
////////////////////////////////////////////////////////////////////////// // // BT LIB GRAFIX Funktionen zum Zeichnen von Pixelgrafiken auf GLCD // // (c) Birger Töpelmann toepelmann(A)web.de Version 141016a // // ////////////////////////////////////////////////////////////////////////// // // BSD License see "license.h" // #include "BSD_license.h" // //#include "bt_lib_utils.h" // Sammlung von Makros und Typedefs #include "nibo2_global.h" // Nibo2 Global Header // // Original NIBO Font 5x8: // 1. Byte = Proportional Maske = Zeichenbreite, // 2..6 Byte = 5 Glyphspalten const char grafix_font[] PROGMEM = { // #include "nibo2_font.h" }; // //uint8_t glcd_type = 0; //uint8_t gfx_enmask = 0; // *************************************** LCD BUFFER ACCESS // Speicher Organisation des GrafikdisplayRAMs [2][8][64] // 2 Chips (KS0108) * 8 Pages * 64 Bytes uint8_t grafix_buffer[1024]; // Bildwiederholspeicher struct{ // Display Koordinaten uint8_t x, y, z, s, m, e; uint8_t *b; // Bufferadresse für x,y } glcd_pos, *pglcd_pos; #if 0 void glcd_enable(uint8_t pagemask) { gfx_enmask = pagemask; } uint8_t glcd_enabled() { return gfx_enmask; } #endif // *********************************************************** GRAFIX INIT void gfx_init() { gfx_fill(0); gfx_gotoXY(0,0); } // gfx_init /* ----------------------------------------------------- GLCD ANSI PRINT STRING: GLCD über ANSI Sequenzen steuern und Text im Terminalmodus ausgeben -> x, y == absolute Pixeladresse -------------------------------------------------------*/ // /***************************************************** VT100 / ANSI Controls // // #define ESC "\x1b" // Escape #define ED ESC"[2J" // Erase Display #define RST ESC"2c" // Display Reset #define CUP(z,s) ESC"["#z";"#s"H" // Cursor Position Zeile,Spalte #define CUU(z) ESC"["#z"A" // Cursor Up z Zeilen #define CUD(z) ESC"["#z"B" // Cursor Down z Zeilen #define CUF(s) ESC"["#s"C" // Cursor Forward s Spalten #define CUB(s) ESC"["#s"D" // Cursor Backward s Spalten #define SCP ESC"[s" // Save Cursor Position #define RCP ESC"[u" // Restore Cursor Position // // Zeichenattribute setzen #define SGR(p) ESC"["#p"m" // Set Grafics Rendition p // - Nibo2 GLCD - Tera Term - PuTTYtel // SGR(0) -> Standard Werte // SGR(1) -> Intensität (Fett) - ignoriert - Gelbe Schrift - hell // SGR(4) -> Unterstreichen ein - i.O. - i.O. - i.O. // SGR(5) -> Blinken ein - invers - Rote Schrift - i.O. (Setup) // SGR(7) -> Inverse Schrift - i.O. - i.O. - i.O. // SGR(8) -> Unsichtbare Schrift - ignoriert - ohne Funktion - ohne Funktion // // Lineattribute - Nibo2 GLCD = Attribut, Teraterm ohne Funktion, PuTTYtel = i.O. (ganze Zeile) #define DHO ESC"#3" // doppelte Höhe + doppelte Breite (obere Hälfte) #define DHU ESC"#4" // doppelte Höhe + doppelte Breite (untere Hälfte) #define DZB ESC"#6" // doppelte Zeichenbreite #define NRM ESC"#5" // Normale Zeichenbreite und -höhe // ***********************************************************************/ enum ansi_states{NORMAL_CHAR, ESC_DETECTED, CSI_DETECTED, LINE_ATTR, BIG_CHAR, CU_POS, CU_SAVE, CU_REST, GETNUM1, GETNUM2}; PGM_P gfx_ansi_strP(PGM_P str){ static uint8_t state, csi, attrl, cursavz, cursavs; static int8_t num1, num2; // Merker letzte Ausgabestringposition static PGM_P saveptr = 0; // Ist eine Ausgabe fortzusetzen (Zyklischer Aufruf)? if(str == 0){ str = saveptr; if(str == 0) return 0; // Stringausgabe fortsetzen do { char c = pgm_read_byte(str++); if (c == 0){ saveptr = 0; state = NORMAL_CHAR; return 0; } ////////////////////////////////////////////////////////////////////////// if (c < ' ') { // Steuerzeichen if (c == 0x1b) { // ESCAPE Zeichen state = ESC_DETECTED; } else if (c == 0x0d) { // Return gfx_curpos(0,1); } else if (c == 0x0a) { // neue Zeile // gfx_curpos(glcd_pos.z+1,0); gfx_curpos(glcd_pos.z+1,1); } } // if STEUERZEICHEN else if (state == NORMAL_CHAR) { // normales Zeichen if (attrl == 0) { gfx_print_char(c); } else { if (attrl == 6) { // Breitschrift gfx_print_bigchar(c,1,2); } else { // Große Schrift gfx_print_bigchar(c,2,2); } } } // if NORMAL_CHAR else if (state == ESC_DETECTED) { // ESC if (c == '[') { state = CSI_DETECTED; csi = NORMAL_CHAR; } else if (c == 'c') { // ESC"c" Reset Display gfx_curpos(1,1); gfx_fill(0); gfx_drawmode(GFX_DM_TERM); state = NORMAL_CHAR; } else if (c == '#') { // ESC"#" Lineattribut state = LINE_ATTR; } else { state = NORMAL_CHAR; // unbekannt -> ignorieren } } // if ESC_DETECTED else if (state == CSI_DETECTED) { // ESC"[" if (csi == NORMAL_CHAR) { csi = GETNUM1; num1 = 0; num2 = 0; } // die Zeichen hinter CSI sollten eine Zahl sein if ((c >= '0') && (c <= '9')) { c &= 0x0f; if (csi == GETNUM1) { num1 = 10 * num1 + c; } else if (csi == GETNUM2) { num2 = 10 * num2 + c; } } // das eigentliche Commando in der ESC Sequenz else if (c == ';') { // auf zweite Zahl abfragen csi = GETNUM2; } else if (c == 'J') { // Bildschirm loeschen if (num1 == 2) { gfx_curpos(1,1); gfx_fill(0); // glcd_drawmode(LCD_DM_TERM); } state = NORMAL_CHAR; } else if (c == 'H') { // Cursor positionieren if (num1 == 0) num1 = 1; if (num2 == 0) num2 = 1; csi = CU_POS; } else if (c == 'A') { // Cursor auf if (num1 == 0) num1 = 1; num1 = glcd_pos.z - num1; csi = CU_POS; } else if (c == 'B') { // Cursor ab if (num1 == 0) num1 = 1; num1 = glcd_pos.z + num1; csi = CU_POS; } else if (c == 'C') { // Cursor rechts if (num1 == 0) num1 = 1; num2 = glcd_pos.s + num1; num1 = 0; csi = CU_POS; } else if (c == 'D') { // Cursor links if (num1 == 0) num1 = 1; num2 = glcd_pos.s - num1; num1 = 0; csi = CU_POS; } ////////////////////////////////////////////////////////////////////////// else if (c == 'm') { // Attribute setzen if(num1 == 0) {glcd_pos.m = GFX_DM_TERM;} else if(num1 == 4) {glcd_pos.m |= GFX_DM_LINE;} else if(num1 == 5) {glcd_pos.m |= GFX_DM_INV;} // Blinken ? else if(num1 == 7) {glcd_pos.m |= GFX_DM_INV;} state = NORMAL_CHAR; } ////////////////////////////////////////////////////////////////////////// else if (c == 's') { // Cursor speichern cursavz = glcd_pos.z; cursavs = glcd_pos.s; state = NORMAL_CHAR; } else if (c == 'u') { // Cursor herstellen if (cursavz == 0) cursavz = glcd_pos.z; if (cursavs == 0) cursavs = glcd_pos.s; num1 = cursavz; num2 = cursavs; csi = CU_POS; } else { // kommt hier noch was? state = NORMAL_CHAR; } if (csi == CU_POS) { // num1 = zeile 1..8 if (num1 < 1) num1 = 1; else if (num1 > 8) num1 = 8; // num2 = spalte 1..21 if (num2 < 1) num2 = 1; else if (num1 > 21) num1 = 21; // .. gfx_curpos(num1,num2); state = NORMAL_CHAR; } } // if CSI_DETECTED else if (state == LINE_ATTR) { // ESC"#" if (c == '3') { // ESC"#3" BigChar oben attrl = 3; } else if (c == '4') { // ESC"#4" BigChar unten attrl = 4; // Zeile nach oben, und Text nochmal ausgeben gfx_curpos(glcd_pos.z-1,0); } else if (c == '5') { // ESC"#5" normale Groesse attrl = 0; } else if (c == '6') { // ESC"#6" Breitschrift attrl = 6; } state = NORMAL_CHAR; // unbekannt -> ignorieren } else state = NORMAL_CHAR; // unbekannt -> ignorieren ////////////////////////////////////////////////////////////////////////// /* if (print_avail() > 2) { print_char(c); } else { --str; saveptr = str; return str; } */ ////////////////////////////////////////////////////////////////////////// } while (1); } // Neuen Bildschirm ausgeben else { // Ist vorherige Ausgabe abgeschlossen? if (saveptr == 0) { saveptr = str; state = NORMAL_CHAR; } } return saveptr; } /* ----------------------------------------------------- GLCD CURSOR POS: Grafik Cursor (Punkt) absolut positionieren und Bufferpointer berechnen. -> z, s == Zeile, Spalte in die Cursor gesetzt wird eine 0 für z o. s wird ignoriert, oben links ist Zeile 1, Spalte 1 unten rechts ist Zeile 8, Spalte 21 -------------------------------------------------------*/ void gfx_curpos(uint8_t z, uint8_t s){ // Wertebegrenzung if ((z > 0) && (z <= 8)) { glcd_pos.z = z; z--; // Ein Zeichen ist 8 Pixel hoch glcd_pos.y = z * 8; // Grafik Y Pos } if ((s > 0) && (s <= 21)) { glcd_pos.s = s; s--; // ein Zeichen ist 6 Pixel breit glcd_pos.x = s * 6; // Grafik X-Pos // 21 * 6 == 126 (Display ist 128 Pixel breit) glcd_pos.x++; // Cursor einen Pixel zur Mitte rutschen } // Werte merken // glcd_pos.z = y/8; // Terminal Zeile // glcd_pos.s = x/6; // Terminal Spalte // Buffer Adresse setzen // grafix_buffer + 128 * (y / 8) + x glcd_pos.b = grafix_buffer + 16 * (glcd_pos.y & 0x38) + glcd_pos.x; // glcd_gotoXY(z*8,s*6); } /* ----------------------------------------------------- GLCD GOTO XY: Grafik Cursor (Punkt) absolut positionieren und Bufferpointer berechnen. -> x, y == absolute Pixeladresse -------------------------------------------------------*/ void gfx_gotoXY(uint8_t x, uint8_t y) { // Wertebegrenzung if (x > 127) x = 127; if (y > 63) y = 63; // Werte merken glcd_pos.x = x; // Grafik X-Pos glcd_pos.y = y; // Grafik Y Pos // glcd_pos.z = y/8; // Terminal Zeile // glcd_pos.s = x/5; // Terminal Spalte // Buffer Adresse setzen // grafix_buffer + 128 * (y / 8) + x glcd_pos.b = grafix_buffer + 16 * (y & 0x38) + x; } /* ----------------------------------------------------- GLCD MOVE XY: Grafik Cursor (Punkt) relativ positionieren und Bufferpointer berechnen. -> x, y == relative Pixeladresse -------------------------------------------------------*/ void gfx_moveXY(uint8_t x, uint8_t y){ gfx_gotoXY(glcd_pos.x+x, glcd_pos.y+y); } /* ----------------------------------------------------- LCD UPDATE: Das auszugebende Byte mit dem aktuellen Hintergrund entsprechend dem DrawMode verknüpfen und ausgeben. -> data = zu schreibendes Datenbyte mask = Maske welche Bits von data auszugeben sind @glcd_pos.dm == lcd Drawmode LCD_DM_SET = Überschreiben ------------------------------------------------------- */ void grafix_update(uint8_t data, uint8_t mask){ // Buffer Range Check if(glcd_pos.b >= (grafix_buffer + sizeof(grafix_buffer))) return; if(glcd_pos.b < grafix_buffer) return; // Byte aus Buffer lesen uint8_t read = *glcd_pos.b; // Invertierte Ausgabe // uint8_t draw = glcd_pos.m & ~(uint8_t) LCD_DM_INV; uint8_t draw = glcd_pos.m; if((draw & (uint8_t) GFX_DM_INV) != 0) data = ~data; draw &=3; // Daten mit Y-verschiebung maskieren data &= mask; // Drawmodi if(draw == GFX_DM_SET){ data |= read & ~mask; } else if(draw == GFX_DM_OR){ data |= read; } else if(draw == GFX_DM_XOR){ data ^= read; } else { //if(draw == GFX_DM_AND) data |= read & ~mask; data &= read; } // Byte in Buffer schreiben *glcd_pos.b = data; } /* ----------------------------------------------------- PRINT BIG CHAR: Ein Ascii-Zeichen 0x20..0x80 im aktuellen Font an der aktuellen xy-Position mit Vergrößerung in Höhe und/oder Breite ausgeben. Die X Position wird um die Zeichenbreite erhöht. -> chr = auszugebendes ASCII-Zeichen 32..128 h = Multiplikator Zeichenhöhe 1..3 w = Multiplikator Zeichenbreite 1..3 glcd_pos.dm = DrawMode glcd_pos.x ~.y = aktuelle Zeichenposition -------------------------------------------------------*/ void gfx_print_bigchar(char chr, uint8_t h, uint8_t w) { uint8_t ch = chr; if(h<1) h = 1; if(h>3) h = 3; if(w<1) w = 1; if(w>3) w = 3; // Bereichsgrenze und Index in Fonttabelle if((ch<0x20) || (ch>0x80)) ch = 0x80; ch -= 0x20; // const uint8_t *ptile = glcd_font + (6* (uint16_t)ch); // uint16_t ptile = (6* (uint16_t)ch); PGM_P ptile = grafix_font + (6* (uint16_t)ch); // Proportional Bitmaske // uint8_t mask = *ptile++; uint8_t mask = pgm_read_byte(ptile++); if((glcd_pos.m & GFX_DM_TERM) != 0) mask = 0x1f; // Bitzähler für neue x-position uint8_t xofs = 0; // Verschiebung in y-richtung 0..7 uint8_t yshift = glcd_pos.y & (uint8_t)7; // Ein Zeichen ist 5 Byte breit + 1 Leerspalte for(uint8_t i=0; i<6; i++){ // Ist das Fontbyte auszugeben? if(((mask &1)!=0) || (i > 4)){ // Lade Byte und Maske für LCD Update uint8_t td; // if(i<5) td = *ptile; if(i<5) td = pgm_read_byte(ptile); else td=0; // für die Leerspalte hinter Zeichen // Untertreichen ein ? if((glcd_pos.m & GFX_DM_LINE) != 0) td ^= 0x80; uint8_t tm = 0x80; uint32_t ltd = 0; uint32_t ltm = 0; // Zeichenausgabe mit doppelter Höhe if(h == 2){ do{ // ein Fontbit setzt 2 Zeichenbit ltd <<= 2; if((td & tm)==tm) ltd |= (uint8_t) 3; tm >>= 1; }while(tm != 0); ltm = 0x0000ffff; } // Zeichenausgabe mit dreifacher Höhe else if(h==3){ do{ // ein Fontbit setzt 3 Zeichenbit ltd <<= 3; if((td & tm)==tm) ltd |= (uint8_t) 7; tm >>= 1; }while(tm != 0); ltm = 0x00ffffff; } // Zeichenausgabe mit einfacher Höhe else{ do{ // ein Fontbit setzt 1 Zeichenbit ltd <<= 1; if((td & tm)==tm) ltd |= (uint8_t) 1; tm >>= 1; }while(tm != 0); ltm = 0x000000ff; } // Verschiebung in y-Richtung erforderlich? if(yshift>0){ // Verschieben in obere und untere Bytes ltd <<= yshift; ltm <<= yshift; } // Bufferpointer merken uint8_t *saveptr = glcd_pos.b; do{ // Grafikbytes und -maske für Ausgabe tm = ltm & (uint8_t) 0xff; // Abbruch wenn alle Bits gesetzt if(tm == 0) break; td = ltd & (uint8_t) 0xff; // Für die Zeichenbreite uint8_t tw = w; // Breitenzähler do{ grafix_update(td, tm); glcd_pos.b++; }while(--tw != 0); // die nächsten Bits für Zeichenhöhe ltd >>= 8; ltm >>= 8; // Bufferpointer für unteres Byte setzen glcd_pos.b += (128 - w); // solange bis Maske leer ist }while(tm!=0); // x-Position erhöhen xofs+=w; // Bufferzeiger erhöhen und begrenzen glcd_pos.b = saveptr + w; if(glcd_pos.b >= (grafix_buffer + sizeof(grafix_buffer))) glcd_pos.b = grafix_buffer; } // if Proportionalmaske // Fontzeiger erhöhen ptile++; // Ausgabemaske weiterschieben mask >>= 1; } // for Bytes / Zeichen // Ausgabeposition für nächstes Zeichen setzen gfx_gotoXY(glcd_pos.x + xofs, glcd_pos.y); } /* ----------------------------------------------------- PRINT CHAR: Ein Ascii-Zeichen 0x20..0x80 im aktuellen Font an der aktuellen xy-Position ausgeben. Die X Position wird um die Zeichenbreite erhöht. -> chr = auszugebendes ASCII-Zeichen 32..128 glcd_pos.dm = DrawMode glcd_pos.x ~.y = aktuelle Zeichenposition -------------------------------------------------------*/ void gfx_print_char(char chr){ uint8_t ch = chr; // Bereichsgrenze und Index in Fonttabelle if((ch<0x20) || (ch>0x80)) ch = 0x80; ch -= 0x20; // const uint8_t *ptile = glcd_font + (6* (uint16_t)ch); PGM_P ptile = grafix_font + (6* (uint16_t)ch); // Proportional Bitmaske // uint8_t mask = *ptile++; uint8_t mask = pgm_read_byte(ptile++); if((glcd_pos.m & GFX_DM_TERM) != 0) mask = 0x1f; // Bitzähler für neue x-position uint8_t xofs = 0; // Verschiebung in y-richtung 0..7 uint8_t yshift = glcd_pos.y & (uint8_t)7; // Ein Zeichen ist 5 Byte breit + 1 Leerspalte for(uint8_t i=0; i<6; i++){ // Ist das Fontbyte auszugeben? if(((mask &1)!=0) || (i > 4)){ // Lade Byte und Maske für LCD Update uint8_t td; // if(i<5) td = *ptile; if(i<5) td = pgm_read_byte(ptile); else td=0; // für die Leerspalte hinter Zeichen // Untertreichen ein ? if((glcd_pos.m & GFX_DM_LINE) != 0) td ^= 0x80; uint8_t tm = 0xff; // Verschiebung in y-Richtung erforderlich? if(yshift>0){ // Verschieben in oberes und unteres Byte uint16_t w_td = td; uint16_t w_tm = tm; w_td <<= yshift; w_tm <<= yshift; // Passt das untere Byte noch in den Buffer? if(glcd_pos.b < (grafix_buffer + 1024 - 128)){ // unteres Grafik Byte ausgeben glcd_pos.b +=128; td = HIBYTE(w_td); tm = HIBYTE(w_tm); grafix_update(td, tm); glcd_pos.b -=128; } // Lade oberes Grafik Byte td = LOBYTE(w_td); tm = LOBYTE(w_tm); } // Grafikbyte ausgeben grafix_update(td, tm); // x-Position erhöhen xofs++; // Bufferzeiger erhöhen und begrenzen if(glcd_pos.b < (grafix_buffer + 1024 - 2)) glcd_pos.b++; } // Fontzeiger erhöhen ptile++; // Ausgabemaske weiterschieben mask >>= 1; } // Ausgabeposition für nächstes Zeichen setzen gfx_gotoXY(glcd_pos.x + xofs, glcd_pos.y); } void gfx_print_str(char * str){ while(*str) gfx_print_char(*str++); } void gfx_print_str_P(PGM_P str){ while(pgm_read_byte(str)) gfx_print_char(pgm_read_byte(str++)); } char sprintfzeile[32]; int16_t gfx_printf(const char* str, ...){ va_list parg; va_start(parg,str); int16_t cp = vsprintf(sprintfzeile,str,parg); va_end(parg); gfx_print_str(sprintfzeile); return cp; } int16_t gfx_printf_P(PGM_P str, ...){ va_list parg; va_start(parg,str); int16_t cp = vsprintf_P(sprintfzeile,str,parg); va_end(parg); gfx_print_str(sprintfzeile); return cp; } /* ----------------------------------------------------- PIXEL: Ein Pixel an der aktuellen xy-Position ausgeben. -> val: 0 = Pixel löschen / 1 = Pixel setzen glcd_pos.dm = DrawMode glcd_pos.x ~.y = aktuelle Zeichenposition -------------------------------------------------------*/ void gfx_pixel(uint8_t val){ uint8_t data = val << (uint8_t)(glcd_pos.y & (uint8_t)0x07); grafix_update(data,data); } /* ----------------------------------------------------- SET PIXEL XY: Ein Pixel an der xy-Position ausgeben. die aktuelle xy-Position wird nicht geändert -> val: 0 = Pixel löschen / 1 = Pixel setzen glcd_pos.dm = DrawMode glcd_pos.x ~.y = aktuelle Zeichenposition -------------------------------------------------------*/ void gfx_setpixelXY(uint8_t x, uint8_t y, uint8_t val){ // Wertebegrenzung if (x > 127) x = 127; if (y > 63) y = 63; // Aktuellen Bufferpointer sichern uint8_t *glcd_posb = glcd_pos.b; // Buffer Adresse für die Ausgabe setzen glcd_pos.b = grafix_buffer + 16*(y & 0x38) + x; // Ausgabebit y-Verschiebung uint8_t mask = 1 << (uint8_t)(y & (uint8_t)0x07); uint8_t data = mask; //val << (uint8_t)(y & (uint8_t)0x07); if(val == 0) data = 0; grafix_update(data,mask); // uint8_t data = val << (uint8_t)(y & (uint8_t)0x07); // glcd_update(data,data); // Aktuellen Bufferpointer wieder herstellen glcd_pos.b = glcd_posb; } struct{ uint8_t glyph[8]; uint8_t vmask,hmask; }glcd_pen; /* ----------------------------------------------------- PEN FILL: Ein Pixel an der aktuellen xy-Position ausgeben. -> val: 0 = Pixel löschen / 1 = Pixel setzen glcd_pos.dm = DrawMode glcd_pos.x ~.y = aktuelle Zeichenposition -------------------------------------------------------*/ void glcd_pen_fill(uint8_t hmask, uint8_t vmask, uint8_t val){ glcd_pen.hmask = hmask; glcd_pen.vmask = vmask; for(uint8_t i=0; i<8; i++) glcd_pen.glyph[i] = val; } /* ----------------------------------------------------- PEN DRAW: Ein Pixel an der aktuellen xy-Position ausgeben. -> val: 0 = Pixel löschen / 1 = Pixel setzen glcd_pos.dm = DrawMode glcd_pos.x ~.y = aktuelle Zeichenposition -------------------------------------------------------*/ void gfx_pen_draw(uint8_t xpos, uint8_t ypos){ gfx_gotoXY(xpos,ypos); if((glcd_pen.hmask != 0) && (glcd_pen.vmask != 0)){ } else gfx_pixel(1); } //************************ void gfx_line(uint8_t xa, uint8_t ya, uint8_t xe, uint8_t ye, uint8_t val){ int16_t delta = 0; int8_t dkurz = xe-xa; int8_t dlang = ye-ya; int8_t steil = 0; if(abs(dkurz) > abs(dlang)){ int8_t tmp = dlang; dlang = dkurz; dkurz = tmp; steil = 1; } if(dlang != 0) delta = (dkurz << 8) / dlang; if(steil == 0){ if(dlang>0){ dlang += ya; for(int16_t d = 0x80 +(xa<<8); ya<=dlang; ++ya){ gfx_setpixelXY(d>>8,ya,val); d+=delta; } return; } dlang += ya; for(int16_t d = 0x80 +(xa<<8); ya>=dlang; --ya){ gfx_setpixelXY(d>>8,ya,val); d-=delta; } return; } // if steil != 0 if(dlang>0){ dlang += xa; for(int16_t d = 0x80 +(ya<<8); xa<=dlang; ++xa){ gfx_setpixelXY(xa,d>>8,val); d+=delta; } return; } dlang += xa; for(int16_t d = 0x80 +(ya<<8); xa>=dlang; --xa){ gfx_setpixelXY(xa,d>>8,val); d-=delta; } return; } //**************** /* ----------------------------------------------------- CIRCLE: Kreis zeichnen aus Achtelkreisen. Es werden nur die Pixelpositionen für ein Achtel-Kreis berechnet. Die anderen Positionen ergeben sich aus der Kreis Symmetrie. -> x,y: Kreismittelpunkt r : Radius val: 0 = Pixel löschen / 1 = Pixel setzen 2 = Kreis löschen / 3 = Kreis füllen mask: Maske für die darzustellenden Achtelkreise glcd_pos.dm = DrawMode glcd_pos.x ~.y = aktuelle Zeichenposition wird nicht verändert -------------------------------------------------------*/ void gfx_circle(uint8_t x, uint8_t y, uint8_t r, uint8_t val, uint8_t mask){ uint8_t cy = r; //unterer Startpunkt uint8_t cx = 0; // Startwerte für int16_t cd = 5- r*4; // Punkte berechnen int16_t dA = 12; // ohne weitere int16_t dB = 20- r*8; // Multiplikationen while(cx<=cy){ // Achtelkreis unten rechts 6:00 - 4:30 gfx_setpixelXY(x+cx, y+cy, val); // Achtelkreis unten links 6:00 - 7:30 gfx_setpixelXY(x-cx, y+cy, val); // Achtelkreis oben rechts 12:00 - 1:30 gfx_setpixelXY(x+cx, y-cy, val); // Achtelkreis oben links 10:30 - 12:00 gfx_setpixelXY(x-cx, y-cy, val); // Achtelkreis rechts oben 1:30 - 3:00 gfx_setpixelXY(x+cy, y-cx, val); // Achtelkreis links oben 9:00 - 10:30 gfx_setpixelXY(x-cy, y-cx, val); // Achtelkreis rechts unten 4:30 - 3:00 gfx_setpixelXY(x+cy, y+cx, val); // Achtelkreis links unten 7:30 - 9:00 gfx_setpixelXY(x-cy, y+cx, val); if(cd < 0){ cd += dA; dB += 8; } else{ cy--; cd += dB; dB += 16; } cx++; dA += 8; } } void gfx_circle2(uint8_t x, uint8_t y, uint8_t r, uint8_t val, uint8_t mask){ uint8_t cy = 0; //unterer Startpunkt uint8_t cx = r; // Startwerte für int8_t cd = 0; // Punkte berechnen while(cx>cy){ // Achtelkreis unten rechts 6:00 - 4:30 gfx_setpixelXY(x+cx, y+cy, val); // Achtelkreis unten links 6:00 - 7:30 gfx_setpixelXY(x-cx, y+cy, val); // Achtelkreis oben rechts 12:00 - 1:30 gfx_setpixelXY(x+cx, y-cy, val); // Achtelkreis oben links 10:30 - 12:00 gfx_setpixelXY(x-cx, y-cy, val); // Achtelkreis rechts oben 1:30 - 3:00 gfx_setpixelXY(x+cy, y-cx, val); // Achtelkreis links oben 9:00 - 10:30 gfx_setpixelXY(x-cy, y-cx, val); // Achtelkreis rechts unten 4:30 - 3:00 gfx_setpixelXY(x+cy, y+cx, val); // Achtelkreis links unten 7:30 - 9:00 gfx_setpixelXY(x-cy, y+cx, val); cd -= (--cx) - (++cy); if(cd < 0){ cd += cx++; } } } /* ----------------------------------------------------- DRAWMODE: Den Drawmode einstellen, der bestimmt wie auszugebende Pixel mit den aktuellen Pixel verknüpft werden sollen. -> dm: = DrawMode -> glcd_pos.dm LCD_DM_SET Überschreibmodus 1->1 0->0 LCD_DM_OR Oder LCD_DM_XOR Exoder LCD_DM_AND Und LCD_DM_INV Überschreibmodus invertiert LCD_DM_IOR LCD_DM_IXOR LCD_DM_IAND LCD_DM_TERM 0x08 LCD_DM_LINE 0x10 -------------------------------------------------------*/ uint8_t gfx_drawmode(uint8_t dm){ uint8_t tmp = glcd_pos.m; glcd_pos.m = (dm & (uint8_t)0x1f); return tmp; } /* ----------------------------------------------------- LCD Bildspeicher Interuptgesteuert an LCD ausgeben: Die Ausgabefunktionen können ohne blockierende Wartezeiten direkt in das eindimensionale Array des Bildspeichers schreiben. Für Drawmode Verknüpfung sind keine Display Lesefunktionen erforderlich. Das Display wird nur geschrieben, die Adresse hat ein Autoinkrement, und muss nur 1x /Page auf 0 gesetzt werden. -------------------------------------------------------*/ //ISR (TIMER2_COMP_vect){ // glcd_ISR(); // als static inline in nibo2_plc_glcd.h //} void gfx_fill(uint8_t data){ uint16_t ctr = sizeof(grafix_buffer); uint8_t *ptr = grafix_buffer; do{ *ptr++ = data; }while(--ctr); } void gfx_box(uint8_t width, uint8_t height, uint8_t data){ uint8_t x = glcd_pos.x; uint8_t y = glcd_pos.y; uint8_t mask = (uint8_t)0xff << (y & (uint8_t)0x07); while(height){ uint8_t rest = 8; rest -= (y & (uint8_t)0x07); if(height < rest){ mask &= (uint8_t)0xff >> (uint8_t)(height-rest); rest = height; } uint8_t i = width; while(i--){ grafix_update(data,mask); } height -= rest; y += rest; gfx_gotoXY(x,y); } } // // EOF
Compiler results:
Werbung
Online
carmelopetty36638757
mattbrock489364684
mckinleysiddons
warrenhinder6456