Projekte
BirgerT
nibo2_fork#01
bt_lib_glcd.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_glcd.c [read only]
////////////////////////////////////////////////////////////////////////// // // BT LIB GLCD Ansteuerung Grafikdisplay 128x64 mit 2x KS0108 // // (c) Birger Töpelmann toepelmann(A)web.de Version 141014a // // INIT // // // SCHREIBEN // // // LESEN // // TODO // Funktionen dokumentieren // ////////////////////////////////////////////////////////////////////////// // // 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 // // Initialisierungskommandos an LCD Controller // const char glcd_initstr[] PROGMEM = {LCD_ON, LCD_OFS0, LCD_PAG0, LCD_ADR0}; // uint8_t glcd_type = 0; uint8_t gfx_enmask = 0; // // uint8_t glcd_wait(uint8_t chip); // *************************************** LCD BUFFER ACCESS // Speicher Organisation des GrafikdisplayRAMs [2][8][64] // 2 Chips (KS0108) * 8 Pages * 64 Bytes struct{ // Display Koordinaten uint8_t x, y, z, s, m, e; uint8_t *b; // Bufferadresse für x,y } glcd_pos, *pglcd_pos; void glcd_enable(uint8_t pagemask) { gfx_enmask = pagemask; } uint8_t glcd_enabled() { return gfx_enmask; } // *********************************************************** GLCD INIT void glcd_init() { // PORT G = PG0..PG4 LCD Control PORT // PG4 = LCD_RW 0 = Lesen 1 = Schreiben // PG3 = LCD_DI 0 = Instruction, 1 = Daten // PG2 = LCD_EN Taktsignal (Strobe) // PG1 = LCD_CS2 Chipselect (rechte Hälfte) // PG0 = LCD_CS1 Chipselect (linke Hälfte) // init in nibo2_glcd_h // LCD Steuerung = Port als Ausgänge LCD_CTRL_DDR |= 0x1f; LCD_CTRL_PORT &= ~0x1f; // LCD Datenbus auf Eingang LCD_DATA_DDR = 0; LCD_DATA_OUT = 0; // Pullup aus // für LCD Reset müssen zwei Pins Low sein // DDRB:0 LCD RST und SS ist als Ausgang initialisiert // DDRD:7 CO-PRO RST ist als Ausgang definiert LCD_DORESET; if(TSTBIT(PIND,PD7)){ CO_RST_L; delay_ms(1); CO_RST_H; } else { delay_ms(1); } LCD_NORESET; if(glcd_wait(0)) { glcd_type |= 1; for(uint8_t i=0; i<4; i++){ char data = pgm_read_byte(&glcd_initstr[i]); // glcd_wait(0); glcd_write(0,data); // glcd_wait(1); glcd_write(1,data); } glcd_fill(0); gfx_gotoXY(0,0); } } // init_glcd //* ****************************************** LCD Ausgabe ISR // Ausgabe des Bufferinhalts an das GLCD über Timerinterrupt // Pro Interrupt wird ein Grafikbyte ans LCD ausgegeben. // Der Aufruf sollte alle 200..1000ns erfolgen // Routine wird als Code in der Timer ISR eingefügt. static struct { uint8_t page; // aktuelle Displayseite 0..15 uint8_t cell; // Schrittzähler 1..64, 65, 66 uint8_t bnew; // Buffer wurde aktualisiert uint8_t *ptr; // Bildspeicher Bytezeiger } step = {0,0,0,grafix_buffer}; void glcd_ISR() { LCD_EN_L; // EnableBit Aus LCD_RW_WR; // Richtung schreiben if(gfx_enmask != 0) { if(step.page < 8) LCD_CHIP1; // ChipSelect else LCD_CHIP2; LCD_DATA_DDR = 0xff; // Datenport = Ausgang // Schritte 0..63 = 64 Bytes an akt. Page if(++step.cell < 65) { LCD_RS_DTA; // Register Select = Daten LCD_DATA_OUT = *step.ptr++; // Daten aus Buffer } // Schritt 64 = nächste Page und Chip auswählen else if(step.cell == 65) { LCD_RS_CMD; // Register Select = Command step.page++; // Page = 0..15 step.page &= 0x0f; if(step.page < 8) { // Page >=8 dann Chip2 LCD_CHIP1; } else { LCD_CHIP2; } // Pageadresse 0..7 an Chip 1 o. 2 LCD_DATA_OUT = LCD_PAG0 + (step.page & 0x07); // Bufferzeiger auf neue Page Adresse step.ptr--; step.ptr += step.cell; } // Schritt 65 = Adresse der Page auf 0 else { LCD_RS_CMD; // Register Select = Command LCD_DATA_OUT = LCD_ADR0; // Adresse = 0 step.cell = 0; // Schrittzähler Reset // Bufferzeiger auf Start für Chip Page if(step.page==0) { step.ptr = grafix_buffer; gfx_enmask = 0; } else if(step.page == 8) step.ptr = grafix_buffer +64; } // Daten am Displayport übernehmen LCD_EN_H; } } /* ----------------------------------------------------- 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 ------------------------------------------------------- */ #if 0 void glcd_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 & LCD_DM_INV) != 0) data = ~data; draw &=3; // Daten mit Y-verschiebung maskieren data &= mask; // Drawmodi if(draw == LCD_DM_SET){ data |= read & ~mask; } else if(draw == LCD_DM_OR){ data |= read; } else if(draw == LCD_DM_XOR){ data ^= read; } else { //if(draw == LCD_DM_AND) data |= read & ~mask; data &= read; } // Byte in Buffer schreiben *glcd_pos.b = data; } #endif #if 0 /* ----------------------------------------------------- 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); glcd_update(data,data); } #endif /* ----------------------------------------------------- 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 //} // *************************************** LCD LOW LEVEL ACCESS // ------------------------ Delayfunktion für das Enable Signal static inline void glcd_delay(){ // Laut Datenblatt soll EN mindestes 450ns (0,5us) aktiv sein delay_us(0.5); } /* ----------------------------------------------------- LCD READ: Ein Byte vom Display auslesen -> cmd == 0: Chip1 Statusbyte 1: Chip2 Statusbyte 2: Chip1 Datenbyte 3: Chip2 Datenbyte <- Statusbyte & 0x80 = Chip ist busy o. Datenbyte der vorher selektierten Adresse -------------------------------------------------------*/ uint8_t glcd_read(uint8_t cmd){ // ChipSelect: Chip1 oder Chip2 if((cmd & (uint8_t)1) == 0) LCD_CHIP1; else LCD_CHIP2; // RegisterSelect Status oder Daten if((cmd & (uint8_t)2) == 0) LCD_RS_CMD; else LCD_RS_DTA; // Datenport auf Eingang LCD_DATA_DDR = 0; // RW auf Read LCD_RW_RD; glcd_delay(); // Enable ein LCD_EN_H; glcd_delay(); // Daten lesen uint8_t data = LCD_DATA_IN; // Enable aus LCD_EN_L; return data; } /* ----------------------------------------------------- GLCD WRITE: Ein Byte ans Display ausgeben -> cmd == 0: Chip1 Kommandobyte 1: Chip2 Kommandobyte 2: Chip1 Datenbyte 3: Chip2 Datenbyte -> data = Befehlsbyte o. Datenbyte für vorher selektierte Adresse -------------------------------------------------------*/ void glcd_write(uint8_t cmd, uint8_t data){ // ChipSelecte if((cmd & (uint8_t)1) == 0) LCD_CHIP1; else LCD_CHIP2; // RegisterSelect if((cmd & (uint8_t)2) == 0) LCD_RS_CMD; else LCD_RS_DTA; // RW = Schreiben LCD_RW_WR; // Datenport auf Ausgang LCD_DATA_DDR = 0xff; LCD_DATA_OUT = data; glcd_delay(); // Enable Ein = Daten übernehmen LCD_EN_H; glcd_delay(); LCD_EN_L; // LCD_DATA_OUT = 0; // LCD_DATA_DDR = 0; } /* ----------------------------------------------------- LCD WAIT: Statusbyte lesen und auf !Busy warten -> chip == 0: Chip1 Status 1: Chip2 Status <- status == 0 = Display TimeOut 1 = Display ist Bereit -------------------------------------------------------*/ uint8_t glcd_wait(uint8_t chip){ chip &= (uint8_t)1; uint16_t timeout = 0xffff; // Register Select = Command LCD_RS_CMD; do{ // Display Status lesen und Busyflag testen if((glcd_read(chip) & (uint8_t)LCD_BUSY) == 0) return 1; } while(--timeout); return 0; } /* ----------------------------------------------------- LCD GOTO XY: Grafik Cursor (Punkt) positionieren und die dazugehörige Display Adresse aktivieren -> x, y == Pixeladresse -------------------------------------------------------*/ void glcd_gotoXY(uint8_t x, uint8_t y){ uint8_t cmd, dat; // Wertebegrenzung if(x>127) x = 127; if(y>63) y = 63; // Werte merken glcd_pos.x = x; glcd_pos.y = y; glcd_pos.z = y/8; glcd_pos.s = x/5; // ChipSelect if(x>63){ x -= 64; cmd = LCD_CMD2; }else{ cmd = LCD_CMD1; } // Adresse setzen dat = LCD_ADR0 + x; glcd_write(cmd,dat); // Seite setzen dat = LCD_PAG0 + glcd_pos.z; glcd_wait(LCD_CMD1); glcd_write(LCD_CMD1,dat); glcd_wait(LCD_CMD2); glcd_write(LCD_CMD2,dat); } /* ----------------------------------------------------- LCD FILL: LCD Speicher mit Bitmuster füllen -> data == Bitmuster (0 oder 0xff) -------------------------------------------------------*/ void glcd_fill(uint8_t data){ // 8 Seiten pro Controller for(uint8_t page=0; page<8; page++){ // Controller Kommandos Seite setzen uint8_t cmd = LCD_PAG0 + page; glcd_wait(LCD_CMD1); glcd_write(LCD_CMD1,cmd); glcd_wait(LCD_CMD2); glcd_write(LCD_CMD2,cmd); // Eine Seite hat 64 Spalten (Bytes) // Das Display macht einen Autoinkrement for(uint8_t col=0; col<64; col++){ glcd_wait(LCD_CMD1); glcd_write(LCD_DAT1,data); glcd_wait(LCD_CMD2); glcd_write(LCD_DAT2,data); } } // Erste Seite aktivieren glcd_wait(LCD_CMD1); glcd_write(LCD_CMD1,LCD_PAG0); glcd_wait(LCD_CMD2); glcd_write(LCD_CMD2,LCD_PAG0); } /* ----------------------------------------------------- LCD FADE: LCD Hintergrundbeleuchtung ein-/ausblenden -> val == Wert der Erhöhung pro aufruf <- aktueller Prozentwert nach der Erhöhung -------------------------------------------------------*/ uint8_t lcd_fade(int8_t val) { return pwm_lcd(pwm_lcd(111) + val); }
Compiler results:
Werbung
Online
Antonioyzc
calebalmeida1046603
candidaharrell99753
chasitycraddock1
michaellnl53864
warrenhinder6456