Jens Altenburg
/
Fachbuch_Initialisierungen
Initialisation Nucleo-F446 by Jens Altenburg
Diff: oled.cpp
- Revision:
- 0:9b6fbe273511
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oled.cpp Wed Mar 17 13:55:03 2021 +0000 @@ -0,0 +1,196 @@ +/** + * SSD1306xLED - Library for the SSD1306 based OLED/PLED 128x64 displays + * + * @author Neven Boyanov + * + * This is part of the Tinusaur/SSD1306xLED project. + * + * Copyright (c) 2018 Neven Boyanov, The Tinusaur Team. All Rights Reserved. + * Distributed as open source software under MIT License, see LICENSE.txt file. + * Retain in your source code the link http://tinusaur.org to the Tinusaur project. + * + * Source code available at: https://bitbucket.org/tinusaur/ssd1306xled + * + */ + +// ============================================================================ +// ACKNOWLEDGEMENTS: +// - Some code and ideas initially based on "IIC_wtihout_ACK" +// by http://www.14blog.com/archives/1358 (defunct) +// - Init sequence used info from Adafruit_SSD1306.cpp init code. +// ============================================================================ + +// ============================================================================ +// STATEMENT: +// - gründlich aufgeräumt +// 29.05.2020 by Jens Altenburg +// ============================================================================ + +#include "oled.h" +#include "font6_8.h" +#include "font8_16.h" + +// ---------------------------------------------------------------------------- + +void ssd1306_start_command(void); // Initiate transmission of command +void ssd1306_start_data(void); // Initiate transmission of data +void ssd1306_data_byte(byte); // Transmission 1 byte of data +void ssd1306_stop(void); // Finish transmission + +// ---------------------------------------------------------------------------- + +const byte ssd1306_init_sequence[] = { // Initialization Sequence + + 0xAE, // Set Display ON/OFF - AE=OFF, AF=ON + 0xD5, 0xF0, // Set display clock divide ratio/oscillator frequency, set divide ratio + 0xA8, 0x3F, // Set multiplex ratio (1 to 64) ... (height - 1) + 0xD3, 0x00, // Set display offset. 00 = no offset + 0x40 | 0x00, // Set start line address, at 0. + 0x8D, 0x14, // Charge Pump Setting, 14h = Enable Charge Pump + 0x20, 0x00, // Set Memory Addressing Mode - 00=Horizontal, 01=Vertical, 10=Page, 11=Invalid + 0xA0 | 0x01, // Set Segment Re-map + 0xC8, // Set COM Output Scan Direction + 0xDA, 0x12, // Set COM Pins Hardware Configuration - 128x32:0x02, 128x64:0x12 + 0x81, 0x3F, // Set contrast control register + 0xD9, 0x22, // Set pre-charge period (0x22 or 0xF1) + 0xDB, 0x20, // Set Vcomh Deselect Level - 0x00: 0.65 x VCC, 0x20: 0.77 x VCC (RESET), 0x30: 0.83 x VCC + 0xA4, // Entire Display ON (resume) - output RAM to display + 0xA6, // Set Normal/Inverse Display mode. A6=Normal; A7=Inverse + 0x2E, // Deactivate Scroll command + 0xAF, // Set Display ON/OFF - AE=OFF, AF=ON + // + 0x22, 0x00, 0x3f, // Set Page Address (start,end) + 0x21, 0x00, 0x7f, // Set Column Address (start,end) + // + }; + + +// ---------------------------------------------------------------------------- + +void i2csw_start(void); +void i2csw_stop(void); +void i2csw_byte(byte); + +// ---------------------------------------------------------------------------- + +void i2csw_start(void) { + vSDAOutput(); + /* SCL ist immer Output */ + vSDA_H(); /* SDA setzen */ + vSCL_H(); /* SCL setzen */ + vSDA_L(); /* SDA löschen */ + vSCL_L(); + } + +void i2csw_stop(void) { + vSDA_L(); /* SDA löschen */ + vSCL_L(); /* SCL löschen */ + vSDA_H(); /* SDA, SCL setzen */ + vSCL_H(); + vSDAInput(); /* SDA-Datenrichtung -> Input */ + } + +void i2csw_byte(byte bData) { + byte i; + for (i = 0; i < 8; i++) { + if ((bData << i) & 0x80) vSDA_H(); + else vSDA_L(); + vI2CShort(); /* set-up-Zeit */ + vSCL_H(); + vI2CDelay(); /* SCL-high-time */ + vSCL_L(); + vI2CShort(); /* set-up-Zeit */ + } + vSDA_L(); + vI2CShort(); /* set-up-Zeit */ + vSCL_H(); + vI2CDelay(); /* SCL-high-time */ + vSCL_L(); + vI2CShort(); /* set-up-Zeit */ + } + +// ============================================================================ + +void ssd1306_start_command(void) { + i2csw_start(); + i2csw_byte(0x78); // Slave address: R/W(SA0)=0 - write + i2csw_byte(0x00); // Control byte: D/C=0 - write command +} + +void ssd1306_start_data(void) { + i2csw_start(); + i2csw_byte(0x78); // Slave address, R/W(SA0)=0 - write + i2csw_byte(0x40); // Control byte: D/C=1 - write data +} + +void ssd1306_data_byte(byte b) { + i2csw_byte(b); +} + +void ssd1306_stop(void) { + i2csw_stop(); +} + +// ============================================================================ + +void vOledInit(void) { + byte i; + ssd1306_start_command(); // Initiate transmission of command + for (i = 0; i < sizeof (ssd1306_init_sequence); i++) { + ssd1306_data_byte(ssd1306_init_sequence[i]); // Send the command out + } + ssd1306_stop(); // Finish transmission +} + +void ssd1306_setpos(byte x, byte y) { + ssd1306_start_command(); + ssd1306_data_byte(0xb0 | (y & 0x07)); // Set page start address + ssd1306_data_byte(x & 0x0f); // Set the lower nibble of the column start address + ssd1306_data_byte(0x10 | (x >> 4)); // Set the higher nibble of the column start address + ssd1306_stop(); // Finish transmission +} + +void ssd1306_fill4(byte p1, byte p2, byte p3, byte p4) { + word i; + ssd1306_setpos(0, 0); + ssd1306_start_data(); // Initiate transmission of data + for (i = 0; i < 128 * 8 / 4; i++) { + ssd1306_data_byte(p1); + ssd1306_data_byte(p2); + ssd1306_data_byte(p3); + ssd1306_data_byte(p4); + } + ssd1306_stop(); // Finish transmission +} + +// ---------------------------------------------------------------------------- + +void ssd1306tx_char(byte ch) { + byte i; + word j = (ch-32)*6; + ssd1306_start_data(); + for (i = 0; i < 6; i++) { + ssd1306_data_byte(ssd1306xled_font6x8data[j + i]); + } + ssd1306_stop(); +} + +void ssd1306tx_large(byte ch, byte x, byte y) { + byte i, yy; + word j = (ch-32)*16; + yy = y >> 1; + ssd1306_setpos(x, (yy)); + ssd1306_start_data(); + for (i = 0; i < 8; i++) { + ssd1306_data_byte(ssd1306xled_font8x16data[j + i]); + } + ssd1306_stop(); + ssd1306_setpos(x, (yy+1)); + ssd1306_start_data(); + for (i = 8; i < 16; i++) { + ssd1306_data_byte(ssd1306xled_font8x16data[j + i]); + } + ssd1306_stop(); + } + +// ============================================================================ \ No newline at end of file