Commits vergleichen

...

91 Commits

Autor SHA1 Nachricht Datum
Sylaina
1f58753823
Update font.c 2021-06-26 16:23:00 +02:00
Sylaina
64341a0d5f
Update Makefile 2021-06-26 16:13:57 +02:00
Sylaina
a48b2e11cb
Update font.c
Add 'Ω' and 'ω' to special charset
2021-06-25 20:51:33 +02:00
Sylaina
d684610c00 Some improvements
Add return-values for some graphic function for error handling.
Improved some graphic functions to reduce needed flash.
Update readme for flash size values
2021-04-08 20:47:51 +02:00
Sylaina
a8fb621eff
Update readme.md 2020-03-30 09:31:41 +02:00
Sylaina
64c964d318
Update lcd.c
Modified init_sequence for different DISPLAY_HEIGHT
2020-03-17 07:13:48 +01:00
Sylaina
525ecf6775
Merge pull request #5 from PaulKlinger/master
Some simple functions for manipulating display buffer/partial updates
2019-12-12 09:35:15 +01:00
Sylaina
4156fd4757
Update lcd.c 2019-09-18 16:18:07 +02:00
Sylaina
c0b15fc20b
Update Makefile 2019-09-18 13:43:44 +02:00
Sylaina
9a4ad9da42
Update readme.md 2019-09-18 11:24:52 +02:00
Sylaina
a9cd2b0baf
Update lcd.c
Add SPI and SSD1309 support
2019-09-18 11:23:38 +02:00
Sylaina
6eab4e7a36
Update lcd.h
Add SPI and SSD1309 support
2019-09-18 11:22:40 +02:00
Sylaina
4a5bc75a1f
Update lcd.c 2019-09-13 07:15:41 +02:00
Sylaina
51aa9ebc5b
Update readme.md 2019-09-13 06:42:23 +02:00
Sylaina
5f4084d9b5
Update i2c.c 2019-09-13 06:36:02 +02:00
Sylaina
ef8b0b85ac
Update lcd.c 2019-09-13 06:33:29 +02:00
Sylaina
4db4927c8d
Update readme.md 2019-09-13 06:18:46 +02:00
Sylaina
2693043cf2
Update lcd.c
Cleanup code
2019-09-13 06:13:55 +02:00
Sylaina
eae35b14aa
Update readme.md 2019-07-10 11:23:09 +02:00
Sylaina
6e6558b7c4
Update readme.md 2019-07-10 11:22:26 +02:00
Paul Klinger
6a4b62579d truncate display_block area if too large 2019-02-13 01:21:19 +01:00
Paul Klinger
0dbd2a14d7 truncate display_block area if too large 2019-02-12 18:26:26 +01:00
Paul Klinger
7f42d3f89a added comment 2019-02-08 19:07:10 +01:00
Paul Klinger
4b49d467c9 tabs/spaces 2019-02-08 17:59:27 +01:00
Paul Klinger
0e14c81df2 use lcd_goto_xpix_y for lcd_gotoxy 2019-02-08 17:55:52 +01:00
Paul Klinger
834f7875a3 added some functions
Added functions to move to goto a specific x pixel, clear display buffer, read from display buffer, and transfer only a portion of the buffer to the display.
2019-02-08 00:50:29 +01:00
Sylaina
fa446f6111
Update lcd.c 2019-01-28 13:18:31 +01:00
Sylaina
c8dce5e4a7
Update lcd.c
draw bitmaps inverted
2019-01-28 13:11:27 +01:00
Sylaina
c7a4bae4f8
Update readme.md 2019-01-02 07:07:53 +01:00
Sylaina
62a2b68e08
Update i2c.h 2018-12-06 21:33:03 +01:00
Sylaina
76fd115015
Update readme.md 2018-12-06 11:00:05 +01:00
Sylaina
d388cf7a38
Update readme.md 2018-12-06 10:58:02 +01:00
Sylaina
9020ebcfb5
Update readme.md 2018-12-05 15:33:49 +01:00
Sylaina
0af7a4510b
Update readme.md 2018-12-05 08:19:34 +01:00
Sylaina
d6b75b03a0
Update readme.md 2018-12-05 08:15:58 +01:00
Sylaina
f252207b4b
Update and rename readme to readme.md 2018-12-05 08:06:18 +01:00
Sylaina
47b2d8f40e
Update readme 2018-12-05 08:04:14 +01:00
Sylaina
857d0ac0ec
Update lcd.h 2018-12-05 07:59:46 +01:00
Sylaina
9139b4830d
Update lcd.c 2018-12-05 07:58:59 +01:00
Sylaina
82533902dd
Update lcd.c 2018-12-04 10:59:38 +01:00
Sylaina
52a024dff4
Add files via upload 2018-12-04 06:25:44 +01:00
Sylaina
6014d0996f
Update lcd.c 2018-12-03 11:59:07 +01:00
Sylaina
38a874c498
Update lcd.c 2018-12-03 11:46:41 +01:00
Sylaina
c1958d225c
Update readme 2018-12-03 11:45:30 +01:00
Sylaina
d28a7056a2
Update lcd.h 2018-12-03 11:41:47 +01:00
Sylaina
981140645e
Update lcd.c 2018-12-03 11:39:19 +01:00
Sylaina
dc337751ab
Update lcd.c 2018-12-03 09:15:35 +01:00
Sylaina
08ceb8e31b
Update readme 2018-11-05 16:39:30 +01:00
Sylaina
5c8717bcff
Update readme 2018-10-01 12:00:47 +02:00
Sylaina
316a742613
Update readme 2018-09-28 07:55:43 +02:00
Sylaina
49661d6307
Update readme 2018-09-28 07:52:47 +02:00
Sylaina
ced1214fc8
Update lcd.h 2018-09-28 07:36:03 +02:00
Sylaina
7e3bb2178f
Update readme 2018-09-28 07:35:29 +02:00
Sylaina
2d89fc679b
Update readme 2018-09-28 07:29:27 +02:00
Sylaina
6213e67b5e
Update lcd.c 2018-09-28 07:22:25 +02:00
Sylaina
ab1f3bc5a5
Update i2c.c 2018-09-21 16:42:33 +02:00
Sylaina
f9b276eaf8
Update lcd.c 2018-09-19 19:40:58 +02:00
Sylaina
a036086139
Update font.c 2018-09-18 22:26:38 +02:00
Sylaina
61ca2e1dc7
Update lcd.c 2018-09-18 21:50:22 +02:00
Sylaina
052b5f8509
Update lcd.c 2018-09-18 21:38:21 +02:00
Sylaina
37f87540fb
Update lcd.c 2018-09-18 21:25:53 +02:00
Sylaina
ffbcc49066
Update readme 2018-09-18 21:07:01 +02:00
Sylaina
f168b52b65
Update readme 2018-09-18 21:05:00 +02:00
Sylaina
6f607980a5
Update lcd.h 2018-09-18 20:55:35 +02:00
Sylaina
ab349346fe
Update lcd.c 2018-09-18 20:55:06 +02:00
Sylaina
db0972c8e9
Update readme 2018-09-18 18:32:59 +02:00
Sylaina
1dc61cedfb
Update readme 2018-09-18 18:32:13 +02:00
Sylaina
02cf7f2216
Add files via upload 2018-09-18 18:21:56 +02:00
Sylaina
88f9e97cdd
Update lcd.h 2018-09-18 18:07:01 +02:00
Sylaina
94c5e66678
Update lcd.c 2018-09-18 18:02:42 +02:00
Sylaina
f2746b5ff9
Update Makefile 2018-09-18 17:44:53 +02:00
Sylaina
ded0169f46
Update lcd.c 2018-09-17 18:15:06 +02:00
Sylaina
59fcdf520a
Update lcd.c 2018-09-17 11:38:26 +02:00
Sylaina
9e96e2cb7f
Update lcd.c 2018-09-17 11:25:12 +02:00
Sylaina
06ac702c66
Update font.h 2018-09-17 11:21:31 +02:00
Sylaina
a9260532d4
Update font.c 2018-09-17 11:21:00 +02:00
Sylaina
509f1ace70
Update readme 2018-09-17 09:41:14 +02:00
Sylaina
10d5bb5bf0
Update lcd.c 2018-09-17 09:35:37 +02:00
Sylaina
3c72a18a0e
Update font.h 2018-09-16 08:52:29 +02:00
Sylaina
0bc6f6b96e
Create font.c 2018-09-16 08:51:18 +02:00
Sylaina
519641b1e9
Update lcd.c 2018-09-16 07:52:43 +02:00
Sylaina
53b690b329
Update font.h 2018-09-15 13:54:47 +02:00
Sylaina
be58852484
Add files via upload 2018-09-15 13:44:26 +02:00
Sylaina
779310c839
Add files via upload 2018-09-15 13:43:44 +02:00
Sylaina
50929ad99a
Update lcd.h
- improved lcd_putc()
- fix lcd_invert()
2018-09-15 13:35:18 +02:00
Sylaina
827aa808dd
Update lcd.c
- improved lcd_putc() function
- fix lcd_invert()
2018-09-15 13:33:29 +02:00
Sylaina
416ea430a4
Add files via upload
contains a 6x8 font for display
2018-09-15 13:31:14 +02:00
Sylaina
727bf2b507
Update i2c.c
add comments for using functions
2018-02-20 07:45:46 +01:00
Sylaina
ecc3c11a5a
Update lcd.h
add information for setting I2C-adress
2018-02-20 06:30:45 +01:00
Sylaina
709cc1f78e
Update lcd.c
add draw bitmap
2018-02-18 06:59:48 +01:00
Sylaina
a9caa935b3
Update lcd.h
add draw bitmap
2018-02-18 06:58:50 +01:00
11 geänderte Dateien mit 844 neuen und 523 gelöschten Zeilen

Datei anzeigen

@ -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äre Datei nicht angezeigt.

Nachher

Breite:  |  Höhe:  |  Größe: 1.0 MiB

140
font.c Normale Datei
Datei anzeigen

@ -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
Datei anzeigen

@ -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
Datei anzeigen

@ -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
Datei anzeigen

@ -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
Datei anzeigen

@ -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
Datei anzeigen

@ -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äre Datei nicht angezeigt.

Nachher

Breite:  |  Höhe:  |  Größe: 1.1 MiB

43
readme
Datei anzeigen

@ -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
Datei anzeigen

@ -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">