Code:
// LCD
//Einstellung für vorgeladene ASCII Zeichen im Display
#define PRELOADLCDCHARS 1
#if PRELOADLCDCHARS==1
const uint8_t chrdata[64] MEM = {
// LCD_GC_CHAR0 124=|
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000100,
0b00000000,
// LCD_GC_CHAR1 252=ü
0b00001010,
0b00000000,
0b00010001,
0b00010001,
0b00010001,
0b00010011,
0b00001101,
0b00000000,
// LCD_GC_CHAR2 228=ä
0b00001010,
0b00000000,
0b00001110,
0b00000001,
0b00001111,
0b00010001,
0b00001111,
0b00000000,
// LCD_GC_CHAR3 246=ö
0b00001010,
0b00000000,
0b00001110,
0b00010001,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
// LCD_GC_CHAR4 220=Ü
0b00001010,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
// LCD_GC_CHAR5 196=Ä
0b00001010,
0b00001110,
0b00010001,
0b00010001,
0b00011111,
0b00010001,
0b00010001,
0b00000000,
// LCD_GC_CHAR6 214=Ö
0b00001010,
0b00001110,
0b00010001,
0b00010001,
0b00010001,
0b00010001,
0b00001110,
0b00000000,
// LCD_GC_CHAR7 223=ß
0b00001100,
0b00001010,
0b00001110,
0b00001001,
0b00001001,
0b00001010,
0b00001000,
0b00000000
};
#endif
const char lcd_wheelchar[] MEM = ".,oO0*0Oo,. "; // sinnvoll wäre auch noch const char wheel[] = "0123456789ABCDEF";
const uint8_t LCDLineAdr[] = {LCD_START_LINE1, LCD_START_LINE2, LCD_START_LINE3, LCD_START_LINE4};
#define LCDwheelsize (sizeof(lcd_wheelchar)-1)
static uint8_t lcd_cpos; // nächste Schreibadresse bzw. Cursorposition im Display
static uint8_t lcd_line;
/**
* Sendet Daten an das M32LCD, für andere LCD Anschlüsse muss nur die Ausgabe per writeSPI angepasst werden
*/
void m32lcd_data( uint8_t data, uint8_t mode )
{
if (mode!=LCD_SINGLE) {
if (mode==LCD_DATA) PORTB |= LCD_RS;// RS setzen / data
else PORTB &= ~LCD_RS; // RS löschen / byte cmd
externalPort.LCDD = data >> 4;
writeSPI(externalPort.byte);
PORTD |= STR;
PORTB |= LCD_EN;
PORTD &= ~STR;
_delay_us(LCD_ENABLE_US);
PORTB &= ~LCD_EN;
} else PORTB &= ~LCD_RS; // RS löschen / nibble cmd
externalPort.LCDD = data & 0x0f;
writeSPI(externalPort.byte);
PORTD |= STR;
PORTB |= LCD_EN;
PORTD &= ~STR;
_delay_us(LCD_ENABLE_US);
PORTB &= ~LCD_EN;
_delay_us(LCD_ENABLE_US);
if (mode==LCD_DATA){
_delay_us( LCD_WRITEDATA_US );
lcd_cpos++; // Cursor increment
}
else _delay_ms( LCD_WRITECMD_MS );
}
/**
* Initialize the LCD. Always call this before using the LCD!
*/
void initLCD(void)
{
uint8_t i;
// _delay_ms(LCD_BOOTUP_MS , LCD_SINGLE); No need for Power ON delay as usually the
// Bootloader should have been executed before...
PORTB &= ~LCD_EN;
PORTB &= ~LCD_RS;
_delay_ms(15);
for(i=0;i<2;++i) {
m32lcd_data(0x3 , LCD_SINGLE);
_delay_ms(2);
} //Reset
// 4-bit Modus aktivieren
m32lcd_data(0x2 , LCD_SINGLE);
_delay_ms(2);
// 4-bit Modus / 2 Zeilen / 5x7
m32lcd_data( LCD_SET_FUNCTION | LCD_FUNCTION_4BIT | LCD_FUNCTION_2LINE | LCD_FUNCTION_5X7 , LCD_CMD);
// Display ein / Cursor aus / Blinken aus
m32lcd_data( LCD_SET_DISPLAY | LCD_DISPLAY_ON | LCD_CURSOR_OFF | LCD_BLINKING_OFF , LCD_CMD);
// Cursor inkrement / kein Scrollen
#if LCD_WRAP_LINES==1
m32lcd_data( LCD_SET_ENTRY | LCD_ENTRY_INCREASE | LCD_ENTRY_NOSHIFT , LCD_CMD);
#else
m32lcd_data( LCD_SET_ENTRY | LCD_ENTRY_INCREASE | LCD_ENTRY_SHIFT , LCD_CMD);
#endif
// vordefinieren der 8 Sonderzeichen
#if PRELOADLCDCHARS==1
uint8_t eeval;
m32lcd_data( LCD_SET_CGADR , LCD_CMD );
for (i=0; i<64; i++ ) {
#if MEMORY==0
eeval = pgm_read_byte(&chrdata[i]);
#else
eeval = eeprom_read_byte(&chrdata[i]);
#endif
m32lcd_data( eeval , LCD_DATA);
}
#endif
// Clear
lcd_cpos=0;
lcd_line=0;
m32lcd_data(LCD_CLEAR_DISPLAY, LCD_CMD);
}
#ifdef WENEEDRP6IO
/**
* Clears the whole LCD!
*/
void clearLCD(void)
{
lcd_cpos=0;
lcd_line=0;
m32lcd_data(LCD_CLEAR_DISPLAY , LCD_CMD);
}
/**
* Write a single character to the LCD.
*/
void writeCharLCD(uint8_t ch)
{
m32lcd_data(ch , LCD_DATA);
}
/**
* Writes a null terminated string from flash program memory to the LCD.
* You can use the macro writeStringLCD_P(STRING); instead, this macro
* ensures that the String is stored in program memory only!
* Example:
* writeNStringLCD_P(PSTR("RP6 Control"));
* // There is also a Macro that makes life easier and
* // you can simply write:
* writeStringLCD_P("RP6 Control");
*/
void writeNStringLCD_P(const char *pstring)
{
uint8_t c;
for (;(c = pgm_read_byte_near(pstring++));m32lcd_data(c , LCD_DATA));
}
/**
* Writes a String from SRAM to the LCD.
*/
void writeStringLCD(char *string)
{
while(*string)
m32lcd_data(*string++ , LCD_DATA);
}
/**
* Writes a string with specified length and offset from SRAM to the LCD.
* If it is a null terminated string, output will be stopped at the
* end. It does not need to be null terminated, but it is recommended
* to use only null terminated strings/buffers, otherwise the function could
* output any SRAM memory data stored after the string until it reaches a 0
* or the specified length!
* Example:
* writeStringLength("RP6 Robot Sytem",16,0);
* // would output: "RP6 Robot Sytem\n"
* writeStringLength("RP6 Robot Sytem",11,4);
* // would output: "Robot System"
* writeStringLength("RP6 Robot Sytem",40,4);
* // would output: "Robot System"
* // No matter if the specified length is 40 characters!
*/
void writeStringLengthLCD(char *string, uint8_t length, uint8_t offset)
{
for(string = &string[offset]; *string && length; length--)
m32lcd_data(*string++ , LCD_DATA);
}
/**
* Write a number (with specified base) to the LCD.
* Example:
* // Write a hexadecimal number to the LCD:
* writeInteger(0xAACC,16);
* // Instead of 16 you can also write "HEX" as this is defined in the
* // RP6RobotBaseLib.h :
* writeInteger(0xAACC, HEX);
* // Other Formats:
* writeInteger(1024,DEC); // Decimal
* writeInteger(511,OCT); // Ocal
* writeInteger(0b11010111,BIN); // Binary
*/
void writeIntegerLCD(int16_t number, uint8_t base)
{
char buffer[17];
itoa(number, &buffer[0], base);
writeStringLCD(&buffer[0]);
}
/**
* Same as writeInteger, but with defined length.
* This means this routine will add leading zeros to the number if length is
* larger than the actual value or cut the upper digits if length is smaller
* than the actual value.
* Example:
* // Write a hexadecimal number to the LCD:
* writeIntegerLength(0xAACC, 16, 8);
* // Instead of 16 you can also write "HEX" as this is defined in the
* // RP6ControlLib.h :
* writeIntegerLength(0xAACC, HEX, 8);
* // Other Formats:
* writeIntegerLength(1024,DEC,6); // Decimal
* writeIntegerLength(511,OCT,4); // Ocal
* writeIntegerLength(0b11010111,BIN,8); // Binary
*/
void writeIntegerLengthLCD(int16_t number, uint8_t base, uint8_t length)
{
char buffer[17];
itoa(number, &buffer[0], base);
int8_t cnt = length - strlen(buffer);
if(cnt > 0) {
for(; cnt > 0; cnt--, writeCharLCD('0'));
writeStringLCD(&buffer[0]);
}
else
writeStringLengthLCD(&buffer[0],length,-cnt);
}
/**
* This function is useful for displaying text screens on the LCD.
* It clears the whole LCD and writes the two Strings to line 1 and
* line 2.
*/
void _showScreenLCD_P(const char *line1, const char *line2)
{
clearLCD();
writeNStringLCD_P(line1);
lcd_line=1;
m32lcd_data(LCD_SET_DDADR + LCDLineAdr[lcd_line] + lcd_cpos, LCD_CMD);
writeNStringLCD_P(line2);
}
/**
* Sets the cursor position on LCD.
*/
void setCursorPosLCD(uint8_t line, uint8_t pos)
{
if (line < LCD_LINES) {
lcd_line=line;
lcd_cpos=pos;
m32lcd_data(LCD_SET_DDADR + LCDLineAdr[line] + pos, LCD_CMD);
}
}
/**
* Clears some characters after the given position.
*/
void clearPosLCD(uint8_t line, uint8_t pos, uint8_t length)
{
lcd_line=0;
lcd_cpos=0;
m32lcd_data(LCD_SET_DDADR + LCDLineAdr[lcd_line] + lcd_cpos, LCD_CMD);
while(length--)
m32lcd_data(' ' , LCD_DATA);
}
/*****************************************************************************/
// die uart_2 lib für LCD
/*****************************************************************************/
void writeLongLCD(int32_t number, uint8_t base) {
char buffer[33];
ltoa(number, buffer, base); //->stdio
writeStringLCD(&buffer[0]);
}
void writeLongLengthLCD(int32_t number, uint8_t base, uint8_t length) {
char buffer[33];
ltoa(number, &buffer[0], base);
int8_t cnt = length - strlen(buffer);
if(cnt > 0) {
for(; cnt > 0; cnt--, writeCharLCD('0'));
writeStringLCD(&buffer[0]);
} else writeStringLengthLCD(&buffer[0], length, -cnt);
}
void writeDoubleLCD(double number, uint8_t width, uint8_t prec) {
char buffer[width + 1];
dtostrf(number, width, prec, buffer);
writeStringLCD(&buffer[0]);
}
void writeDoubleExpLCD(double number, uint8_t prec, uint8_t flags) {
char buffer[prec + 8];
dtostre(number, buffer, prec, flags);
writeStringLCD(&buffer[0]);
}
#endif
// die neuen LCD Funktionen
void lcd_CalcCursorUP(uint8_t setcursor){ //Boundary check upward
if ( lcd_cpos >= LCD_LINE_LENGTH ) { //linewrap prüfen und nächste Zeile setzen
lcd_cpos=0;
if (lcd_line >= LCD_LINES) lcd_line=0; else lcd_line++;
setcursor=true;
}
if (setcursor==true) m32lcd_data(LCD_SET_DDADR + LCDLineAdr[lcd_line] + lcd_cpos, LCD_CMD);
}
void lcd_CalcCursorDOWN(void){ //Boundary check downward
if (lcd_cpos > 0 ) lcd_cpos--;
else {
if (lcd_line > 0) lcd_line--;
else lcd_line=LCD_LINES-1;
lcd_cpos=LCD_LINE_LENGTH-1;
}
m32lcd_data(LCD_SET_DDADR + LCDLineAdr[lcd_line] + lcd_cpos, LCD_CMD);
}
/*****************************************************************************/
void lcd_putxy(char c, uint8_t line, uint8_t pos) //gibt Zeichen an xy aus
{
lcd_line=line;
lcd_cpos=pos;
lcd_CalcCursorUP(true);
m32lcd_data(c , LCD_DATA);
lcd_CalcCursorUP(false);
}
int16_t lcd_putchar(char c, __attribute__((unused)) FILE *stream)
{
//*********
#if LCDMODE==LCD_ASCII
static bool nl_seen;
static bool cursor_seen;
uint8_t i;
if (cursor_seen) { // erstes Zeichen nach \v, Cursorposition also \v%c
lcd_cpos = c % LCD_LINE_LENGTH;
lcd_line = (c / LCD_LINE_LENGTH) % LCD_LINES;
lcd_CalcCursorUP(true);
cursor_seen = false; //ok es geht weiter im String
return 1; // darf nicht zur weiteren Auswertung gelangen.
} else { // wenn keine Cursorposition, dann normales Zeichen
switch (c) { // Steuerzeichen nach ISO/IEC 6429
case '\a': // BELL Zeichen
sound(230,25,25);
break;
case '\t': // nächsten Tabulator ansteuern
lcd_cpos=lcd_cpos+LCD_TAB_SIZE-(lcd_cpos % LCD_TAB_SIZE);
lcd_CalcCursorUP(true);
break;
case '\r': // wagenrücklauf, nächste Zeile löschen
lcd_line++;
lcd_cpos=0;
lcd_CalcCursorUP(true);
for(i=0;i<LCD_LINE_LENGTH;i++) m32lcd_data(' ' , LCD_DATA);
lcd_cpos-=LCD_LINE_LENGTH;
lcd_CalcCursorUP(true);
break;
case '\v': //set cursor line, nächstes "char" ist der kumulierte cursorwert
cursor_seen = true;
break;
case '\x7f': // ist zwar ein Zeichen im Displayzeichensatz, aber laut ASCII das DEL char!
lcd_CalcCursorDOWN();
m32lcd_data(' ' , LCD_DATA);
case '\b': // 1 Zeichen zurück gehen, nicht löschen entspricht <- [cursor].
lcd_CalcCursorDOWN();
break;
case '\xff': // steht für signed -1, EOF, ALTSPACE, hier als "jumpover" bzw. SPACE ohne löschen / [cursor] ->
lcd_cpos++;
lcd_CalcCursorUP(true);
break;
case '\n': // indirekter löschbefehl
nl_seen = true;
break;
case '\f': // direkter löschbefehl
lcd_cpos=0;
lcd_line=0;
m32lcd_data(LCD_CLEAR_DISPLAY , LCD_CMD);
break;
default:
if (nl_seen && c != '\n') { // First character after newline, clear display and home cursor.
lcd_cpos=0;
lcd_line=0;
m32lcd_data(LCD_CLEAR_DISPLAY , LCD_CMD);
nl_seen = false;
}
#if PRELOADLCDCHARS==1
switch (c) { // Umsetzungstabelle für Sonderzeichen laut ISO/IEC 8859-1/15
case 124: // LCD_GC_CHAR0 124=|
c=0x80+LCD_GC_CHAR0;
break;
case 252: // LCD_GC_CHAR1 252=ü
c=0x80+LCD_GC_CHAR1;
break;
case 228: // LCD_GC_CHAR2 228=ä
c=0x80+LCD_GC_CHAR2;
break;
case 246: // LCD_GC_CHAR3 246=ö
c=0x80+LCD_GC_CHAR3;
break;
case 220: // LCD_GC_CHAR4 220=Ü
c=0x80+LCD_GC_CHAR4;
break;
case 196: // LCD_GC_CHAR5 196=Ä
c=0x80+LCD_GC_CHAR5;
break;
case 214: // LCD_GC_CHAR6 214=Ö
c=0x80+LCD_GC_CHAR6;
break;
case 223: // LCD_GC_CHAR7 223=ß
c=0x80+LCD_GC_CHAR7;
break;
}
#endif
if ((c >= ' ' && c <= '\x87')) { // ist das ein verwertbares Zeichen incl. CGCHAR?
m32lcd_data(c & 0x7f , LCD_DATA); // ggf. das "Steuerzeichenvehikel" für CGCHAR (0x80+CGCHAR) ausmaskieren
lcd_CalcCursorUP(false); //Linewrap berechen...
} else printf ("%c %x. ",c,c);
break;
}
}
//*********
#elif LCDMODE==LCD_BINARY
m32lcd_data(c , LCD_DATA); //nur ausgeben und cursor boundary berechnen/setzen
lcd_CalcCursorUP(false); //cursor boundary berechnen/setzen
#endif
return 0;
}
void lcd_wheel(uint8_t line, uint8_t pos) //sowas wie Sanduhr/Kringel oder rotierender Cursor, gut zum debuggen
{
static uint8_t i=0;
m32lcd_data(LCD_SET_DDADR + LCDLineAdr[line] + pos, LCD_CMD);
#if MEMORY==0
m32lcd_data(pgm_read_byte(&lcd_wheelchar[i++]), LCD_DATA);
#else
m32lcd_data(eeprom_read_byte(&lcd_wheelchar[i++]), LCD_DATA);
#endif
lcd_cpos-=1; // Cursor korrigieren, war ja kein reguläres char im Display
if (i==LCDwheelsize) i=0;
m32lcd_data(LCD_SET_DDADR + LCDLineAdr[lcd_line] + lcd_cpos, LCD_CMD);
}
uint8_t lcd_getCursorPos(void) // gibt aktuelle cursorposition als kumulierten Wert zurück
{
return ((lcd_line*LCD_LINE_LENGTH) + lcd_cpos);
}
void lcd_setCursorPos(uint8_t data) // setzt aktuelle cursorposition als kumulierten Wert
{
lcd_cpos = data % LCD_LINE_LENGTH;
lcd_line = (data / LCD_LINE_LENGTH) % LCD_LINES;
lcd_CalcCursorUP(true);
}
uint8_t lcd_xy(uint8_t line, uint8_t pos) // gibt x/y cursorposition als kumulierten Wert zurück
{
return ((line*LCD_LINE_LENGTH) + pos);
}
/*
* Erzeugt selbst definierte Zeichen im CGRAM, Beisp.:
* const uint8_t chrdata0[8] EEPMEM = {
* 0b00000000,
* 0b00000000,
* 0b00001010, // X X
* 0b00011111, // XXXXX
* 0b00001110, // XXX
* 0b00000100, // X
* 0b00000000,
* 0b00000000};
*
* lcd_generatechar(LCD_GC_CHAR0, chrdata0); //erzeugt 5x7 oder 5x10 char (+cursorline)
* Die Funktion erkennt selbst wie viel Byte einzulesen sind
* für 5x10 Zeichen muss das bitarray 11 lines haben und man kann nur jedes 2.te GCCHAR nutzen.
* Also LCD_GC_CHAR0, LCD_GC_CHAR2, LCD_GC_CHAR4 und LCD_GC_CHAR6
*/
void lcd_generatechar( uint8_t code, const uint8_t *data)
{
uint8_t i;
m32lcd_data( LCD_SET_CGADR | (code<<3) , LCD_CMD ); // Startposition des Zeichens einstellen
for (i=0; i<sizeof(data); i++ )
m32lcd_data( data[i] , LCD_DATA); // Zeichendaten byteweise hoch laden
lcd_cpos-=i; // Cursor korrigieren, war ja kein char im Display
m32lcd_data(LCD_SET_DDADR + LCDLineAdr[lcd_line] + lcd_cpos, LCD_CMD); // Zurück setzen auf alte cursor Position
}
/*****************************************************************************/
// Keypad:
Das gleiche macht man sinngemäß mit der RP6ControlLib.h und folgendem Code.
Code:
// LCD:
// zur Compile Zeit einstellbar:
#define LCD_ASCII 0 // wie ASCII Terminal, Steuerungszeichen werden verarbeitet
#define LCD_BINARY 1 // RAW Binärübertragung ohne Beeinflussung des Datenstroms
// Modus für putchar, wirkt sich auf die Codesize aus.
#define LCDMODE LCD_ASCII // Oder LCD_BINARY
// das Display selbt hat Eigenschaften:
#define LCD_LINES 0x02 //Anzahl Zeilen
#define LCD_DISP_LENGTH 0x10 //sichtbare Anzahl Zeichen pro Zeile IN HEX !!! 16Z=0x10,20Z=0x14,24Z=0x18
#define LCD_WRAP_LINES 1 // 0 buffer wrap?, 1 (default) wrap auf sichtbaren Zeilengrenzen*
#define LCD_TAB_SIZE 0x04 // Tabulator Position */
//*Die Einstellungen für Bufferwrap konnten noch nicht getestet werden
//Timings
#define LCD_BOOTUP_MS 0x28 //40ms
#define LCD_ENABLE_US 0x01 //1us
#define LCD_WRITEDATA_US 0x32 //50us
#define LCD_WRITECMD_MS 0x03 //3ms
//LCD Befehle
// Clear Display -------------- 0b00000001
#define LCD_CLEAR_DISPLAY 0x01
// Cursor Home ---------------- 0b0000001x
#define LCD_CURSOR_HOME 0x02
// Set Entry Mode ------------- 0b000001xx
#define LCD_SET_ENTRY 0x04
#define LCD_ENTRY_DECREASE 0x00
#define LCD_ENTRY_INCREASE 0x02
#define LCD_ENTRY_NOSHIFT 0x00
#define LCD_ENTRY_SHIFT 0x01
// Set Display ---------------- 0b00001xxx
#define LCD_SET_DISPLAY 0x08
#define LCD_DISPLAY_OFF 0x00
#define LCD_DISPLAY_ON 0x04
#define LCD_CURSOR_OFF 0x00
#define LCD_CURSOR_ON 0x02
#define LCD_BLINKING_OFF 0x00
#define LCD_BLINKING_ON 0x01
// Set Shift ------------------ 0b0001xxxx
#define LCD_SET_SHIFT 0x10
#define LCD_CURSOR_MOVE 0x00
#define LCD_DISPLAY_SHIFT 0x08
#define LCD_SHIFT_LEFT 0x00
#define LCD_SHIFT_RIGHT 0x04
// Set Function --------------- 0b001xxxxx
#define LCD_SOFT_RESET 0x30
#define LCD_SET_FUNCTION 0x20
#define LCD_FUNCTION_4BIT 0x00
#define LCD_FUNCTION_8BIT 0x10
#define LCD_FUNCTION_1LINE 0x00
#define LCD_FUNCTION_2LINE 0x08
#define LCD_FUNCTION_5X7 0x00
#define LCD_FUNCTION_5X10 0x04
// Set CG RAM Address --------- 0b01xxxxxx (Character Generator RAM)
#define LCD_SET_CGADR 0x40
#define LCD_GC_CHAR0 0
#define LCD_GC_CHAR1 1
#define LCD_GC_CHAR2 2
#define LCD_GC_CHAR3 3
#define LCD_GC_CHAR4 4
#define LCD_GC_CHAR5 5
#define LCD_GC_CHAR6 6
#define LCD_GC_CHAR7 7
// Set DD RAM Address --------- 0b1xxxxxxx (Display Data RAM)
#define LCD_SET_DDADR 0x80
// Modus für LCD-schreibfunktion (RP6 Spezifisch)
#define LCD_DATA 0 // 8 bit Daten mit RS1
#define LCD_CMD 1 // 8 bit Befehl mit RS0
#define LCD_SINGLE 2 // 4 bit init
#if LCD_WRAP_LINES==1
#define LCD_LINE_LENGTH LCD_DISP_LENGTH // wrap auf Display Sichtgrenzen
#else
#define LCD_LINE_LENGTH 0x40 // wrap auf Buffer Grenzen, Wert=Buffergröße
#endif
//Dispay Daten Adressen für 2x16, 4x16
#define LCD_START_LINE1 0x00
#define LCD_START_LINE2 0x40
#if LCD_DISP_LENGTH==16 // 16er Displays haben wohl andere Adressen für Line 3&4 als 20er
#define LCD_START_LINE3 0x10
#define LCD_START_LINE4 0x50
#else // 20 zeichen/line
#define LCD_START_LINE3 0x14
#define LCD_START_LINE4 0x54
#endif
// neue stdio Ausgabefunktion, alles andere würd über printf und Steuerzeichen gemacht.
int16_t lcd_putchar(char c, __attribute__((unused)) FILE *stream); // Ausgabe mit Steuerzeichen
// neue LCD Funktion
void lcd_wheel(uint8_t line, uint8_t ); // gibt eine Folge von chars als "Wheel" auf x/y aus
uint8_t lcd_getCursorPos(void); // gibt aktuelle cursorposition als kumulierten Wert zurück
void lcd_setCursorPos(uint8_t data); // setzt aktuelle cursorposition als kumulierten Wert
uint8_t lcd_xy(uint8_t line, uint8_t pos); // gibt x/y cursorposition als kumulierten Wert zurück
void lcd_generatechar( uint8_t code, const uint8_t *data); //schreibt Zeichen in CGRAM
// internal use
void m32lcd_data( uint8_t data, uint8_t mode ); // zentrale Schreibfunktion, Mode LCD_DATA/LCD_CMD/LCD_SINGLE
void lcd_CalcCursorUP(uint8_t setcursor); //Boundary check upward
void lcd_CalcCursorDOWN(void); //Boundary check downward
/*
Benutzung von lcd_generatechar()
const uint8_t chrdata0[8] = {
0b00000000,
0b00000000,
0b00001010, // X X
0b00011111, // XXXXX
0b00001110, // XXX
0b00000100, // X
0b00000000,
0b00000000
};
lcd_generatechar(LCD_GC_CHAR0, chrdata0);
m32lcd_data(LCD_GC_CHAR0,LCD_DATA); // als direkte Ausgabe im Display-Zeichensatz 0-7
//oder
fprintf(M32lcd,"LCD char: \x80"); // die 8 CGCHARS liegen also ab 0x80 bis 0x87 im ASCII Zeichensatz
*/
// alte und geänderte Funktionen
void initLCD(void);
#ifdef WENEEDRP6IO
void clearLCD(void);
void clearPosLCD(uint8_t line, uint8_t pos, uint8_t length);
void writeCharLCD(uint8_t ch);
#define writeStringLCD_P(__pstr) writeNStringLCD_P((PSTR(__pstr)))
void writeStringLengthLCD(char *string, uint8_t length, uint8_t offset);
void writeStringLCD(char *string);
void writeNStringLCD_P(const char *pstring);
void _showScreenLCD_P(const char *line1, const char *line2);
#define showScreenLCD(__line1,__line2); ({_showScreenLCD_P((PSTR(__line1)),(PSTR(__line2)));})
void writeIntegerLCD(int16_t number, uint8_t base);
void writeIntegerLengthLCD(int16_t number, uint8_t base, uint8_t length);
void setCursorPosLCD(uint8_t line, uint8_t pos);
/*****************************************************************************/
// die uart_2 lib
/*****************************************************************************/
#define PRECISION 6
#define DTOSTR_ALWAYS_SIGN 0x01
#define DTOSTR_PLUS_SIGN 0x02
#define DTOSTR_UPPERCASE 0x04
void writeLongLCD(int32_t number, uint8_t base);
void writeLongLengthLCD(int32_t number, uint8_t base, uint8_t length);
void writeDoubleLCD(double number, uint8_t width, uint8_t prec);
void writeDoubleExpLCD(double number, uint8_t prec, uint8_t flags);
/*****************************************************************************/
#endif
#ifndef HEX
#define HEX 16
#endif
#ifndef DEC
#define DEC 10
#endif
#ifndef OCT
#define OCT 8
#endif
#ifndef BIN
#define BIN 2
#endif
/*****************************************************************************/
// Keys:
NACHTRAG:
Lesezeichen