Commits vergleichen
Keine gemeinsamen Commits. "master" und "v1.0.1" haben vollständig unterschiedliche Historien.
8
Makefile
8
Makefile
@ -42,7 +42,7 @@ MCU = atmega328p
|
||||
|
||||
# Main Oscillator Frequency
|
||||
# This is only used to define F_CPU in all assembler and c-sources.
|
||||
F_CPU = 16000000UL
|
||||
F_CPU = 14745600UL
|
||||
|
||||
# Output format. (can be srec, ihex, binary)
|
||||
FORMAT = ihex
|
||||
@ -52,7 +52,7 @@ TARGET = main
|
||||
|
||||
|
||||
# List C source files here. (C dependencies are automatically generated.)
|
||||
SRC = $(wildcard *.c)
|
||||
SRC = $(TARGET).c i2c.c lcd.c
|
||||
|
||||
# List Assembler source files here.
|
||||
# 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 += $(CSTANDARD)
|
||||
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_VERBOSE)
|
||||
AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)
|
||||
AVRDUDE_FLAGS += -b 19200
|
||||
AVRDUDE_FLAGS += -B 1
|
||||
|
||||
|
||||
|
||||
|
BIN
bigchars.JPG
BIN
bigchars.JPG
Binäre Datei nicht angezeigt.
Vorher Breite: | Höhe: | Größe: 1.0 MiB |
140
font.c
140
font.c
@ -1,140 +0,0 @@
|
||||
/*
|
||||
* 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
16
font.h
@ -1,16 +0,0 @@
|
||||
/*
|
||||
* 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
|
71
i2c.c
71
i2c.c
@ -8,16 +8,7 @@
|
||||
|
||||
#include "i2c.h"
|
||||
|
||||
#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 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 PSC_I2C != 1 && PSC_I2C != 4 && PSC_I2C != 16 && PSC_I2C != 64
|
||||
#error "Wrong prescaler for TWI !"
|
||||
#elif SET_TWBR < 0 || SET_TWBR > 255
|
||||
@ -25,15 +16,7 @@ defined (__AVR_ATmega2560__)
|
||||
#endif
|
||||
|
||||
uint8_t I2C_ErrorCode;
|
||||
/**********************************************
|
||||
Public Function: i2c_init
|
||||
|
||||
Purpose: Initialise TWI/I2C interface
|
||||
|
||||
Input Parameter: none
|
||||
|
||||
Return Value: none
|
||||
**********************************************/
|
||||
void i2c_init(void){
|
||||
// set clock
|
||||
switch (PSC_I2C) {
|
||||
@ -54,16 +37,6 @@ void i2c_init(void){
|
||||
// enable
|
||||
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){
|
||||
// i2c start
|
||||
TWCR = (1 << TWINT)|(1 << TWSTA)|(1 << TWEN);
|
||||
@ -89,29 +62,10 @@ 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){
|
||||
// i2c stop
|
||||
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){
|
||||
TWDR = byte;
|
||||
TWCR = (1 << TWINT)|( 1 << TWEN);
|
||||
@ -125,17 +79,6 @@ 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){
|
||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
|
||||
uint16_t timeout = F_CPU/F_I2C*2.0;
|
||||
@ -149,18 +92,6 @@ uint8_t i2c_readAck(void){
|
||||
};
|
||||
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){
|
||||
TWCR = (1<<TWINT)|(1<<TWEN);
|
||||
uint16_t timeout = F_CPU/F_I2C*2.0;
|
||||
|
8
i2c.h
8
i2c.h
@ -9,10 +9,6 @@
|
||||
#ifndef i2c_h
|
||||
#define i2c_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* TODO: setup i2c/twi */
|
||||
#define F_I2C 100000UL// clock i2c
|
||||
#define PSC_I2C 1 // prescaler i2c
|
||||
@ -39,8 +35,4 @@ void i2c_byte(uint8_t byte); // send data_byte
|
||||
uint8_t i2c_readAck(void); // read byte with ACK
|
||||
uint8_t i2c_readNAck(void); // read byte with NACK
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* i2c_h */
|
||||
|
740
lcd.c
740
lcd.c
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* This file is part of lcd library for ssd1306/ssd1309/sh1106 oled-display.
|
||||
* This file is part of lcd library for ssd1306/sh1106 oled-display.
|
||||
*
|
||||
* lcd library for ssd1306/ssd1309/sh1106 oled-display is free software: you can redistribute it and/or modify
|
||||
* lcd library for ssd1306/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
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
*
|
||||
* lcd library for ssd1306/ssd1309/sh1106 oled-display is distributed in the hope that it will be useful,
|
||||
* lcd library for ssd1306/sh1106 oled-display is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
@ -13,14 +13,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Diese Datei ist Teil von lcd library for ssd1306/ssd1309/sh1106 oled-display.
|
||||
* Diese Datei ist Teil von lcd library for ssd1306/sh1106 oled-display.
|
||||
*
|
||||
* lcd library for ssd1306/ssd1309/sh1106 oled-display ist Freie Software: Sie können es unter den Bedingungen
|
||||
* lcd library for ssd1306/sh1106 oled-display ist Freie Software: Sie können es unter den Bedingungen
|
||||
* der GNU General Public License, wie von der Free Software Foundation,
|
||||
* Version 3 der Lizenz oder jeder späteren
|
||||
* veröffentlichten Version, weiterverbreiten und/oder modifizieren.
|
||||
*
|
||||
* lcd library for ssd1306/ssd1309/sh1106 oled-display wird in der Hoffnung, dass es nützlich sein wird, aber
|
||||
* lcd library for ssd1306/sh1106 oled-display wird in der Hoffnung, dass es nützlich sein wird, aber
|
||||
* OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
|
||||
* Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
|
||||
* Siehe die GNU General Public License für weitere Details.
|
||||
@ -33,39 +33,130 @@
|
||||
* Created by Michael Köhler on 22.12.16.
|
||||
* Copyright 2016 Skie-Systems. All rights reserved.
|
||||
*
|
||||
* lib for OLED-Display with ssd1306/ssd1309/sh1106-Controller
|
||||
* lib for OLED-Display with ssd1306/sh1106-Controller
|
||||
* first dev-version only for I2C-Connection
|
||||
* at ATMega328P like Arduino Uno
|
||||
*
|
||||
* at GRAPHICMODE lib needs static SRAM for display:
|
||||
* at GRAPHICMODE lib needs SRAM for display
|
||||
* DISPLAY-WIDTH * DISPLAY-HEIGHT + 2 bytes
|
||||
*
|
||||
* at TEXTMODE lib need static SRAM for display:
|
||||
* 2 bytes (cursorPosition)
|
||||
*/
|
||||
|
||||
#include "lcd.h"
|
||||
#include "font.h"
|
||||
#include <string.h>
|
||||
|
||||
#if defined SPI
|
||||
#include <util/delay.h>
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} cursorPosition;
|
||||
|
||||
static uint8_t charMode = NORMALSIZE;
|
||||
uint8_t cursorPosition=0;
|
||||
#if defined GRAPHICMODE
|
||||
#include <stdlib.h>
|
||||
static uint8_t displayBuffer[DISPLAY_HEIGHT/8][DISPLAY_WIDTH];
|
||||
#elif defined TEXTMODE
|
||||
#else
|
||||
#error "No valid displaymode! Refer lcd.h"
|
||||
static uint8_t displayBuffer[DISPLAYSIZE];
|
||||
uint16_t actualIndex = 0;
|
||||
#endif
|
||||
|
||||
/* Standard ASCII 6x8 font */
|
||||
static const uint8_t ssd1306oled_font6x8 [] 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, // ~
|
||||
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
|
||||
LCD_DISP_OFF, // Display OFF (sleep mode)
|
||||
@ -80,77 +171,38 @@ const uint8_t init_sequence [] PROGMEM = { // Initialization Sequence
|
||||
0x81, 0x3F, // Set contrast control register
|
||||
0xA1, // Set Segment Re-map. A0=address mapped; A1=address 127 mapped.
|
||||
0xA6, // Set display mode. A6=Normal; A7=Inverse
|
||||
0xA8, DISPLAY_HEIGHT-1, // Set multiplex ratio(1 to 64)
|
||||
0xA8, 0x3F, // 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
|
||||
0xDA, 0x12, // Set com pins hardware configuration
|
||||
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) {
|
||||
#if defined I2C
|
||||
i2c_start((LCD_I2C_ADR << 1) | 0);
|
||||
i2c_start(LCD_I2C_ADR);
|
||||
i2c_byte(0x00); // 0x00 for command, 0x40 for data
|
||||
for (uint8_t i=0; i<size; i++) {
|
||||
i2c_byte(cmd[i]);
|
||||
}
|
||||
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) {
|
||||
#if defined I2C
|
||||
i2c_start((LCD_I2C_ADR << 1) | 0);
|
||||
i2c_start(LCD_I2C_ADR);
|
||||
i2c_byte(0x40); // 0x00 for command, 0x40 for data
|
||||
for (uint16_t i = 0; i<size; i++) {
|
||||
i2c_byte(data[i]);
|
||||
}
|
||||
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){
|
||||
#if defined I2C
|
||||
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];
|
||||
for (uint8_t i = 0; i < sizeof (init_sequence); i++) {
|
||||
commandSequence[i] = (pgm_read_byte(&init_sequence[i]));
|
||||
@ -159,217 +211,23 @@ void lcd_init(uint8_t dispAttr){
|
||||
lcd_command(commandSequence, sizeof(commandSequence));
|
||||
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){
|
||||
lcd_gotoxy(0, 0);
|
||||
}
|
||||
void lcd_invert(uint8_t invert){
|
||||
i2c_start(LCD_I2C_ADR);
|
||||
uint8_t commandSequence[1];
|
||||
if (invert != YES) {
|
||||
commandSequence[0] = 0xA6;
|
||||
if (invert == YES) {
|
||||
commandSequence[0] = 0xA7;
|
||||
} else {
|
||||
commandSequence[0] = 0xA7;
|
||||
}
|
||||
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){
|
||||
uint8_t commandSequence[2] = {0x81, contrast};
|
||||
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){
|
||||
while (*s) {
|
||||
lcd_putc(*s++);
|
||||
@ -381,50 +239,261 @@ void lcd_puts_p(const char* progmem_s){
|
||||
lcd_putc(c);
|
||||
}
|
||||
}
|
||||
#ifdef GRAPHICMODE
|
||||
#pragma mark -
|
||||
#pragma mark GRAPHIC FUNCTIONS
|
||||
uint8_t lcd_drawPixel(uint8_t x, uint8_t y, uint8_t color){
|
||||
if( x > DISPLAY_WIDTH-1 || y > (DISPLAY_HEIGHT-1)) return 1; // out of Display
|
||||
#if defined TEXTMODE
|
||||
void lcd_clrscr(void){
|
||||
uint8_t clearLine[DISPLAY_WIDTH];
|
||||
memset(clearLine, 0x00, DISPLAY_WIDTH);
|
||||
for (uint8_t j = 0; j < DISPLAY_HEIGHT/8; j++){
|
||||
lcd_gotoxy(0,j);
|
||||
lcd_data(clearLine, sizeof(clearLine));
|
||||
|
||||
if( color == WHITE){
|
||||
displayBuffer[(y / 8)][x] |= (1 << (y % 8));
|
||||
} else {
|
||||
displayBuffer[(y / 8)][x] &= ~(1 << (y % 8));
|
||||
}
|
||||
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
uint8_t lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color){
|
||||
uint8_t result;
|
||||
|
||||
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){
|
||||
displayBuffer[(uint8_t)(y / (DISPLAY_HEIGHT/8)) * DISPLAY_WIDTH +x] |= (1 << (y % (DISPLAY_HEIGHT/8)));
|
||||
} else {
|
||||
displayBuffer[(uint8_t)(y / (DISPLAY_HEIGHT/8)) * DISPLAY_WIDTH +x] &= ~(1 << (y % (DISPLAY_HEIGHT/8)));
|
||||
}
|
||||
}
|
||||
void lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color){
|
||||
if( x1 > DISPLAY_WIDTH-1 ||
|
||||
x2 > DISPLAY_WIDTH-1 ||
|
||||
y1 > DISPLAY_HEIGHT-1 ||
|
||||
y2 > DISPLAY_HEIGHT-1) return;
|
||||
int dx = abs(x2-x1), sx = x1<x2 ? 1 : -1;
|
||||
int dy = -abs(y2-y1), sy = y1<y2 ? 1 : -1;
|
||||
int err = dx+dy, e2; /* error value e_xy */
|
||||
|
||||
while(1){
|
||||
result = lcd_drawPixel(x1, y1, color);
|
||||
lcd_drawPixel(x1, y1, color);
|
||||
if (x1==x2 && y1==y2) break;
|
||||
e2 = 2*err;
|
||||
if (e2 > dy) { err += dy; x1 += sx; } /* e_xy+e_x > 0 */
|
||||
if (e2 < dx) { err += dx; y1 += sy; } /* e_xy+e_y < 0 */
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
uint8_t lcd_drawRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){
|
||||
uint8_t result;
|
||||
|
||||
result = lcd_drawLine(px1, py1, px2, py1, color);
|
||||
result = lcd_drawLine(px2, py1, px2, py2, color);
|
||||
result = lcd_drawLine(px2, py2, px1, py2, color);
|
||||
result = lcd_drawLine(px1, py2, px1, py1, color);
|
||||
|
||||
return result;
|
||||
void lcd_drawRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){
|
||||
if( px1 > DISPLAY_WIDTH-1 ||
|
||||
px2 > DISPLAY_WIDTH-1 ||
|
||||
py1 > DISPLAY_HEIGHT-1 ||
|
||||
py2 > DISPLAY_HEIGHT-1) return;
|
||||
lcd_drawLine(px1, py1, px2, py1, color);
|
||||
lcd_drawLine(px2, py1, px2, py2, color);
|
||||
lcd_drawLine(px2, py2, px1, py2, color);
|
||||
lcd_drawLine(px1, py2, px1, py1, color);
|
||||
}
|
||||
uint8_t lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){
|
||||
uint8_t result;
|
||||
|
||||
void lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t color){
|
||||
if( px1 > px2){
|
||||
uint8_t temp = px1;
|
||||
px1 = px2;
|
||||
@ -434,24 +503,24 @@ uint8_t lcd_fillRect(uint8_t px1, uint8_t py1, uint8_t px2, uint8_t py2, uint8_t
|
||||
py2 = temp;
|
||||
}
|
||||
for (uint8_t i=0; i<=(py2-py1); i++){
|
||||
result = lcd_drawLine(px1, py1+i, px2, py1+i, color);
|
||||
lcd_drawLine(px1, py1+i, px2, py1+i, color);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
uint8_t lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color){
|
||||
uint8_t result;
|
||||
|
||||
void lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color){
|
||||
if( ((center_x + radius) > DISPLAY_WIDTH-1) ||
|
||||
((center_y + radius) > DISPLAY_HEIGHT-1) ||
|
||||
center_x < radius ||
|
||||
center_y < radius) return;
|
||||
int16_t f = 1 - radius;
|
||||
int16_t ddF_x = 1;
|
||||
int16_t ddF_y = -2 * radius;
|
||||
int16_t x = 0;
|
||||
int16_t y = radius;
|
||||
|
||||
result = lcd_drawPixel(center_x , center_y+radius, color);
|
||||
result = lcd_drawPixel(center_x , center_y-radius, color);
|
||||
result = lcd_drawPixel(center_x+radius, center_y , color);
|
||||
result = lcd_drawPixel(center_x-radius, center_y , color);
|
||||
lcd_drawPixel(center_x , center_y+radius, color);
|
||||
lcd_drawPixel(center_x , center_y-radius, color);
|
||||
lcd_drawPixel(center_x+radius, center_y , color);
|
||||
lcd_drawPixel(center_x-radius, center_y , color);
|
||||
|
||||
while (x<y) {
|
||||
if (f >= 0) {
|
||||
@ -463,63 +532,44 @@ uint8_t lcd_drawCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8
|
||||
ddF_x += 2;
|
||||
f += ddF_x;
|
||||
|
||||
result = lcd_drawPixel(center_x + x, center_y + y, color);
|
||||
result = lcd_drawPixel(center_x - x, center_y + y, color);
|
||||
result = lcd_drawPixel(center_x + x, center_y - y, color);
|
||||
result = lcd_drawPixel(center_x - x, center_y - y, color);
|
||||
result = lcd_drawPixel(center_x + y, center_y + x, color);
|
||||
result = lcd_drawPixel(center_x - y, center_y + x, color);
|
||||
result = lcd_drawPixel(center_x + y, center_y - x, color);
|
||||
result = lcd_drawPixel(center_x - y, center_y - x, color);
|
||||
lcd_drawPixel(center_x + x, center_y + y, color);
|
||||
lcd_drawPixel(center_x - x, center_y + y, color);
|
||||
lcd_drawPixel(center_x + x, center_y - y, color);
|
||||
lcd_drawPixel(center_x - x, center_y - y, color);
|
||||
lcd_drawPixel(center_x + y, center_y + x, color);
|
||||
lcd_drawPixel(center_x - y, center_y + x, color);
|
||||
lcd_drawPixel(center_x + y, center_y - x, color);
|
||||
lcd_drawPixel(center_x - y, center_y - x, color);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
uint8_t lcd_fillCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color) {
|
||||
uint8_t result;
|
||||
void lcd_fillCircle(uint8_t center_x, uint8_t center_y, uint8_t radius, uint8_t color) {
|
||||
for(uint8_t i=0; i<= radius;i++){
|
||||
result = lcd_drawCircle(center_x, center_y, i, color);
|
||||
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;
|
||||
void lcd_drawBitmap(uint8_t x, uint8_t y, const uint8_t *picture, uint8_t width, uint8_t height, uint8_t color){
|
||||
uint8_t 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);
|
||||
lcd_drawPixel(x+i, y+j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
void lcd_display() {
|
||||
#if defined (SSD1306) || defined (SSD1309)
|
||||
#if defined SSD1306
|
||||
lcd_gotoxy(0,0);
|
||||
lcd_data(&displayBuffer[0][0], DISPLAY_WIDTH*DISPLAY_HEIGHT/8);
|
||||
lcd_data(displayBuffer, sizeof(displayBuffer));
|
||||
#elif defined SH1106
|
||||
for (uint8_t i = 0; i < DISPLAY_HEIGHT/8; i++){
|
||||
lcd_gotoxy(0,i);
|
||||
lcd_data(displayBuffer[i], sizeof(displayBuffer[i]));
|
||||
for (uint8_t i=0; i < DISPLAY_HEIGHT/8; i++) {
|
||||
lcd_gotoxy(0, 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));
|
||||
}
|
||||
#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
|
||||
|
120
lcd.h
120
lcd.h
@ -1,11 +1,11 @@
|
||||
/*
|
||||
* This file is part of lcd library for ssd1306/ssd1309/sh1106 oled-display.
|
||||
* This file is part of lcd library for ssd1306/sh1106 oled-display.
|
||||
*
|
||||
* lcd library for ssd1306/ssd1309/sh1106 oled-display is free software: you can redistribute it and/or modify
|
||||
* lcd library for ssd1306/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
|
||||
* the Free Software Foundation, either version 3 of the License, or any later version.
|
||||
*
|
||||
* lcd library for ssd1306/ssd1309/sh1106 oled-display is distributed in the hope that it will be useful,
|
||||
* lcd library for ssd1306/sh1106 oled-display is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
@ -13,14 +13,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Diese Datei ist Teil von lcd library for ssd1306/ssd1309/sh1106 oled-display.
|
||||
* Diese Datei ist Teil von lcd library for ssd1306/sh1106 oled-display.
|
||||
*
|
||||
* lcd library for ssd1306/ssd1309/sh1106 oled-display ist Freie Software: Sie können es unter den Bedingungen
|
||||
* lcd library for ssd1306/sh1106 oled-display ist Freie Software: Sie können es unter den Bedingungen
|
||||
* der GNU General Public License, wie von der Free Software Foundation,
|
||||
* Version 3 der Lizenz oder jeder späteren
|
||||
* veröffentlichten Version, weiterverbreiten und/oder modifizieren.
|
||||
*
|
||||
* lcd library for ssd1306/ssd1309/sh1106 oled-display wird in der Hoffnung, dass es nützlich sein wird, aber
|
||||
* lcd library for ssd1306/sh1106 oled-display wird in der Hoffnung, dass es nützlich sein wird, aber
|
||||
* OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
|
||||
* Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
|
||||
* Siehe die GNU General Public License für weitere Details.
|
||||
@ -33,7 +33,7 @@
|
||||
* Created by Michael Köhler on 22.12.16.
|
||||
* Copyright 2016 Skie-Systems. All rights reserved.
|
||||
*
|
||||
* lib for OLED-Display with ssd1306/ssd1309/sh1106-Controller
|
||||
* lib for OLED-Display with ssd1306/sh1106-Controller
|
||||
* first dev-version only for I2C-Connection
|
||||
* at ATMega328P like Arduino Uno
|
||||
*
|
||||
@ -44,8 +44,11 @@
|
||||
#ifndef LCD_H
|
||||
#define LCD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#ifndef YES
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
#else
|
||||
#error "Check #defines for YES and NO in other sources !"
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ * 100 + __GNUC_MINOR__) < 303
|
||||
@ -54,49 +57,18 @@ extern "C" {
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/* TODO: define bus */
|
||||
#define I2C // I2C or SPI
|
||||
/* TODO: define displaycontroller */
|
||||
#define SH1106 // or SSD1306, check datasheet of your display
|
||||
/* 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)
|
||||
|
||||
|
||||
#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
|
||||
/* TODO: define displaycontroller */
|
||||
#define SH1106 // or SSD1306, check datasheet of your display
|
||||
/* TODO: define displaymode */
|
||||
#define GRAPHICMODE // TEXTMODE for only text to display,
|
||||
// GRAPHICMODE for text and graphic
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef YES
|
||||
#define YES 1
|
||||
#endif
|
||||
|
||||
#define NORMALSIZE 1
|
||||
#define DOUBLESIZE 2
|
||||
#define LCD_I2C_ADR 0x7A
|
||||
|
||||
#define LCD_DISP_OFF 0xAE
|
||||
#define LCD_DISP_ON 0xAF
|
||||
@ -106,44 +78,32 @@ extern "C" {
|
||||
|
||||
#define DISPLAY_WIDTH 128
|
||||
#define DISPLAY_HEIGHT 64
|
||||
#define DISPLAYSIZE DISPLAY_WIDTH*DISPLAY_HEIGHT/8
|
||||
|
||||
void lcd_command(uint8_t cmd[], uint8_t size); // transmit command to display
|
||||
void lcd_data(uint8_t data[], uint16_t size); // transmit data to display
|
||||
void lcd_init(uint8_t dispAttr);
|
||||
void lcd_home(void); // set cursor to 0,0
|
||||
void lcd_invert(uint8_t invert); // invert display
|
||||
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_command(uint8_t cmd[], uint8_t size); // transmit command to display
|
||||
void lcd_data(uint8_t data[], uint16_t size); // transmit data to display
|
||||
void lcd_init(uint8_t dispAttr);
|
||||
void lcd_home(void); // set cursor to 0,0
|
||||
void lcd_invert(uint8_t invert); // invert display
|
||||
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,
|
||||
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
|
||||
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
|
||||
uint8_t lcd_drawPixel(uint8_t x, uint8_t y, uint8_t color);
|
||||
uint8_t lcd_drawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, uint8_t color);
|
||||
uint8_t lcd_drawRect(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 lcd_drawCircle(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 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
|
||||
}
|
||||
void 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);
|
||||
void 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);
|
||||
void 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);
|
||||
void 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
|
||||
#endif
|
||||
#endif /* LCD_H */
|
||||
|
BIN
oled.jpg
BIN
oled.jpg
Binäre Datei nicht angezeigt.
Vorher Breite: | Höhe: | Größe: 1.1 MiB |
43
readme
Normale Datei
43
readme
Normale Datei
@ -0,0 +1,43 @@
|
||||
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
130
readme.md
@ -1,130 +0,0 @@
|
||||
# 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