Commits vergleichen
91 Commits
Autor | SHA1 | Datum | |
---|---|---|---|
![]() |
1f58753823 | ||
![]() |
64341a0d5f | ||
![]() |
a48b2e11cb | ||
![]() |
d684610c00 | ||
![]() |
a8fb621eff | ||
![]() |
64c964d318 | ||
![]() |
525ecf6775 | ||
![]() |
4156fd4757 | ||
![]() |
c0b15fc20b | ||
![]() |
9a4ad9da42 | ||
![]() |
a9cd2b0baf | ||
![]() |
6eab4e7a36 | ||
![]() |
4a5bc75a1f | ||
![]() |
51aa9ebc5b | ||
![]() |
5f4084d9b5 | ||
![]() |
ef8b0b85ac | ||
![]() |
4db4927c8d | ||
![]() |
2693043cf2 | ||
![]() |
eae35b14aa | ||
![]() |
6e6558b7c4 | ||
![]() |
6a4b62579d | ||
![]() |
0dbd2a14d7 | ||
![]() |
7f42d3f89a | ||
![]() |
4b49d467c9 | ||
![]() |
0e14c81df2 | ||
![]() |
834f7875a3 | ||
![]() |
fa446f6111 | ||
![]() |
c8dce5e4a7 | ||
![]() |
c7a4bae4f8 | ||
![]() |
62a2b68e08 | ||
![]() |
76fd115015 | ||
![]() |
d388cf7a38 | ||
![]() |
9020ebcfb5 | ||
![]() |
0af7a4510b | ||
![]() |
d6b75b03a0 | ||
![]() |
f252207b4b | ||
![]() |
47b2d8f40e | ||
![]() |
857d0ac0ec | ||
![]() |
9139b4830d | ||
![]() |
82533902dd | ||
![]() |
52a024dff4 | ||
![]() |
6014d0996f | ||
![]() |
38a874c498 | ||
![]() |
c1958d225c | ||
![]() |
d28a7056a2 | ||
![]() |
981140645e | ||
![]() |
dc337751ab | ||
![]() |
08ceb8e31b | ||
![]() |
5c8717bcff | ||
![]() |
316a742613 | ||
![]() |
49661d6307 | ||
![]() |
ced1214fc8 | ||
![]() |
7e3bb2178f | ||
![]() |
2d89fc679b | ||
![]() |
6213e67b5e | ||
![]() |
ab1f3bc5a5 | ||
![]() |
f9b276eaf8 | ||
![]() |
a036086139 | ||
![]() |
61ca2e1dc7 | ||
![]() |
052b5f8509 | ||
![]() |
37f87540fb | ||
![]() |
ffbcc49066 | ||
![]() |
f168b52b65 | ||
![]() |
6f607980a5 | ||
![]() |
ab349346fe | ||
![]() |
db0972c8e9 | ||
![]() |
1dc61cedfb | ||
![]() |
02cf7f2216 | ||
![]() |
88f9e97cdd | ||
![]() |
94c5e66678 | ||
![]() |
f2746b5ff9 | ||
![]() |
ded0169f46 | ||
![]() |
59fcdf520a | ||
![]() |
9e96e2cb7f | ||
![]() |
06ac702c66 | ||
![]() |
a9260532d4 | ||
![]() |
509f1ace70 | ||
![]() |
10d5bb5bf0 | ||
![]() |
3c72a18a0e | ||
![]() |
0bc6f6b96e | ||
![]() |
519641b1e9 | ||
![]() |
53b690b329 | ||
![]() |
be58852484 | ||
![]() |
779310c839 | ||
![]() |
50929ad99a | ||
![]() |
827aa808dd | ||
![]() |
416ea430a4 | ||
![]() |
727bf2b507 | ||
![]() |
ecc3c11a5a | ||
![]() |
709cc1f78e | ||
![]() |
a9caa935b3 |
8
Makefile
8
Makefile
@ -42,7 +42,7 @@ MCU = atmega328p
|
|||||||
|
|
||||||
# Main Oscillator Frequency
|
# Main Oscillator Frequency
|
||||||
# This is only used to define F_CPU in all assembler and c-sources.
|
# This is only used to define F_CPU in all assembler and c-sources.
|
||||||
F_CPU = 14745600UL
|
F_CPU = 16000000UL
|
||||||
|
|
||||||
# Output format. (can be srec, ihex, binary)
|
# Output format. (can be srec, ihex, binary)
|
||||||
FORMAT = ihex
|
FORMAT = ihex
|
||||||
@ -52,7 +52,7 @@ TARGET = main
|
|||||||
|
|
||||||
|
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
# List C source files here. (C dependencies are automatically generated.)
|
||||||
SRC = $(TARGET).c i2c.c lcd.c
|
SRC = $(wildcard *.c)
|
||||||
|
|
||||||
# List Assembler source files here.
|
# List Assembler source files here.
|
||||||
# Make them always end in a capital .S. Files ending in a lowercase .s
|
# Make them always end in a capital .S. Files ending in a lowercase .s
|
||||||
@ -111,7 +111,7 @@ CFLAGS += -Wa,-adhlns=$(<:.c=.lst)
|
|||||||
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
|
||||||
CFLAGS += $(CSTANDARD)
|
CFLAGS += $(CSTANDARD)
|
||||||
CFLAGS += -DF_CPU=$(F_CPU)
|
CFLAGS += -DF_CPU=$(F_CPU)
|
||||||
CFLAGS += -finput-charset=utf-8 -fexec-charset=iso-8859-15
|
#CFLAGS += -finput-charset=utf-8 -fexec-charset=iso-8859-15
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
|||||||
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)
|
||||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
||||||
AVRDUDE_FLAGS += -B 1
|
AVRDUDE_FLAGS += -b 19200
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BIN
bigchars.JPG
Normale Datei
BIN
bigchars.JPG
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 1.0 MiB |
140
font.c
Normale Datei
140
font.c
Normale Datei
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* font.c
|
||||||
|
* i2c
|
||||||
|
*
|
||||||
|
* Created by Michael Köhler on 16.09.18.
|
||||||
|
* Copyright 2018 Skie-Systems. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "font.h"
|
||||||
|
|
||||||
|
const char ssd1306oled_font[][6] PROGMEM = {
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // sp
|
||||||
|
{0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // !
|
||||||
|
{0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // "
|
||||||
|
{0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // #
|
||||||
|
{0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $
|
||||||
|
{0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // %
|
||||||
|
{0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // &
|
||||||
|
{0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // '
|
||||||
|
{0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // (
|
||||||
|
{0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // )
|
||||||
|
{0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // *
|
||||||
|
{0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // +
|
||||||
|
{0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // ,
|
||||||
|
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // -
|
||||||
|
{0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // .
|
||||||
|
{0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // /
|
||||||
|
{0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0
|
||||||
|
{0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1
|
||||||
|
{0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2
|
||||||
|
{0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3
|
||||||
|
{0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4
|
||||||
|
{0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5
|
||||||
|
{0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6
|
||||||
|
{0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7
|
||||||
|
{0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8
|
||||||
|
{0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9
|
||||||
|
{0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // :
|
||||||
|
{0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ;
|
||||||
|
{0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // <
|
||||||
|
{0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // =
|
||||||
|
{0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // >
|
||||||
|
{0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ?
|
||||||
|
{0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @
|
||||||
|
{0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A
|
||||||
|
{0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B
|
||||||
|
{0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C
|
||||||
|
{0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D
|
||||||
|
{0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E
|
||||||
|
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F
|
||||||
|
{0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G
|
||||||
|
{0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H
|
||||||
|
{0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I
|
||||||
|
{0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J
|
||||||
|
{0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K
|
||||||
|
{0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L
|
||||||
|
{0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M
|
||||||
|
{0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N
|
||||||
|
{0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O
|
||||||
|
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P
|
||||||
|
{0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q
|
||||||
|
{0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R
|
||||||
|
{0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S
|
||||||
|
{0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T
|
||||||
|
{0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U
|
||||||
|
{0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V
|
||||||
|
{0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W
|
||||||
|
{0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X
|
||||||
|
{0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y
|
||||||
|
{0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z
|
||||||
|
{0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [
|
||||||
|
{0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // backslash
|
||||||
|
{0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ]
|
||||||
|
{0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^
|
||||||
|
{0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _
|
||||||
|
{0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // '
|
||||||
|
{0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a
|
||||||
|
{0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b
|
||||||
|
{0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c
|
||||||
|
{0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d
|
||||||
|
{0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e
|
||||||
|
{0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f
|
||||||
|
{0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g
|
||||||
|
{0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h
|
||||||
|
{0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i
|
||||||
|
{0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j
|
||||||
|
{0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k
|
||||||
|
{0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l
|
||||||
|
{0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m
|
||||||
|
{0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n
|
||||||
|
{0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o
|
||||||
|
{0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p
|
||||||
|
{0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q
|
||||||
|
{0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r
|
||||||
|
{0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s
|
||||||
|
{0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t
|
||||||
|
{0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u
|
||||||
|
{0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v
|
||||||
|
{0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w
|
||||||
|
{0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x
|
||||||
|
{0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y
|
||||||
|
{0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z
|
||||||
|
{0x00, 0x00, 0x08, 0x77, 0x41, 0x00}, // {
|
||||||
|
{0x00, 0x00, 0x00, 0x63, 0x00, 0x00}, // ¦
|
||||||
|
{0x00, 0x00, 0x41, 0x77, 0x08, 0x00}, // }
|
||||||
|
{0x00, 0x08, 0x04, 0x08, 0x08, 0x04}, // ~
|
||||||
|
/* end of normal char-set */
|
||||||
|
/* put your own signs/chars here, edit special_char too */
|
||||||
|
/* be sure that your first special char stand here */
|
||||||
|
{0x00, 0x3A, 0x40, 0x40, 0x20, 0x7A}, // ü, !!! Important: this must be special_char[0] !!!
|
||||||
|
{0x00, 0x3D, 0x40, 0x40, 0x40, 0x3D}, // Ü
|
||||||
|
{0x00, 0x21, 0x54, 0x54, 0x54, 0x79}, // ä
|
||||||
|
{0x00, 0x7D, 0x12, 0x11, 0x12, 0x7D}, // Ä
|
||||||
|
{0x00, 0x39, 0x44, 0x44, 0x44, 0x39}, // ö
|
||||||
|
{0x00, 0x3D, 0x42, 0x42, 0x42, 0x3D}, // Ö
|
||||||
|
{0x00, 0x02, 0x05, 0x02, 0x00, 0x00}, // °
|
||||||
|
{0x00, 0x7E, 0x01, 0x49, 0x55, 0x73}, // ß
|
||||||
|
{0x00, 0x7C, 0x10, 0x10, 0x08, 0x1C}, // µ
|
||||||
|
{0x00, 0x30, 0x48, 0x20, 0x48, 0x30}, // ω
|
||||||
|
{0x00, 0x5C, 0x62, 0x02, 0x62, 0x5C} // Ω
|
||||||
|
};
|
||||||
|
const char special_char[][2] PROGMEM = {
|
||||||
|
// define position of special char in font
|
||||||
|
// {special char, position in font}
|
||||||
|
// be sure that last element of this
|
||||||
|
// array are {0xff, 0xff} and first element
|
||||||
|
// are {first special char, first element after normal char-set in font}
|
||||||
|
{'ü', 95}, // special_char[0]
|
||||||
|
{'Ü', 96},
|
||||||
|
{'ä', 97},
|
||||||
|
{'Ä', 98},
|
||||||
|
{'ö', 99},
|
||||||
|
{'Ö', 100},
|
||||||
|
{'°', 101},
|
||||||
|
{'ß', 102},
|
||||||
|
{'µ', 103},
|
||||||
|
{'ω', 104},
|
||||||
|
{'Ω', 105},
|
||||||
|
{0xff, 0xff} // end of table special_char
|
||||||
|
};
|
16
font.h
Normale Datei
16
font.h
Normale Datei
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* font.h
|
||||||
|
* i2c
|
||||||
|
*
|
||||||
|
* Created by Michael Köhler on 13.09.18.
|
||||||
|
* Copyright 2018 Skie-Systems. All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef _font_h_
|
||||||
|
#define _font_h_
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
extern const char ssd1306oled_font[][6] PROGMEM;
|
||||||
|
extern const char special_char[][2] PROGMEM;
|
||||||
|
|
||||||
|
#endif
|
75
i2c.c
75
i2c.c
@ -8,7 +8,16 @@
|
|||||||
|
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
|
||||||
#if defined (__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega1284P__) || defined (__AVR_ATmega324A__) || defined (__AVR_ATmega324P__) || defined (__AVR_ATmega324PA__) || defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__) || defined (__AVR_ATmega1284P__)
|
#if defined (__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || \
|
||||||
|
defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PA__) || \
|
||||||
|
defined(__AVR_ATmega88P__) || \
|
||||||
|
defined(__AVR_ATmega8__) || \
|
||||||
|
defined(__AVR_ATmega48P__) || \
|
||||||
|
defined(__AVR_ATmega1284P__) || \
|
||||||
|
defined (__AVR_ATmega324A__) || defined (__AVR_ATmega324P__) || defined (__AVR_ATmega324PA__) || \
|
||||||
|
defined (__AVR_ATmega644__) || defined (__AVR_ATmega644A__) || defined (__AVR_ATmega644P__) || defined (__AVR_ATmega644PA__) || \
|
||||||
|
defined (__AVR_ATmega1284P__) || \
|
||||||
|
defined (__AVR_ATmega2560__)
|
||||||
#if PSC_I2C != 1 && PSC_I2C != 4 && PSC_I2C != 16 && PSC_I2C != 64
|
#if PSC_I2C != 1 && PSC_I2C != 4 && PSC_I2C != 16 && PSC_I2C != 64
|
||||||
#error "Wrong prescaler for TWI !"
|
#error "Wrong prescaler for TWI !"
|
||||||
#elif SET_TWBR < 0 || SET_TWBR > 255
|
#elif SET_TWBR < 0 || SET_TWBR > 255
|
||||||
@ -16,7 +25,15 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t I2C_ErrorCode;
|
uint8_t I2C_ErrorCode;
|
||||||
|
/**********************************************
|
||||||
|
Public Function: i2c_init
|
||||||
|
|
||||||
|
Purpose: Initialise TWI/I2C interface
|
||||||
|
|
||||||
|
Input Parameter: none
|
||||||
|
|
||||||
|
Return Value: none
|
||||||
|
**********************************************/
|
||||||
void i2c_init(void){
|
void i2c_init(void){
|
||||||
// set clock
|
// set clock
|
||||||
switch (PSC_I2C) {
|
switch (PSC_I2C) {
|
||||||
@ -37,6 +54,16 @@ void i2c_init(void){
|
|||||||
// enable
|
// enable
|
||||||
TWCR = (1 << TWEN);
|
TWCR = (1 << TWEN);
|
||||||
}
|
}
|
||||||
|
/**********************************************
|
||||||
|
Public Function: i2c_start
|
||||||
|
|
||||||
|
Purpose: Start TWI/I2C interface
|
||||||
|
|
||||||
|
Input Parameter:
|
||||||
|
- uint8_t i2c_addr: Adress of reciever
|
||||||
|
|
||||||
|
Return Value: none
|
||||||
|
**********************************************/
|
||||||
void i2c_start(uint8_t i2c_addr){
|
void i2c_start(uint8_t i2c_addr){
|
||||||
// i2c start
|
// i2c start
|
||||||
TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN);
|
TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN);
|
||||||
@ -62,10 +89,29 @@ void i2c_start(uint8_t i2c_addr){
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
/**********************************************
|
||||||
|
Public Function: i2c_stop
|
||||||
|
|
||||||
|
Purpose: Stop TWI/I2C interface
|
||||||
|
|
||||||
|
Input Parameter: none
|
||||||
|
|
||||||
|
Return Value: none
|
||||||
|
**********************************************/
|
||||||
void i2c_stop(void){
|
void i2c_stop(void){
|
||||||
// i2c stop
|
// i2c stop
|
||||||
TWCR = (1 << TWINT)|(1 << TWSTO)|(1 << TWEN);
|
TWCR = (1 << TWINT)|(1 << TWSTO)|(1 << TWEN);
|
||||||
}
|
}
|
||||||
|
/**********************************************
|
||||||
|
Public Function: i2c_byte
|
||||||
|
|
||||||
|
Purpose: Send byte at TWI/I2C interface
|
||||||
|
|
||||||
|
Input Parameter:
|
||||||
|
- uint8_t byte: Byte to send to reciever
|
||||||
|
|
||||||
|
Return Value: none
|
||||||
|
**********************************************/
|
||||||
void i2c_byte(uint8_t byte){
|
void i2c_byte(uint8_t byte){
|
||||||
TWDR = byte;
|
TWDR = byte;
|
||||||
TWCR = (1 << TWINT)|( 1 << TWEN);
|
TWCR = (1 << TWINT)|( 1 << TWEN);
|
||||||
@ -79,6 +125,17 @@ void i2c_byte(uint8_t byte){
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
/**********************************************
|
||||||
|
Public Function: i2c_readAck
|
||||||
|
|
||||||
|
Purpose: read acknowledge from TWI/I2C Interface
|
||||||
|
|
||||||
|
Input Parameter: none
|
||||||
|
|
||||||
|
Return Value: uint8_t
|
||||||
|
- TWDR: recieved value at TWI/I2C-Interface, 0 at timeout
|
||||||
|
- 0: Error at read
|
||||||
|
**********************************************/
|
||||||
uint8_t i2c_readAck(void){
|
uint8_t i2c_readAck(void){
|
||||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
|
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
|
||||||
uint16_t timeout = F_CPU/F_I2C*2.0;
|
uint16_t timeout = F_CPU/F_I2C*2.0;
|
||||||
@ -92,6 +149,18 @@ uint8_t i2c_readAck(void){
|
|||||||
};
|
};
|
||||||
return TWDR;
|
return TWDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************
|
||||||
|
Public Function: i2c_readNAck
|
||||||
|
|
||||||
|
Purpose: read non-acknowledge from TWI/I2C Interface
|
||||||
|
|
||||||
|
Input Parameter: none
|
||||||
|
|
||||||
|
Return Value: uint8_t
|
||||||
|
- TWDR: recieved value at TWI/I2C-Interface
|
||||||
|
- 0: Error at read
|
||||||
|
**********************************************/
|
||||||
uint8_t i2c_readNAck(void){
|
uint8_t i2c_readNAck(void){
|
||||||
TWCR = (1<<TWINT)|(1<<TWEN);
|
TWCR = (1<<TWINT)|(1<<TWEN);
|
||||||
uint16_t timeout = F_CPU/F_I2C*2.0;
|
uint16_t timeout = F_CPU/F_I2C*2.0;
|
||||||
@ -100,7 +169,7 @@ uint8_t i2c_readNAck(void){
|
|||||||
timeout--;
|
timeout--;
|
||||||
if(timeout == 0){
|
if(timeout == 0){
|
||||||
I2C_ErrorCode |= (1 << I2C_READNACK);
|
I2C_ErrorCode |= (1 << I2C_READNACK);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return TWDR;
|
return TWDR;
|
||||||
|
8
i2c.h
8
i2c.h
@ -9,6 +9,10 @@
|
|||||||
#ifndef i2c_h
|
#ifndef i2c_h
|
||||||
#define i2c_h
|
#define i2c_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO: setup i2c/twi */
|
/* TODO: setup i2c/twi */
|
||||||
#define F_I2C 100000UL// clock i2c
|
#define F_I2C 100000UL// clock i2c
|
||||||
#define PSC_I2C 1 // prescaler i2c
|
#define PSC_I2C 1 // prescaler i2c
|
||||||
@ -35,4 +39,8 @@ void i2c_byte(uint8_t byte); // send data_byte
|
|||||||
uint8_t i2c_readAck(void); // read byte with ACK
|
uint8_t i2c_readAck(void); // read byte with ACK
|
||||||
uint8_t i2c_readNAck(void); // read byte with NACK
|
uint8_t i2c_readNAck(void); // read byte with NACK
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* i2c_h */
|
#endif /* i2c_h */
|
||||||
|
796
lcd.c
796
lcd.c
@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of lcd library for ssd1306/sh1106 oled-display.
|
* This file is part of lcd library for ssd1306/ssd1309/sh1106 oled-display.
|
||||||
*
|
*
|
||||||
* lcd library for ssd1306/sh1106 oled-display is free software: you can redistribute it and/or modify
|
* lcd library for ssd1306/ssd1309/sh1106 oled-display is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||||
*
|
*
|
||||||
* lcd library for ssd1306/sh1106 oled-display is distributed in the hope that it will be useful,
|
* lcd library for ssd1306/ssd1309/sh1106 oled-display is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
@ -13,14 +13,14 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Diese Datei ist Teil von lcd library for ssd1306/sh1106 oled-display.
|
* Diese Datei ist Teil von lcd library for ssd1306/ssd1309/sh1106 oled-display.
|
||||||
*
|
*
|
||||||
* lcd library for ssd1306/sh1106 oled-display ist Freie Software: Sie können es unter den Bedingungen
|
* lcd library for ssd1306/ssd1309/sh1106 oled-display ist Freie Software: Sie können es unter den Bedingungen
|
||||||
* der GNU General Public License, wie von der Free Software Foundation,
|
* der GNU General Public License, wie von der Free Software Foundation,
|
||||||
* Version 3 der Lizenz oder jeder späteren
|
* Version 3 der Lizenz oder jeder späteren
|
||||||
* veröffentlichten Version, weiterverbreiten und/oder modifizieren.
|
* veröffentlichten Version, weiterverbreiten und/oder modifizieren.
|
||||||
*
|
*
|
||||||
* lcd library for ssd1306/sh1106 oled-display wird in der Hoffnung, dass es nützlich sein wird, aber
|
* lcd library for ssd1306/ssd1309/sh1106 oled-display wird in der Hoffnung, dass es nützlich sein wird, aber
|
||||||
* OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
|
* OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
|
||||||
* Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
|
* Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
|
||||||
* Siehe die GNU General Public License für weitere Details.
|
* Siehe die GNU General Public License für weitere Details.
|
||||||
@ -33,176 +33,124 @@
|
|||||||
* Created by Michael Köhler on 22.12.16.
|
* Created by Michael Köhler on 22.12.16.
|
||||||
* Copyright 2016 Skie-Systems. All rights reserved.
|
* Copyright 2016 Skie-Systems. All rights reserved.
|
||||||
*
|
*
|
||||||
* lib for OLED-Display with ssd1306/sh1106-Controller
|
* lib for OLED-Display with ssd1306/ssd1309/sh1106-Controller
|
||||||
* first dev-version only for I2C-Connection
|
* first dev-version only for I2C-Connection
|
||||||
* at ATMega328P like Arduino Uno
|
* at ATMega328P like Arduino Uno
|
||||||
*
|
*
|
||||||
* at GRAPHICMODE lib needs SRAM for display
|
* at GRAPHICMODE lib needs static SRAM for display:
|
||||||
* DISPLAY-WIDTH * DISPLAY-HEIGHT + 2 bytes
|
* DISPLAY-WIDTH * DISPLAY-HEIGHT + 2 bytes
|
||||||
|
*
|
||||||
|
* at TEXTMODE lib need static SRAM for display:
|
||||||
|
* 2 bytes (cursorPosition)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lcd.h"
|
#include "lcd.h"
|
||||||
|
#include "font.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
uint8_t cursorPosition=0;
|
#if defined SPI
|
||||||
#if defined GRAPHICMODE
|
#include <util/delay.h>
|
||||||
#include <stdlib.h>
|
|
||||||
static uint8_t displayBuffer[DISPLAYSIZE];
|
|
||||||
uint16_t actualIndex = 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Standard ASCII 6x8 font */
|
static struct {
|
||||||
static const uint8_t ssd1306oled_font6x8 [] PROGMEM = {
|
uint8_t x;
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp
|
uint8_t y;
|
||||||
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // !
|
} cursorPosition;
|
||||||
0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // "
|
|
||||||
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // #
|
|
||||||
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $
|
|
||||||
0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // %
|
|
||||||
0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // &
|
|
||||||
0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // '
|
|
||||||
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // (
|
|
||||||
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // )
|
|
||||||
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // *
|
|
||||||
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // +
|
|
||||||
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // ,
|
|
||||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // -
|
|
||||||
0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // .
|
|
||||||
0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // /
|
|
||||||
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
|
|
||||||
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1
|
|
||||||
0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2
|
|
||||||
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3
|
|
||||||
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4
|
|
||||||
0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5
|
|
||||||
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
|
|
||||||
0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7
|
|
||||||
0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8
|
|
||||||
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9
|
|
||||||
0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // :
|
|
||||||
0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ;
|
|
||||||
0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // <
|
|
||||||
0x00, 0x14, 0x14, 0x14, 0x14, 0x14, // =
|
|
||||||
0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // >
|
|
||||||
0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ?
|
|
||||||
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @
|
|
||||||
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A
|
|
||||||
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B
|
|
||||||
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C
|
|
||||||
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D
|
|
||||||
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E
|
|
||||||
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F
|
|
||||||
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G
|
|
||||||
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H
|
|
||||||
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I
|
|
||||||
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J
|
|
||||||
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K
|
|
||||||
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L
|
|
||||||
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
|
|
||||||
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N
|
|
||||||
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O
|
|
||||||
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P
|
|
||||||
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
|
|
||||||
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R
|
|
||||||
0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S
|
|
||||||
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T
|
|
||||||
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U
|
|
||||||
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V
|
|
||||||
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W
|
|
||||||
0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X
|
|
||||||
0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y
|
|
||||||
0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z
|
|
||||||
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [
|
|
||||||
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55, // backslash
|
|
||||||
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ]
|
|
||||||
0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^
|
|
||||||
0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _
|
|
||||||
0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // '
|
|
||||||
0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a
|
|
||||||
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b
|
|
||||||
0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c
|
|
||||||
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d
|
|
||||||
0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e
|
|
||||||
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f
|
|
||||||
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
|
|
||||||
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h
|
|
||||||
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i
|
|
||||||
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j
|
|
||||||
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k
|
|
||||||
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l
|
|
||||||
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m
|
|
||||||
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n
|
|
||||||
0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o
|
|
||||||
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p
|
|
||||||
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q
|
|
||||||
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r
|
|
||||||
0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s
|
|
||||||
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t
|
|
||||||
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u
|
|
||||||
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v
|
|
||||||
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w
|
|
||||||
0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x
|
|
||||||
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y
|
|
||||||
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z
|
|
||||||
0x00, 0x00, 0x08, 0x77, 0x41, 0x00, // {
|
|
||||||
0x00, 0x00, 0x00, 0x63, 0x00, 0x00, // ¦
|
|
||||||
0x00, 0x00, 0x41, 0x77, 0x08, 0x00, // }
|
|
||||||
0x00, 0x08, 0x04, 0x08, 0x08, 0x04, // ~
|
|
||||||
0x00, 0x3D, 0x40, 0x40, 0x20, 0x7D, // ü
|
|
||||||
0x00, 0x3D, 0x40, 0x40, 0x40, 0x3D, // Ü
|
|
||||||
0x00, 0x21, 0x54, 0x54, 0x54, 0x79, // ä
|
|
||||||
0x00, 0x7D, 0x12, 0x11, 0x12, 0x7D, // Ä
|
|
||||||
0x00, 0x39, 0x44, 0x44, 0x44, 0x39, // ö
|
|
||||||
0x00, 0x3D, 0x42, 0x42, 0x42, 0x3D, // Ö
|
|
||||||
0x00, 0x02, 0x05, 0x02, 0x00, 0x00, // °
|
|
||||||
0x00, 0x7E, 0x01, 0x49, 0x55, 0x73, // ß
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t init_sequence [] PROGMEM = { // Initialization Sequence
|
static uint8_t charMode = NORMALSIZE;
|
||||||
LCD_DISP_OFF, // Display OFF (sleep mode)
|
#if defined GRAPHICMODE
|
||||||
0x20, 0b00, // Set Memory Addressing Mode
|
#include <stdlib.h>
|
||||||
// 00=Horizontal Addressing Mode; 01=Vertical Addressing Mode;
|
static uint8_t displayBuffer[DISPLAY_HEIGHT/8][DISPLAY_WIDTH];
|
||||||
// 10=Page Addressing Mode (RESET); 11=Invalid
|
#elif defined TEXTMODE
|
||||||
0xB0, // Set Page Start Address for Page Addressing Mode, 0-7
|
#else
|
||||||
0xC8, // Set COM Output Scan Direction
|
#error "No valid displaymode! Refer lcd.h"
|
||||||
0x00, // --set low column address
|
#endif
|
||||||
0x10, // --set high column address
|
|
||||||
0x40, // --set start line address
|
|
||||||
0x81, 0x3F, // Set contrast control register
|
const uint8_t init_sequence [] PROGMEM = { // Initialization Sequence
|
||||||
0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped.
|
LCD_DISP_OFF, // Display OFF (sleep mode)
|
||||||
0xA6, // Set display mode. A6=Normal; A7=Inverse
|
0x20, 0b00, // Set Memory Addressing Mode
|
||||||
0xA8, 0x3F, // Set multiplex ratio(1 to 64)
|
// 00=Horizontal Addressing Mode; 01=Vertical Addressing Mode;
|
||||||
0xA4, // Output RAM to Display
|
// 10=Page Addressing Mode (RESET); 11=Invalid
|
||||||
// 0xA4=Output follows RAM content; 0xA5,Output ignores RAM content
|
0xB0, // Set Page Start Address for Page Addressing Mode, 0-7
|
||||||
0xD3, 0x00, // Set display offset. 00 = no offset
|
0xC8, // Set COM Output Scan Direction
|
||||||
0xD5, // --set display clock divide ratio/oscillator frequency
|
0x00, // --set low column address
|
||||||
0xF0, // --set divide ratio
|
0x10, // --set high column address
|
||||||
0xD9, 0x22, // Set pre-charge period
|
0x40, // --set start line address
|
||||||
0xDA, 0x12, // Set com pins hardware configuration
|
0x81, 0x3F, // Set contrast control register
|
||||||
0xDB, // --set vcomh
|
0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped.
|
||||||
0x20, // 0x20,0.77xVcc
|
0xA6, // Set display mode. A6=Normal; A7=Inverse
|
||||||
0x8D, 0x14, // Set DC-DC enable
|
0xA8, DISPLAY_HEIGHT-1, // Set multiplex ratio(1 to 64)
|
||||||
|
0xA4, // Output RAM to Display
|
||||||
|
// 0xA4=Output follows RAM content; 0xA5,Output ignores RAM content
|
||||||
|
0xD3, 0x00, // Set display offset. 00 = no offset
|
||||||
|
0xD5, // --set display clock divide ratio/oscillator frequency
|
||||||
|
0xF0, // --set divide ratio
|
||||||
|
0xD9, 0x22, // Set pre-charge period
|
||||||
|
// Set com pins hardware configuration
|
||||||
|
#if DISPLAY_HEIGHT==64
|
||||||
|
0xDA, 0x12,
|
||||||
|
#elif DISPLAY_HEIGHT==32
|
||||||
|
0xDA, 0x02,
|
||||||
|
#endif
|
||||||
|
0xDB, // --set vcomh
|
||||||
|
0x20, // 0x20,0.77xVcc
|
||||||
|
0x8D, 0x14, // Set DC-DC enable
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
#pragma mark LCD COMMUNICATION
|
||||||
void lcd_command(uint8_t cmd[], uint8_t size) {
|
void lcd_command(uint8_t cmd[], uint8_t size) {
|
||||||
i2c_start(LCD_I2C_ADR);
|
#if defined I2C
|
||||||
i2c_byte(0x00); // 0x00 for command, 0x40 for data
|
i2c_start((LCD_I2C_ADR << 1) | 0);
|
||||||
|
i2c_byte(0x00); // 0x00 for command, 0x40 for data
|
||||||
for (uint8_t i=0; i<size; i++) {
|
for (uint8_t i=0; i<size; i++) {
|
||||||
i2c_byte(cmd[i]);
|
i2c_byte(cmd[i]);
|
||||||
}
|
}
|
||||||
i2c_stop();
|
i2c_stop();
|
||||||
|
#elif defined SPI
|
||||||
|
LCD_PORT &= ~(1 << CS_PIN);
|
||||||
|
LCD_PORT &= ~(1 << DC_PIN);
|
||||||
|
for (uint8_t i=0; i<size; i++) {
|
||||||
|
SPDR = cmd[i];
|
||||||
|
while(!(SPSR & (1<<SPIF)));
|
||||||
|
}
|
||||||
|
LCD_PORT |= (1 << CS_PIN);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void lcd_data(uint8_t data[], uint16_t size) {
|
void lcd_data(uint8_t data[], uint16_t size) {
|
||||||
i2c_start(LCD_I2C_ADR);
|
#if defined I2C
|
||||||
i2c_byte(0x40); // 0x00 for command, 0x40 for data
|
i2c_start((LCD_I2C_ADR << 1) | 0);
|
||||||
|
i2c_byte(0x40); // 0x00 for command, 0x40 for data
|
||||||
for (uint16_t i = 0; i<size; i++) {
|
for (uint16_t i = 0; i<size; i++) {
|
||||||
i2c_byte(data[i]);
|
i2c_byte(data[i]);
|
||||||
}
|
}
|
||||||
i2c_stop();
|
i2c_stop();
|
||||||
|
#elif defined SPI
|
||||||
|
LCD_PORT &= ~(1 << CS_PIN);
|
||||||
|
LCD_PORT |= (1 << DC_PIN);
|
||||||
|
for (uint16_t i = 0; i<size; i++) {
|
||||||
|
SPDR = data[i];
|
||||||
|
while(!(SPSR & (1<<SPIF)));
|
||||||
|
}
|
||||||
|
LCD_PORT |= (1 << CS_PIN);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
#pragma mark -
|
||||||
|
#pragma mark GENERAL FUNCTIONS
|
||||||
void lcd_init(uint8_t dispAttr){
|
void lcd_init(uint8_t dispAttr){
|
||||||
|
#if defined I2C
|
||||||
i2c_init();
|
i2c_init();
|
||||||
|
#elif defined SPI
|
||||||
|
DDRB |= (1 << PB2)|(1 << PB3)|(1 << PB5);
|
||||||
|
SPCR = (1 << SPE)|(1<<MSTR)|(1<<SPR0);
|
||||||
|
LCD_DDR |= (1 << CS_PIN)|(1 << DC_PIN)|(1 << RES_PIN);
|
||||||
|
LCD_PORT |= (1 << CS_PIN)|(1 << DC_PIN)|(1 << RES_PIN);
|
||||||
|
LCD_PORT &= ~(1 << RES_PIN);
|
||||||
|
_delay_ms(10);
|
||||||
|
LCD_PORT |= (1 << RES_PIN);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint8_t commandSequence[sizeof(init_sequence)+1];
|
uint8_t commandSequence[sizeof(init_sequence)+1];
|
||||||
for (uint8_t i = 0; i < sizeof (init_sequence); i++) {
|
for (uint8_t i = 0; i < sizeof (init_sequence); i++) {
|
||||||
commandSequence[i] = (pgm_read_byte(&init_sequence[i]));
|
commandSequence[i] = (pgm_read_byte(&init_sequence[i]));
|
||||||
@ -211,23 +159,217 @@ void lcd_init(uint8_t dispAttr){
|
|||||||
lcd_command(commandSequence, sizeof(commandSequence));
|
lcd_command(commandSequence, sizeof(commandSequence));
|
||||||
lcd_clrscr();
|
lcd_clrscr();
|
||||||
}
|
}
|
||||||
|
void lcd_gotoxy(uint8_t x, uint8_t y){
|
||||||
|
x = x * sizeof(FONT[0]);
|
||||||
|
lcd_goto_xpix_y(x,y);
|
||||||
|
}
|
||||||
|
void lcd_goto_xpix_y(uint8_t x, uint8_t y){
|
||||||
|
if( x > (DISPLAY_WIDTH) || y > (DISPLAY_HEIGHT/8-1)) return;// out of display
|
||||||
|
cursorPosition.x=x;
|
||||||
|
cursorPosition.y=y;
|
||||||
|
#if defined (SSD1306) || defined (SSD1309)
|
||||||
|
uint8_t commandSequence[] = {0xb0+y, 0x21, x, 0x7f};
|
||||||
|
#elif defined SH1106
|
||||||
|
uint8_t commandSequence[] = {0xb0+y, 0x21, 0x00+((2+x) & (0x0f)), 0x10+( ((2+x) & (0xf0)) >> 4 ), 0x7f};
|
||||||
|
#endif
|
||||||
|
lcd_command(commandSequence, sizeof(commandSequence));
|
||||||
|
}
|
||||||
|
void lcd_clrscr(void){
|
||||||
|
#ifdef GRAPHICMODE
|
||||||
|
for (uint8_t i = 0; i < DISPLAY_HEIGHT/8; i++){
|
||||||
|
memset(displayBuffer[i], 0x00, sizeof(displayBuffer[i]));
|
||||||
|
lcd_gotoxy(0,i);
|
||||||
|
lcd_data(displayBuffer[i], sizeof(displayBuffer[i]));
|
||||||
|
}
|
||||||
|
#elif defined TEXTMODE
|
||||||
|
uint8_t displayBuffer[DISPLAY_WIDTH];
|
||||||
|
memset(displayBuffer, 0x00, sizeof(displayBuffer));
|
||||||
|
for (uint8_t i = 0; i < DISPLAY_HEIGHT/8; i++){
|
||||||
|
lcd_gotoxy(0,i);
|
||||||
|
lcd_data(displayBuffer, sizeof(displayBuffer));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
lcd_home();
|
||||||
|
}
|
||||||
void lcd_home(void){
|
void lcd_home(void){
|
||||||
lcd_gotoxy(0, 0);
|
lcd_gotoxy(0, 0);
|
||||||
}
|
}
|
||||||
void lcd_invert(uint8_t invert){
|
void lcd_invert(uint8_t invert){
|
||||||
i2c_start(LCD_I2C_ADR);
|
|
||||||
uint8_t commandSequence[1];
|
uint8_t commandSequence[1];
|
||||||
if (invert == YES) {
|
if (invert != YES) {
|
||||||
commandSequence[0] = 0xA7;
|
commandSequence[0] = 0xA6;
|
||||||
} else {
|
} else {
|
||||||
commandSequence[0] = 0xA7;
|
commandSequence[0] = 0xA7;
|
||||||
}
|
}
|
||||||
lcd_command(commandSequence, 1);
|
lcd_command(commandSequence, 1);
|
||||||
}
|
}
|
||||||
|
void lcd_sleep(uint8_t sleep){
|
||||||
|
uint8_t commandSequence[1];
|
||||||
|
if (sleep != YES) {
|
||||||
|
commandSequence[0] = 0xAF;
|
||||||
|
} else {
|
||||||
|
commandSequence[0] = 0xAE;
|
||||||
|
}
|
||||||
|
lcd_command(commandSequence, 1);
|
||||||
|
}
|
||||||
void lcd_set_contrast(uint8_t contrast){
|
void lcd_set_contrast(uint8_t contrast){
|
||||||
uint8_t commandSequence[2] = {0x81, contrast};
|
uint8_t commandSequence[2] = {0x81, contrast};
|
||||||
lcd_command(commandSequence, sizeof(commandSequence));
|
lcd_command(commandSequence, sizeof(commandSequence));
|
||||||
}
|
}
|
||||||
|
void lcd_putc(char c){
|
||||||
|
switch (c) {
|
||||||
|
case '\b':
|
||||||
|
// backspace
|
||||||
|
lcd_gotoxy(cursorPosition.x-charMode, cursorPosition.y);
|
||||||
|
lcd_putc(' ');
|
||||||
|
lcd_gotoxy(cursorPosition.x-charMode, cursorPosition.y);
|
||||||
|
break;
|
||||||
|
case '\t':
|
||||||
|
// tab
|
||||||
|
if( (cursorPosition.x+charMode*4) < (DISPLAY_WIDTH/ sizeof(FONT[0])-charMode*4) ){
|
||||||
|
lcd_gotoxy(cursorPosition.x+charMode*4, cursorPosition.y);
|
||||||
|
}else{
|
||||||
|
lcd_gotoxy(DISPLAY_WIDTH/ sizeof(FONT[0]), cursorPosition.y);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
// linefeed
|
||||||
|
if(cursorPosition.y < (DISPLAY_HEIGHT/8-1)){
|
||||||
|
lcd_gotoxy(cursorPosition.x, cursorPosition.y+charMode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
// carrige return
|
||||||
|
lcd_gotoxy(0, cursorPosition.y);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// char doesn't fit in line
|
||||||
|
if( (cursorPosition.x >= DISPLAY_WIDTH-sizeof(FONT[0])) || (c < ' ') ) break;
|
||||||
|
// mapping char
|
||||||
|
c -= ' ';
|
||||||
|
if (c >= pgm_read_byte(&special_char[0][1]) ) {
|
||||||
|
char temp = c;
|
||||||
|
c = 0xff;
|
||||||
|
for (uint8_t i=0; pgm_read_byte(&special_char[i][1]) != 0xff; i++) {
|
||||||
|
if ( pgm_read_byte(&special_char[i][0])-' ' == temp ) {
|
||||||
|
c = pgm_read_byte(&special_char[i][1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( c == 0xff ) break;
|
||||||
|
}
|
||||||
|
// print char at display
|
||||||
|
#ifdef GRAPHICMODE
|
||||||
|
if (charMode == DOUBLESIZE) {
|
||||||
|
uint16_t doubleChar[sizeof(FONT[0])];
|
||||||
|
uint8_t dChar;
|
||||||
|
if ((cursorPosition.x+2*sizeof(FONT[0]))>DISPLAY_WIDTH) break;
|
||||||
|
|
||||||
|
for (uint8_t i=0; i < sizeof(FONT[0]); i++) {
|
||||||
|
doubleChar[i] = 0;
|
||||||
|
dChar = pgm_read_byte(&(FONT[(uint8_t)c][i]));
|
||||||
|
for (uint8_t j=0; j<8; j++) {
|
||||||
|
if ((dChar & (1 << j))) {
|
||||||
|
doubleChar[i] |= (1 << (j*2));
|
||||||
|
doubleChar[i] |= (1 << ((j*2)+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < sizeof(FONT[0]); i++)
|
||||||
|
{
|
||||||
|
// load bit-pattern from flash
|
||||||
|
displayBuffer[cursorPosition.y+1][cursorPosition.x+(2*i)] = doubleChar[i] >> 8;
|
||||||
|
displayBuffer[cursorPosition.y+1][cursorPosition.x+(2*i)+1] = doubleChar[i] >> 8;
|
||||||
|
displayBuffer[cursorPosition.y][cursorPosition.x+(2*i)] = doubleChar[i] & 0xff;
|
||||||
|
displayBuffer[cursorPosition.y][cursorPosition.x+(2*i)+1] = doubleChar[i] & 0xff;
|
||||||
|
}
|
||||||
|
cursorPosition.x += sizeof(FONT[0])*2;
|
||||||
|
} else {
|
||||||
|
if ((cursorPosition.x+sizeof(FONT[0]))>DISPLAY_WIDTH) break;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < sizeof(FONT[0]); i++)
|
||||||
|
{
|
||||||
|
// load bit-pattern from flash
|
||||||
|
displayBuffer[cursorPosition.y][cursorPosition.x+i] =pgm_read_byte(&(FONT[(uint8_t)c][i]));
|
||||||
|
}
|
||||||
|
cursorPosition.x += sizeof(FONT[0]);
|
||||||
|
}
|
||||||
|
#elif defined TEXTMODE
|
||||||
|
if (charMode == DOUBLESIZE) {
|
||||||
|
uint16_t doubleChar[sizeof(FONT[0])];
|
||||||
|
uint8_t dChar;
|
||||||
|
if ((cursorPosition.x+2*sizeof(FONT[0]))>DISPLAY_WIDTH) break;
|
||||||
|
|
||||||
|
for (uint8_t i=0; i < sizeof(FONT[0]); i++) {
|
||||||
|
doubleChar[i] = 0;
|
||||||
|
dChar = pgm_read_byte(&(FONT[(uint8_t)c][i]));
|
||||||
|
for (uint8_t j=0; j<8; j++) {
|
||||||
|
if ((dChar & (1 << j))) {
|
||||||
|
doubleChar[i] |= (1 << (j*2));
|
||||||
|
doubleChar[i] |= (1 << ((j*2)+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint8_t data[sizeof(FONT[0])*2];
|
||||||
|
for (uint8_t i = 0; i < sizeof(FONT[0]); i++)
|
||||||
|
{
|
||||||
|
// print font to ram, print 6 columns
|
||||||
|
data[i<<1]=(doubleChar[i] & 0xff);
|
||||||
|
data[(i<<1)+1]=(doubleChar[i] & 0xff);
|
||||||
|
}
|
||||||
|
lcd_data(data, sizeof(FONT[0])*2);
|
||||||
|
|
||||||
|
#if defined (SSD1306) || defined (SSD1309)
|
||||||
|
uint8_t commandSequence[] = {0xb0+cursorPosition.y+1,
|
||||||
|
0x21,
|
||||||
|
cursorPosition.x,
|
||||||
|
0x7f};
|
||||||
|
#elif defined SH1106
|
||||||
|
uint8_t commandSequence[] = {0xb0+cursorPosition.y+1,
|
||||||
|
0x21,
|
||||||
|
0x00+((2+cursorPosition.x) & (0x0f)),
|
||||||
|
0x10+( ((2+cursorPosition.x) & (0xf0)) >> 4 ),
|
||||||
|
0x7f};
|
||||||
|
#endif
|
||||||
|
lcd_command(commandSequence, sizeof(commandSequence));
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < sizeof(FONT[0]); i++)
|
||||||
|
{
|
||||||
|
// print font to ram, print 6 columns
|
||||||
|
data[i<<1]=(doubleChar[i] >> 8);
|
||||||
|
data[(i<<1)+1]=(doubleChar[i] >> 8);
|
||||||
|
}
|
||||||
|
lcd_data(data, sizeof(FONT[0])*2);
|
||||||
|
|
||||||
|
commandSequence[0] = 0xb0+cursorPosition.y;
|
||||||
|
#if defined (SSD1306) || defined (SSD1309)
|
||||||
|
commandSequence[2] = cursorPosition.x+(2*sizeof(FONT[0]));
|
||||||
|
#elif defined SH1106
|
||||||
|
commandSequence[2] = 0x00+((2+cursorPosition.x+(2*sizeof(FONT[0]))) & (0x0f));
|
||||||
|
commandSequence[3] = 0x10+( ((2+cursorPosition.x+(2*sizeof(FONT[0]))) & (0xf0)) >> 4 );
|
||||||
|
#endif
|
||||||
|
lcd_command(commandSequence, sizeof(commandSequence));
|
||||||
|
cursorPosition.x += sizeof(FONT[0])*2;
|
||||||
|
} else {
|
||||||
|
uint8_t data[sizeof(FONT[0])];
|
||||||
|
if ((cursorPosition.x+sizeof(FONT[0]))>DISPLAY_WIDTH) break;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < sizeof(FONT[0]); i++)
|
||||||
|
{
|
||||||
|
// print font to ram, print 6 columns
|
||||||
|
data[i]=(pgm_read_byte(&(FONT[(uint8_t)c][i])));
|
||||||
|
}
|
||||||
|
lcd_data(data, sizeof(FONT[0]));
|
||||||
|
cursorPosition.x += sizeof(FONT[0]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void lcd_charMode(uint8_t mode){
|
||||||
|
charMode = mode;
|
||||||
|
}
|
||||||
void lcd_puts(const char* s){
|
void lcd_puts(const char* s){
|
||||||
while (*s) {
|
while (*s) {
|
||||||
lcd_putc(*s++);
|
lcd_putc(*s++);
|
||||||
@ -239,261 +381,50 @@ void lcd_puts_p(const char* progmem_s){
|
|||||||
lcd_putc(c);
|
lcd_putc(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined TEXTMODE
|
#ifdef GRAPHICMODE
|
||||||
void lcd_clrscr(void){
|
#pragma mark -
|
||||||
uint8_t clearLine[DISPLAY_WIDTH];
|
#pragma mark GRAPHIC FUNCTIONS
|
||||||
memset(clearLine, 0x00, DISPLAY_WIDTH);
|
uint8_t lcd_drawPixel(uint8_t x, uint8_t y, uint8_t color){
|
||||||
for (uint8_t j = 0; j < DISPLAY_HEIGHT/8; j++){
|
if( x > DISPLAY_WIDTH-1 || y > (DISPLAY_HEIGHT-1)) return 1; // out of Display
|
||||||
lcd_gotoxy(0,j);
|
|
||||||
lcd_data(clearLine, sizeof(clearLine));
|
|
||||||
|
|
||||||
}
|
|
||||||
lcd_home();
|
|
||||||
}
|
|
||||||
void lcd_gotoxy(uint8_t x, uint8_t y) {
|
|
||||||
if( x > (DISPLAY_WIDTH/6) || y > (DISPLAY_HEIGHT/8-1)) return;// out of display
|
|
||||||
cursorPosition=x;
|
|
||||||
x = x * 6; // one char: 6 pixel width
|
|
||||||
#if defined SSD1306
|
|
||||||
uint8_t commandSequence[] = {0xb0+y, 0x21, x, 0x7f};
|
|
||||||
#elif defined SH1106
|
|
||||||
uint8_t commandSequence[] = {0xb0+y, 0x21, 0x00+((2+x) & (0x0f)), 0x10+( ((2+x) & (0xf0)) >> 4 ), 0x7f};
|
|
||||||
#endif
|
|
||||||
lcd_command(commandSequence, sizeof(commandSequence));
|
|
||||||
}
|
|
||||||
void lcd_putc(char c){
|
|
||||||
if((c > 127 ||
|
|
||||||
cursorPosition > 20 ||
|
|
||||||
c < 32) &&
|
|
||||||
(c != 'ü' &&
|
|
||||||
c != 'ö' &&
|
|
||||||
c != '°' &&
|
|
||||||
c != 'ä' &&
|
|
||||||
c != 'ß' &&
|
|
||||||
c != 'Ü' &&
|
|
||||||
c != 'Ö' &&
|
|
||||||
c != 'Ä' ) ) return;
|
|
||||||
cursorPosition++;
|
|
||||||
i2c_start(LCD_I2C_ADR);
|
|
||||||
i2c_byte(0x40); // 0x00 for command, 0x40 for data
|
|
||||||
switch (c) {
|
|
||||||
case 'ü':
|
|
||||||
c = 95; // ü
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ö':
|
|
||||||
c = 99; // ö
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '°':
|
|
||||||
c = 101; // °
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ä':
|
|
||||||
c = 97; // ä
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ß':
|
|
||||||
c = 102; // ß
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Ü':
|
|
||||||
c = 96; // Ü
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Ö':
|
|
||||||
c = 100; // Ö
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Ä':
|
|
||||||
c = 98; // Ä
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 32;
|
|
||||||
if( c < 127-32 ) {
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
i2c_byte(pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i])); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
i2c_stop();
|
|
||||||
}
|
|
||||||
#elif defined GRAPHICMODE
|
|
||||||
void lcd_clrscr(void){
|
|
||||||
memset(displayBuffer, 0x00, sizeof(displayBuffer));
|
|
||||||
#if defined SSD1306
|
|
||||||
lcd_data(displayBuffer, sizeof(displayBuffer));
|
|
||||||
#elif defined SH1106
|
|
||||||
for (uint8_t i=0; i <= DISPLAY_HEIGHT/8; i++) {
|
|
||||||
uint8_t actualLine[DISPLAY_WIDTH];
|
|
||||||
for (uint8_t j=0; j< DISPLAY_WIDTH; j++) {
|
|
||||||
actualLine[j]=displayBuffer[i*DISPLAY_WIDTH+j];
|
|
||||||
}
|
|
||||||
lcd_data(actualLine, sizeof(actualLine));
|
|
||||||
lcd_gotoxy(0, i);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
lcd_home();
|
|
||||||
}
|
|
||||||
void lcd_gotoxy(uint8_t x, uint8_t y){
|
|
||||||
if( x > (DISPLAY_WIDTH/6) || y > (DISPLAY_HEIGHT/8-1)) return;// out of display
|
|
||||||
cursorPosition=x;
|
|
||||||
x = x * 6; // one char: 6 pixel width
|
|
||||||
actualIndex = (x)+(y*DISPLAY_WIDTH);
|
|
||||||
#if defined SSD1306
|
|
||||||
uint8_t commandSequence[] = {0xb0+y, 0x21, x, 0x7f};
|
|
||||||
#elif defined SH1106
|
|
||||||
uint8_t commandSequence[] = {0xb0+y, 0x21, 0x00+((2+x) & (0x0f)), 0x10+( ((2+x) & (0xf0)) >> 4 ), 0x7f};
|
|
||||||
#endif
|
|
||||||
lcd_command(commandSequence, sizeof(commandSequence));
|
|
||||||
}
|
|
||||||
void lcd_putc(char c){
|
|
||||||
if((actualIndex+1)%127 != 0){
|
|
||||||
if((c > 127 ||
|
|
||||||
cursorPosition > 20 ||
|
|
||||||
c < 32) &&
|
|
||||||
(c != 'ü' &&
|
|
||||||
c != 'ö' &&
|
|
||||||
c != '°' &&
|
|
||||||
c != 'ä' &&
|
|
||||||
c != 'ß' &&
|
|
||||||
c != 'Ü' &&
|
|
||||||
c != 'Ö' &&
|
|
||||||
c != 'Ä' ) ) return;
|
|
||||||
cursorPosition++;
|
|
||||||
switch (c) {
|
|
||||||
case 'ü':
|
|
||||||
c = 95; // ü - 188
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ö':
|
|
||||||
c = 99; // ö
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '°':
|
|
||||||
c = 101; // °
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ä':
|
|
||||||
c = 97; // ä
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'ß':
|
|
||||||
c = 102; // ß
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Ü':
|
|
||||||
c = 96; // Ü
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Ö':
|
|
||||||
c = 100; // Ö
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Ä':
|
|
||||||
c = 98; // Ä
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]); // print font to ram, print 6 columns
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
c -= 32;
|
|
||||||
for (uint8_t i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
displayBuffer[actualIndex+i] = pgm_read_byte(&ssd1306oled_font6x8[c * 6 + i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
actualIndex += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
void lcd_drawPixel(uint8_t x, uint8_t y, uint8_t color){
|
|
||||||
if( x > DISPLAY_WIDTH-1 || y > (DISPLAY_HEIGHT-1)) return; // out of Display
|
|
||||||
if( color == WHITE){
|
if( color == WHITE){
|
||||||
displayBuffer[(uint8_t)(y / (DISPLAY_HEIGHT/8)) * DISPLAY_WIDTH +x] |= (1 << (y % (DISPLAY_HEIGHT/8)));
|
displayBuffer[(y / 8)][x] |= (1 << (y % 8));
|
||||||
} else {
|
} else {
|
||||||
displayBuffer[(uint8_t)(y / (DISPLAY_HEIGHT/8)) * DISPLAY_WIDTH +x] &= ~(1 << (y % (DISPLAY_HEIGHT/8)));
|
displayBuffer[(y / 8)][x] &= ~(1 << (y % 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
void lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color){
|
uint8_t lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color){
|
||||||
if( x1 > DISPLAY_WIDTH-1 ||
|
uint8_t result;
|
||||||
x2 > DISPLAY_WIDTH-1 ||
|
|
||||||
y1 > DISPLAY_HEIGHT-1 ||
|
|
||||||
y2 > DISPLAY_HEIGHT-1) return;
|
|
||||||
int dx = abs(x2-x1), sx = x1<x2 ? 1 : -1;
|
int dx = abs(x2-x1), sx = x1<x2 ? 1 : -1;
|
||||||
int dy = -abs(y2-y1), sy = y1<y2 ? 1 : -1;
|
int dy = -abs(y2-y1), sy = y1<y2 ? 1 : -1;
|
||||||
int err = dx+dy, e2; /* error value e_xy */
|
int err = dx+dy, e2; /* error value e_xy */
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
lcd_drawPixel(x1, y1, color);
|
result = lcd_drawPixel(x1, y1, color);
|
||||||
if (x1==x2 && y1==y2) break;
|
if (x1==x2 && y1==y2) break;
|
||||||
e2 = 2*err;
|
e2 = 2*err;
|
||||||
if (e2 > dy) { err += dy; x1 += sx; } /* e_xy+e_x > 0 */
|
if (e2 > dy) { err += dy; x1 += sx; } /* e_xy+e_x > 0 */
|
||||||
if (e2 < dx) { err += dx; y1 += sy; } /* e_xy+e_y < 0 */
|
if (e2 < dx) { err += dx; y1 += sy; } /* e_xy+e_y < 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
void lcd_drawRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){
|
uint8_t lcd_drawRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){
|
||||||
if( px1 > DISPLAY_WIDTH-1 ||
|
uint8_t result;
|
||||||
px2 > DISPLAY_WIDTH-1 ||
|
|
||||||
py1 > DISPLAY_HEIGHT-1 ||
|
result = lcd_drawLine(px1, py1, px2, py1, color);
|
||||||
py2 > DISPLAY_HEIGHT-1) return;
|
result = lcd_drawLine(px2, py1, px2, py2, color);
|
||||||
lcd_drawLine(px1, py1, px2, py1, color);
|
result = lcd_drawLine(px2, py2, px1, py2, color);
|
||||||
lcd_drawLine(px2, py1, px2, py2, color);
|
result = lcd_drawLine(px1, py2, px1, py1, color);
|
||||||
lcd_drawLine(px2, py2, px1, py2, color);
|
|
||||||
lcd_drawLine(px1, py2, px1, py1, color);
|
return result;
|
||||||
}
|
}
|
||||||
void lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){
|
uint8_t lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){
|
||||||
|
uint8_t result;
|
||||||
|
|
||||||
if( px1 > px2){
|
if( px1 > px2){
|
||||||
uint8_t temp = px1;
|
uint8_t temp = px1;
|
||||||
px1 = px2;
|
px1 = px2;
|
||||||
@ -503,24 +434,24 @@ void lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t co
|
|||||||
py2 = temp;
|
py2 = temp;
|
||||||
}
|
}
|
||||||
for (uint8_t i=0; i<=(py2-py1); i++){
|
for (uint8_t i=0; i<=(py2-py1); i++){
|
||||||
lcd_drawLine(px1, py1+i, px2, py1+i, color);
|
result = lcd_drawLine(px1, py1+i, px2, py1+i, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
void lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color){
|
uint8_t lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color){
|
||||||
if( ((center_x + radius) > DISPLAY_WIDTH-1) ||
|
uint8_t result;
|
||||||
((center_y + radius) > DISPLAY_HEIGHT-1) ||
|
|
||||||
center_x < radius ||
|
|
||||||
center_y < radius) return;
|
|
||||||
int16_t f = 1 - radius;
|
int16_t f = 1 - radius;
|
||||||
int16_t ddF_x = 1;
|
int16_t ddF_x = 1;
|
||||||
int16_t ddF_y = -2 * radius;
|
int16_t ddF_y = -2 * radius;
|
||||||
int16_t x = 0;
|
int16_t x = 0;
|
||||||
int16_t y = radius;
|
int16_t y = radius;
|
||||||
|
|
||||||
lcd_drawPixel(center_x , center_y+radius, color);
|
result = lcd_drawPixel(center_x , center_y+radius, color);
|
||||||
lcd_drawPixel(center_x , center_y-radius, color);
|
result = lcd_drawPixel(center_x , center_y-radius, color);
|
||||||
lcd_drawPixel(center_x+radius, center_y , color);
|
result = lcd_drawPixel(center_x+radius, center_y , color);
|
||||||
lcd_drawPixel(center_x-radius, center_y , color);
|
result = lcd_drawPixel(center_x-radius, center_y , color);
|
||||||
|
|
||||||
while (x<y) {
|
while (x<y) {
|
||||||
if (f >= 0) {
|
if (f >= 0) {
|
||||||
@ -532,34 +463,63 @@ void lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t
|
|||||||
ddF_x += 2;
|
ddF_x += 2;
|
||||||
f += ddF_x;
|
f += ddF_x;
|
||||||
|
|
||||||
lcd_drawPixel(center_x + x, center_y + y, color);
|
result = lcd_drawPixel(center_x + x, center_y + y, color);
|
||||||
lcd_drawPixel(center_x - x, center_y + y, color);
|
result = lcd_drawPixel(center_x - x, center_y + y, color);
|
||||||
lcd_drawPixel(center_x + x, center_y - y, color);
|
result = lcd_drawPixel(center_x + x, center_y - y, color);
|
||||||
lcd_drawPixel(center_x - x, center_y - y, color);
|
result = lcd_drawPixel(center_x - x, center_y - y, color);
|
||||||
lcd_drawPixel(center_x + y, center_y + x, color);
|
result = lcd_drawPixel(center_x + y, center_y + x, color);
|
||||||
lcd_drawPixel(center_x - y, center_y + x, color);
|
result = lcd_drawPixel(center_x - y, center_y + x, color);
|
||||||
lcd_drawPixel(center_x + y, center_y - x, color);
|
result = lcd_drawPixel(center_x + y, center_y - x, color);
|
||||||
lcd_drawPixel(center_x - y, center_y - x, color);
|
result = lcd_drawPixel(center_x - y, center_y - x, color);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
void lcd_fillCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color) {
|
uint8_t lcd_fillCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color) {
|
||||||
|
uint8_t result;
|
||||||
for(uint8_t i=0; i<= radius;i++){
|
for(uint8_t i=0; i<= radius;i++){
|
||||||
lcd_drawCircle(center_x, center_y, i, color);
|
result = lcd_drawCircle(center_x, center_y, i, color);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
uint8_t lcd_drawBitmap(uint8_t x, uint8_t y, const uint8_t *picture, uint8_t width, uint8_t height, uint8_t color){
|
||||||
|
uint8_t result,i,j, byteWidth = (width+7)/8;
|
||||||
|
for (j = 0; j < height; j++) {
|
||||||
|
for(i=0; i < width;i++){
|
||||||
|
if(pgm_read_byte(picture + j * byteWidth + i / 8) & (128 >> (i & 7))){
|
||||||
|
result = lcd_drawPixel(x+i, y+j, color);
|
||||||
|
} else {
|
||||||
|
result = lcd_drawPixel(x+i, y+j, !color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
void lcd_display() {
|
void lcd_display() {
|
||||||
#if defined SSD1306
|
#if defined (SSD1306) || defined (SSD1309)
|
||||||
lcd_gotoxy(0,0);
|
lcd_gotoxy(0,0);
|
||||||
lcd_data(displayBuffer, sizeof(displayBuffer));
|
lcd_data(&displayBuffer[0][0], DISPLAY_WIDTH*DISPLAY_HEIGHT/8);
|
||||||
#elif defined SH1106
|
#elif defined SH1106
|
||||||
for (uint8_t i=0; i < DISPLAY_HEIGHT/8; i++) {
|
for (uint8_t i = 0; i < DISPLAY_HEIGHT/8; i++){
|
||||||
lcd_gotoxy(0, i);
|
lcd_gotoxy(0,i);
|
||||||
uint8_t actualLine[DISPLAY_WIDTH];
|
lcd_data(displayBuffer[i], sizeof(displayBuffer[i]));
|
||||||
for (uint8_t j=0; j < DISPLAY_WIDTH; j++) {
|
|
||||||
actualLine[j]=displayBuffer[i*DISPLAY_WIDTH+j];
|
|
||||||
}
|
|
||||||
lcd_data(actualLine, sizeof(actualLine));
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
void lcd_clear_buffer() {
|
||||||
|
for (uint8_t i = 0; i < DISPLAY_HEIGHT/8; i++){
|
||||||
|
memset(displayBuffer[i], 0x00, sizeof(displayBuffer[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint8_t lcd_check_buffer(uint8_t x, uint8_t y) {
|
||||||
|
if( x > DISPLAY_WIDTH-1 || y > (DISPLAY_HEIGHT-1)) return 0; // out of Display
|
||||||
|
return displayBuffer[(y / (DISPLAY_HEIGHT/8))][x] & (1 << (y % (DISPLAY_HEIGHT/8)));
|
||||||
|
}
|
||||||
|
void lcd_display_block(uint8_t x, uint8_t line, uint8_t width) {
|
||||||
|
if (line > (DISPLAY_HEIGHT/8-1) || x > DISPLAY_WIDTH - 1){return;}
|
||||||
|
if (x + width > DISPLAY_WIDTH) { // no -1 here, x alone is width 1
|
||||||
|
width = DISPLAY_WIDTH - x;
|
||||||
|
}
|
||||||
|
lcd_goto_xpix_y(x,line);
|
||||||
|
lcd_data(&displayBuffer[line][x], width);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
151
lcd.h
151
lcd.h
@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is part of lcd library for ssd1306/sh1106 oled-display.
|
* This file is part of lcd library for ssd1306/ssd1309/sh1106 oled-display.
|
||||||
*
|
*
|
||||||
* lcd library for ssd1306/sh1106 oled-display is free software: you can redistribute it and/or modify
|
* lcd library for ssd1306/ssd1309/sh1106 oled-display is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||||
*
|
*
|
||||||
* lcd library for ssd1306/sh1106 oled-display is distributed in the hope that it will be useful,
|
* lcd library for ssd1306/ssd1309/sh1106 oled-display is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
@ -13,14 +13,14 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* Diese Datei ist Teil von lcd library for ssd1306/sh1106 oled-display.
|
* Diese Datei ist Teil von lcd library for ssd1306/ssd1309/sh1106 oled-display.
|
||||||
*
|
*
|
||||||
* lcd library for ssd1306/sh1106 oled-display ist Freie Software: Sie können es unter den Bedingungen
|
* lcd library for ssd1306/ssd1309/sh1106 oled-display ist Freie Software: Sie können es unter den Bedingungen
|
||||||
* der GNU General Public License, wie von der Free Software Foundation,
|
* der GNU General Public License, wie von der Free Software Foundation,
|
||||||
* Version 3 der Lizenz oder jeder späteren
|
* Version 3 der Lizenz oder jeder späteren
|
||||||
* veröffentlichten Version, weiterverbreiten und/oder modifizieren.
|
* veröffentlichten Version, weiterverbreiten und/oder modifizieren.
|
||||||
*
|
*
|
||||||
* lcd library for ssd1306/sh1106 oled-display wird in der Hoffnung, dass es nützlich sein wird, aber
|
* lcd library for ssd1306/ssd1309/sh1106 oled-display wird in der Hoffnung, dass es nützlich sein wird, aber
|
||||||
* OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
|
* OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
|
||||||
* Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
|
* Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
|
||||||
* Siehe die GNU General Public License für weitere Details.
|
* Siehe die GNU General Public License für weitere Details.
|
||||||
@ -33,7 +33,7 @@
|
|||||||
* Created by Michael Köhler on 22.12.16.
|
* Created by Michael Köhler on 22.12.16.
|
||||||
* Copyright 2016 Skie-Systems. All rights reserved.
|
* Copyright 2016 Skie-Systems. All rights reserved.
|
||||||
*
|
*
|
||||||
* lib for OLED-Display with ssd1306/sh1106-Controller
|
* lib for OLED-Display with ssd1306/ssd1309/sh1106-Controller
|
||||||
* first dev-version only for I2C-Connection
|
* first dev-version only for I2C-Connection
|
||||||
* at ATMega328P like Arduino Uno
|
* at ATMega328P like Arduino Uno
|
||||||
*
|
*
|
||||||
@ -44,65 +44,106 @@
|
|||||||
#ifndef LCD_H
|
#ifndef LCD_H
|
||||||
#define LCD_H
|
#define LCD_H
|
||||||
|
|
||||||
#ifndef YES
|
#ifdef __cplusplus
|
||||||
#define YES 1
|
extern "C" {
|
||||||
#define NO 0
|
|
||||||
#else
|
|
||||||
#error "Check #defines for YES and NO in other sources !"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303
|
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303
|
||||||
#error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC compiler !"
|
#error "This library requires AVR-GCC 3.3 or later, update to newer AVR-GCC compiler !"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "i2c.h" // library for I2C-communication
|
|
||||||
// if you want to use other lib for I2C
|
|
||||||
// edit i2c_xxx commands in this library
|
|
||||||
// i2c_start(), i2c_byte(), i2c_stop()
|
|
||||||
|
|
||||||
/* TODO: define displaycontroller */
|
/* TODO: define bus */
|
||||||
#define SH1106 // or SSD1306, check datasheet of your display
|
#define I2C // I2C or SPI
|
||||||
/* TODO: define displaymode */
|
/* TODO: define displaycontroller */
|
||||||
#define GRAPHICMODE // TEXTMODE for only text to display,
|
#define SH1106 // or SSD1306, check datasheet of your display
|
||||||
// GRAPHICMODE for text and graphic
|
/* TODO: define displaymode */
|
||||||
|
#define TEXTMODE // TEXTMODE for only text to display,
|
||||||
|
// GRAPHICMODE for text and graphic
|
||||||
|
/* TODO: define font */
|
||||||
|
#define FONT ssd1306oled_font// set font here, refer font-name at font.h/font.c
|
||||||
|
|
||||||
|
/* TODO: define I2C-adress for display */
|
||||||
|
|
||||||
|
// using 7-bit-adress for lcd-library
|
||||||
|
// if you use your own library for twi check I2C-adress-handle
|
||||||
|
#define LCD_I2C_ADR (0x78 >> 1) // 7 bit slave-adress without r/w-bit
|
||||||
|
// r/w-bit are set/unset by library
|
||||||
|
// e.g. 8 bit slave-adress:
|
||||||
|
// 0x78 = adress 0x3C with cleared r/w-bit (write-mode)
|
||||||
|
|
||||||
#define LCD_I2C_ADR 0x7A
|
|
||||||
|
#ifdef I2C
|
||||||
|
#include "i2c.h" // library for I2C-communication
|
||||||
|
// if you want to use other lib for I2C
|
||||||
|
// edit i2c_xxx commands in this library
|
||||||
|
// i2c_start(), i2c_byte(), i2c_stop()
|
||||||
|
|
||||||
|
#elif defined SPI
|
||||||
|
// if you want to use your other lib/function for SPI replace SPI-commands
|
||||||
|
#define LCD_PORT PORTB
|
||||||
|
#define LCD_DDR DDRB
|
||||||
|
#define RES_PIN PB0
|
||||||
|
#define DC_PIN PB1
|
||||||
|
#define CS_PIN PB2
|
||||||
|
|
||||||
#define LCD_DISP_OFF 0xAE
|
#endif
|
||||||
#define LCD_DISP_ON 0xAF
|
|
||||||
|
|
||||||
#define WHITE 0x01
|
#ifndef YES
|
||||||
#define BLACK 0x00
|
#define YES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DISPLAY_WIDTH 128
|
#define NORMALSIZE 1
|
||||||
#define DISPLAY_HEIGHT 64
|
#define DOUBLESIZE 2
|
||||||
#define DISPLAYSIZE DISPLAY_WIDTH*DISPLAY_HEIGHT/8
|
|
||||||
|
#define LCD_DISP_OFF 0xAE
|
||||||
void lcd_command(uint8_t cmd[], uint8_t size); // transmit command to display
|
#define LCD_DISP_ON 0xAF
|
||||||
void lcd_data(uint8_t data[], uint16_t size); // transmit data to display
|
|
||||||
void lcd_init(uint8_t dispAttr);
|
#define WHITE 0x01
|
||||||
void lcd_home(void); // set cursor to 0,0
|
#define BLACK 0x00
|
||||||
void lcd_invert(uint8_t invert); // invert display
|
|
||||||
void lcd_set_contrast(uint8_t contrast); // set contrast for display
|
#define DISPLAY_WIDTH 128
|
||||||
void lcd_puts(const char* s); // print string, \n-terminated, from ram on screen (TEXTMODE)
|
#define DISPLAY_HEIGHT 64
|
||||||
// or buffer (GRAPHICMODE)
|
|
||||||
void lcd_puts_p(const char* progmem_s); // print string from flash on screen (TEXTMODE)
|
|
||||||
// or buffer (GRAPHICMODE)
|
|
||||||
|
void lcd_command(uint8_t cmd[], uint8_t size); // transmit command to display
|
||||||
void lcd_clrscr(void); // clear screen (and buffer at GRFAICMODE)
|
void lcd_data(uint8_t data[], uint16_t size); // transmit data to display
|
||||||
void lcd_gotoxy(uint8_t x, uint8_t y); // set curser at pos x, y. x means character,
|
void lcd_init(uint8_t dispAttr);
|
||||||
// y means line (page, refer lcd manual)
|
void lcd_home(void); // set cursor to 0,0
|
||||||
void lcd_putc(char c); // print character on screen at TEXTMODE
|
void lcd_invert(uint8_t invert); // invert display
|
||||||
// at GRAPHICMODE print character to buffer
|
void lcd_sleep(uint8_t sleep); // display goto sleep (power off)
|
||||||
|
void lcd_set_contrast(uint8_t contrast); // set contrast for display
|
||||||
|
void lcd_puts(const char* s); // print string, \n-terminated, from ram on screen (TEXTMODE)
|
||||||
|
// or buffer (GRAPHICMODE)
|
||||||
|
void lcd_puts_p(const char* progmem_s); // print string from flash on screen (TEXTMODE)
|
||||||
|
// or buffer (GRAPHICMODE)
|
||||||
|
|
||||||
|
void lcd_clrscr(void); // clear screen (and buffer at GRFAICMODE)
|
||||||
|
void lcd_gotoxy(uint8_t x, uint8_t y); // set curser at pos x, y. x means character,
|
||||||
|
// y means line (page, refer lcd manual)
|
||||||
|
void lcd_goto_xpix_y(uint8_t x, uint8_t y); // set curser at pos x, y. x means pixel,
|
||||||
|
// y means line (page, refer lcd manual)
|
||||||
|
void lcd_putc(char c); // print character on screen at TEXTMODE
|
||||||
|
// at GRAPHICMODE print character to buffer
|
||||||
|
void lcd_charMode(uint8_t mode); // set size of chars
|
||||||
#if defined GRAPHICMODE
|
#if defined GRAPHICMODE
|
||||||
void lcd_drawPixel(uint8_t x, uint8_t y, uint8_t color);
|
uint8_t lcd_drawPixel(uint8_t x, uint8_t y, uint8_t color);
|
||||||
void lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color);
|
uint8_t lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color);
|
||||||
void lcd_drawRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color);
|
uint8_t lcd_drawRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color);
|
||||||
void lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color);
|
uint8_t lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color);
|
||||||
void lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color);
|
uint8_t lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color);
|
||||||
void lcd_fillCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color);
|
uint8_t lcd_fillCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color);
|
||||||
void lcd_display(void); // copy buffer to display RAM
|
uint8_t lcd_drawBitmap(uint8_t x, uint8_t y, const uint8_t picture[], uint8_t width, uint8_t height, uint8_t color);
|
||||||
|
void lcd_display(void); // copy buffer to display RAM
|
||||||
|
void lcd_clear_buffer(void); // clear display buffer
|
||||||
|
uint8_t lcd_check_buffer(uint8_t x, uint8_t y); // read a pixel value from the display buffer
|
||||||
|
void lcd_display_block(uint8_t x, uint8_t line, uint8_t width); // display (part of) a display line
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /* LCD_H */
|
#endif /* LCD_H */
|
||||||
|
BIN
oled.jpg
Normale Datei
BIN
oled.jpg
Normale Datei
Binäre Datei nicht angezeigt.
Nachher Breite: | Höhe: | Größe: 1.1 MiB |
43
readme
43
readme
@ -1,43 +0,0 @@
|
|||||||
Library for oled-displays with SSD1306 or SH1106 display-controller connected with I2C at an AVR Atmel Atmega like Atmega328P.
|
|
||||||
|
|
||||||
This library allows you to display text or/and graphic at oled-display.
|
|
||||||
The library need less then 2000 bytes flash-memory in textmode and less then 3200 bytes in graphicmode so you can use oled-displays e.g with Atmega48PA.
|
|
||||||
Library is only tested with 128x64 Pixel display, lower resolution not tested but should work too.
|
|
||||||
|
|
||||||
If you want to use your own I2C library you have to fit i2c-function at lcd-library.
|
|
||||||
Settings for I2C-bus have to set at i2c.h
|
|
||||||
Settings for display have to set at lcd.h
|
|
||||||
|
|
||||||
If you want to use characters like e.g. ä set your compiler input-charset to utf-8 and your compiler exec-charset to iso-8859-15 (look at makefile line 115).
|
|
||||||
|
|
||||||
example:
|
|
||||||
|
|
||||||
//****main.c****//
|
|
||||||
#include "lcd.h"
|
|
||||||
|
|
||||||
|
|
||||||
int main(void){
|
|
||||||
lcd_init(LCD_DISP_ON); // init lcd and turn on
|
|
||||||
|
|
||||||
lcd_puts("Hello World"); // put string from RAM to display (TEXTMODE) or buffer (GRAPHICMODE)
|
|
||||||
lcd_gotoxy(0,2); // set cursor to first column at line 3
|
|
||||||
lcd_puts_p(PSTR("String from flash")); // puts string form flash to display (TEXTMODE) or buffer (GRAPHICMODE)
|
|
||||||
#if defined GRAPHICMODE
|
|
||||||
lcd_drawCircle(64,32,7,WHITE); // draw circle to buffer
|
|
||||||
lcd_display(); // send buffer to display
|
|
||||||
#endif
|
|
||||||
for(;;){
|
|
||||||
//main loop
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
For Arduino-Users:
|
|
||||||
|
|
||||||
Remember that this library is a c-library. Type
|
|
||||||
|
|
||||||
extern "C"{
|
|
||||||
#include "lcd.h"
|
|
||||||
}
|
|
||||||
|
|
||||||
for include.
|
|
130
readme.md
Normale Datei
130
readme.md
Normale Datei
@ -0,0 +1,130 @@
|
|||||||
|
# OLED for AVR mikrocontrollers
|
||||||
|
Library for oled-displays with SSD1306, SSD1309 or SH1106 display-controller connected with I2C or SPI at an AVR Atmel Atmega like Atmega328P.
|
||||||
|
|
||||||
|
<img src="https://github.com/Sylaina/oled-display/blob/master/oled.jpg?raw=true" width="500">
|
||||||
|
|
||||||
|
This library allows you to display text or/and graphic at oled-display.
|
||||||
|
The library need less than 2 kilobytes flash-memory and 3 bytes sram in textmode, in graphicmode library need less than 3 kilobytes flash-memory and 1027 bytes static sram so you can use oled-displays e.g with Atmega48PA (only with textmode).
|
||||||
|
Library is only tested with 128x64 Pixel display, lower resolution not tested but should work too.
|
||||||
|
|
||||||
|
If you want to use your own I2C library you have to fit i2c-function at lcd-library.
|
||||||
|
Settings for I2C-bus have to set at i2c.h
|
||||||
|
Settings for display have to set at lcd.h
|
||||||
|
|
||||||
|
If you want to use characters like e.g. ä set your compiler input-charset to utf-8 and your compiler exec-charset to iso-8859-15 (look at makefile line 115).
|
||||||
|
|
||||||
|
Testcondition: Display: SSD1306 OLED, Compiler Optimizelevel: -Os, µC: Atmega328p @ 8 MHz internal RC
|
||||||
|
|
||||||
|
Memory:
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Modul</th>
|
||||||
|
<th>Flash</th>
|
||||||
|
<th>Static RAM</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>I2C-Core</td>
|
||||||
|
<td>220 Bytes</td>
|
||||||
|
<td>0 Bytes</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>FONT</td>
|
||||||
|
<td>644 Bytes</td>
|
||||||
|
<td>0 Bytes</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OLED (Text-Mode)</td>
|
||||||
|
<td>1395 Bytes</td>
|
||||||
|
<td>3 Bytes</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OLED (Graphic-Mode)</td>
|
||||||
|
<td>2541 Bytes</td>
|
||||||
|
<td>1027 Bytes</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Speed (print 20 charaters (1 line) in normal size to display):
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Mode</th>
|
||||||
|
<th>Time</th>
|
||||||
|
<th>I2C-Speed</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OLED (Text-Mode)</td>
|
||||||
|
<td>4.411 ms</td>
|
||||||
|
<td>400 kHz</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OLED (Text-Mode)</td>
|
||||||
|
<td>15.384 ms</td>
|
||||||
|
<td>100 kHz</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OLED (Graphic-Mode)</td>
|
||||||
|
<td>26.603 ms</td>
|
||||||
|
<td>400 kHz</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>OLED (Graphic-Mode)</td>
|
||||||
|
<td>96.294 ms</td>
|
||||||
|
<td>100 kHz</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
example:
|
||||||
|
|
||||||
|
```c
|
||||||
|
//****main.c****//
|
||||||
|
#include "lcd.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
lcd_init(LCD_DISP_ON); // init lcd and turn on
|
||||||
|
|
||||||
|
lcd_puts("Hello World"); // put string from RAM to display (TEXTMODE) or buffer (GRAPHICMODE)
|
||||||
|
lcd_gotoxy(0,2); // set cursor to first column at line 3
|
||||||
|
lcd_puts_p(PSTR("String from flash")); // puts string form flash to display (TEXTMODE) or buffer (GRAPHICMODE)
|
||||||
|
#if defined GRAPHICMODE
|
||||||
|
lcd_drawCircle(64,32,7,WHITE); // draw circle to buffer
|
||||||
|
lcd_display(); // send buffer to display
|
||||||
|
#endif
|
||||||
|
for(;;){
|
||||||
|
//main loop
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
example for chars with double height:
|
||||||
|
```c
|
||||||
|
//****main.c****//
|
||||||
|
#include "lcd.h"
|
||||||
|
|
||||||
|
int main(void){
|
||||||
|
|
||||||
|
lcd_init(LCD_DISP_ON);
|
||||||
|
lcd_clrscr();
|
||||||
|
lcd_set_contrast(0x00);
|
||||||
|
lcd_gotoxy(4,1);
|
||||||
|
lcd_puts("Normal Size");
|
||||||
|
lcd_charMode(DOUBLESIZE);
|
||||||
|
lcd_gotoxy(0,4);
|
||||||
|
lcd_puts(" Double \r\n Size");
|
||||||
|
lcd_charMode(NORMALSIZE);
|
||||||
|
|
||||||
|
#ifdef GRAPHICMODE
|
||||||
|
lcd_display();
|
||||||
|
#endif
|
||||||
|
for(;;){
|
||||||
|
//main loop
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<img src="https://github.com/Sylaina/oled-display/blob/master/bigchars.JPG?raw=true" width="500">
|
Laden…
x
In neuem Issue referenzieren
Einen Benutzer sperren