Book Appointment Now

SSD1306 Modülün PIC ile kullanılması
1) OLED teknolojisi:
Organic Light Emitting Diode kelimelerini baş harflerinden oluşan OLED ışık veren organik diyotlara verilen addır. Ekran teknolojisinde her piksel bir oled’dir. Her piksel bağımsız olarak kontrol edilebilir ve arka aydınlatma gerekmez. Pikseller tamamen kapanabildiği için gerçek ve derin siyahlar elde edilir. Oledlerin akımı ayarlanarak geniş bir aralıkta kontrast sağlanabilir. Arka aydınlatma olmadığı için, daha ince ekranlar yapılabilir.
2) SSD1306 modülü
SSD1306 denetleyicisi ile OLED ekranın birlikte paketlendiği modüldür. Piyasada değişik iletişim usulleri ile 128×64 ve 128×32 çözünürlükte çeşitleri bulunmaktadır. Genellikle 0,96 inç ekran boyutuna sahiptir. Bu yazıda 128×64 çözünürlükte olan anlatılacaktır.
3) I2C iletişimi
I2C iletişimi SDA veri hattı ve SCL saat hattı olmak üzere, 2 tel üzerinden yapılır. Sistemde Ana Aygıtlar (Master) ve Bağlı Aygıtlar (Slave) bulunur. İletişimi Ana Aygıtlardan birisi başlatır. Aynı anda birden çok ana aygıt iletişim başlatmak isterse, Ana Aygıtlardan birisi belli usullerle seçilir ve seçilen Ana Aygıt İletişime devam eder, diğer ana aygıt iletişimin bitmesini bekler.
a) Yukarı çekme (Pull-up) dirençleri
SDA ve SCL hatlarında yukarı çekme dirençleri bulunmalıdır. Uygulamada 4,7 kΩ sık kullanılan bir değerdir. Ancak kullanılacak direnç değeri, besleme gerilimine, hat kapasitesine, kablo uzunluğuna ve haberleşme hızına göre değişebilir. Birçok hazır SSD1306 OLED modülünde SDA ve SCL hatları için gerekli yukarı çekme dirençleri modül üzerinde zaten bulunmaktadır.
b) I2C adresi
I2C standardında 7 bit adres kullanılır. Ancak iletişim 8 bit üzerinden yapılır. 7 bit adres 8 bit iletişim baytına çevrilirken, en düşük bit olarak yazma/okuma biti eklenir. Böylece iletişimin tamamı 8 bit üzerinden yapılır. Bu bit yazma için 0, okuma için 1 yapılır. Kullanılan PIC fonksiyonlarına bağlı olarak bu işlemin adres gönderilmeden yapılması gerekebilir. Bu durumda adres yüklenmeden 1 bit sola kaydırılır, boşalan 0 bitine yazma/okuma biti yazılır. (adres<1 | W/R)
7 bit adres: 0111100 = 60
Sola kaydırılmış adres: 01111000 = 120
Yazma: 01111000 = 120
Okuma: 01111001 = 1214) SSD1306 denetleyici
a) Çözünürlük
Bu denetleyici 128×64 piksel OLED ekranları denetlemek için tasarlanmıştır. Her piksel için bir bit belleğe sahiptir. Düşeydeki 64 piksel için 64 COM ve yataydaki 128 piksel için 128 SEG uçları vardır. Bu uçlar sırayla taranarak ilgili pikselin ışık vermesi/vermemesi sağlanır.

b) Monokrom
Bu denetleyici tek renkli OLED ekranlar içindir.
c) Bellek
Denetleyicinin 128×64=8.192 bit belleği vardır. Her belleğe 1 bit karşılık gelmektedir. Bu nedenle tek renkli ekranları denetleyebilir.
128 × 64 = 8192 piksel
8192 bit = 1024 bayt
d) Sayfa yapısı
Ekranın düşeyde bulunan 64 pikseli, 8’er pikselden oluşan 8 sayfaya ayrılmıştır. Her sayfada 128 sütun bulunur. Bir sütundaki 8 piksel, bir veri baytının 8 biti ile kontrol edilir.

e) Adreslemede Sayfa/Sütun mantığı
Ekran 8 sayfa ve 128 sütundan oluşmaktadır. Adresleme sayfa ve sütun numaraları ile yapılmaktadır. Sayfa içerisindeki 8 piksel adreslemesi ise gönderilen bayt ile yapılmaktadır. Baytın 0 numaralı biti en yukarı gelecek şekildedir.

f) İletişim
İletişim bayt ile yapılmaktadır. 3 değişik yolla iletişim sağlanabilmektedir. Bu yolların seçimi çip üzerindeki gerekli pinlerin mantıksal 1 ve 0 ayarlanması ile sağlanmaktadır. Modülün montajı sırasında bu bağlantılar yapılır ve sonradan değiştirilemez.
i) I2C
I2C bilindiği gibi 2 tel üzerinden iletişim sağlar. Hız standart olarak 100 kHz dir. Ayrıca 400 kHz ve 1 MHz hızlar da vardır. Bu projede 100 kHz hız kullanılacaktır. Bazı kaynaklarda bu hızın düşük kaldığı belirtilse de yapılan denemelerde dikkati çeken yavaşlık gözlenmemiştir.
ii) SPI
SPI iletişimi veri ve saat hatlarına ek olarak aygıt seçme ve bazı kontrol hatları kullanılabilir. SPI iletişimin hızı I2C’ye göre daha fazla olsa da, her bağlı eleman için, I2C’ye göre fazladan bağlantı gerektirebilir. Çok bağlı elemanın bulunduğu projede bu sıkıntı yaratabilir.
iii) Paralel
8 bit iletişim için 8 bağlantı gerekir. Uygulamada bağlantı için 8 uç bulunması kolay değildir. Hazır OLED modüllerinde I2C ve SPI arabirimleri daha yaygın olarak kullanılmaktadır.
g) Komut ve veri iletişimi
SSD1306 ile iletimde komut veya veri gönderilmesi söz konusudur.
i) Komut gönderme
Komut gönderimi adresten sonra 0x00 baytı gönderilerek sağlanır. Arkasından komut bayt olarak gönderilir.
// Komut gönderme
#define SSD1306_CMD 0x00
void SSD1306_Command(uint8_t cmd)
{
I2C_Start();
I2C_Write((SSD1306_ADDR << 1) | 0); // Write
I2C_Write(SSD1306_CMD);
I2C_Write(cmd);
I2C_Stop();
}Veri gönderme
Veri gönderimi adresten sonra 0x40 baytı gönderilerek sağlanır. Arkasından veri bayt olarak gönderilir.
// Tek Byte Veri Gönderme
#define SSD1306_DATA 0x40
void SSD1306_Data(uint8_t data)
{
I2C_Start();
I2C_Write((SSD1306_ADDR << 1));
I2C_Write(SSD1306_DATA);
I2C_Write(data);
I2C_Stop();
}I2C protokolü peş peşe birden çok veri/komut gönderilmesini sağlar. Ancak bu projede bir seferde tek komut/veri gönderilecektir.
h) Adresleme modları
Üç çeşit adresleme modu vardır. Bu modların hepsinde adresleme sayfa ve sütun numaralarının belirlenmesiyle yapılır. Aradaki fark her bayttan sonra hangi sayfa veya sütuna geçileceğidir.
i) Sayfa adresleme modu
Modül seçilen sayfada, her bayt veriden sonra sütun numarasını 1 artırır. Sayfadaki sütunların sonuna gelince aynı sayfanın ilk sütununa geçilir.
ii) Yatay adresleme modu
Bu modun sayfa adresleme modundan farkı, sona gelinince bir sonraki sayfaya geçilmesidir.
iii) Düşey adresleme modu
Modül her bayttan sonra sayfa numarasını 1 artırır. Son sayfaya gelinince ilk sayfanın bir sonraki sütununa geçilir.
i) Karakter yazdırma
i) Font yapısı
SSD1306 modülü herhangi bir karakter seti ya da font içermez. Bu nedenle SSD1306’ya “A harfini yaz” şeklinde bir komut gönderilmez. A harfinin piksel bilgileri mikrodenetleyicide bulunan font tablosundan alınır ve SSD1306’ya görüntü verisi olarak gönderilir. Bunun için 5×7 veya 6×8 gibi font yapısı seçilebileceği gibi daha büyük 10×14 gibi font yapısı seçilebilir. Ancak daha büyük font daha çok mikrodenetleyici belleği gerektirecektir. Bu projede 5×7 font kullanılacak, ancak 2 katı büyük font hesaplanarak kullanılacaktır.
ii) ASCII karakter tablosu
Birçok gömülü sistem uygulamasında karakterler ASCII tabanlı font tabloları kullanılarak gösterilir. Bu set bir bayt ile İngiliz alfabesindeki karakterleri belirler. Ancak Türkçe karakterler yoktur. Türkçe karakterlerin kullanılması ayrı bir yazı konusudur.
iii) Karakterin SSD1306’ya aktarılması
5×7 fontta her karakter için 5 bayt belirlenmelidir. Bu baytlar sayfalara sıfırıncı biti en yukarı gelecek şekilde yerleştirilir. Her baytın yedinci biti 0 yapılarak satırlar arasında boşluk bırakılması sağlanır ve satırların birbirine karışması engellenir. 5 bayt peş peşe gönderilir. Harfler arasında boşluk bırakmak için, her harften sonra bir kez 0 bayt gönderilir.

iv) Sayısal değer yazdırma
Sayı yazdırmada, sayıların metne çevrildikten sonra yazdırılmaları gereklidir. Bunun için C/C++ dilinde snprintf kullanılabilir. Kullanılması aşağıdaki örnekteki gibidir. Ancak bu fonksiyonun kullanılması bellek kullanımını artırabileceği göz önünde bulundurulmalıdır.
char dizi[16];
float volt = 4.12;
snprintf(dizi, 16, "Volt: %.2f", volt);
SSD1306_WriteString(dizi,5, 8, 2);5) PIC18F45K22 denetleyicisi
Bu projede PIC18F45K22 kullanılacaktır. 40 ucu, 32 kbayt program belleği,1536 bayt veri belleği ve İki adet MSSP modülü sayesinde I2C ve SPI haberleşmesi için uygun donanım birimlerine sahip olması, hem iletişim ve hem de karakter setinin depolanmasına uygundur.
a) I2C fonksiyonları
Bu PIC için daha önce yayınlanan projede I2C fonksiyonu MCC ( MPLAB Code Configurator ) ile hazırlanan kullanılmış idi. Bu projede I2C fonksiyonları yeniden hazırlanacaktır.
b) Örnek SSD1306 fonksiyonları
Kullanılacak bazı fonksiyonların prototipleri aşağıda verilmiştir.
// Komut gönderme
void SSD1306_Command(uint8_t cmd)
// Tek Byte Veri Gönderme
void SSD1306_Data(uint8_t data)
// Çoklu Byte Yazma
void SSD1306_DataBuffer(uint8_t *buffer, uint16_t length)
// İmleci verilen Sayfa ve Kolon adresine yerleştirme
void SSD1306_SetCursor(uint8_t page,uint8_t column)
// Ekranı Temizleme
void SSD1306_Clear(void)
// Modülü Başlatma (En yaygın kullanılan ayarlar ile):
void SSD1306_Init(void)c) Program
Programın tamamına GitHub üzerinden ulaşmak olanaklıdır. GitHub adresi: https://github.com/ckerdem/SSD1306_PIC Program 5 dosyadan oluşmaktadır. Aşağıda her dosya ayrı ayrı bulunmaktadır.
i) Ana dosya: oled_ana.c
/*
* File: oled_ana.c
* Author: Celal Erdem
*
* PIC18F45K22 içindir.
* Created on June 21, 2026, 3:16 PM
*/
// 'C' source line config statements
//CONFIG1H
#pragma config FOSC = INTIO67 // Oscillator Selection bits->Internal oscillator block
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit->Fail-Safe Clock Monitor disabled
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit->Oscillator Switchover mode disabled
#pragma config PLLCFG = ON // 4X PLL Enable->Oscillator multiplied by 4
#pragma config PRICLKEN = ON // Primary clock enable bit->Primary clock is always enabled
//CONFIG2L
#pragma config PWRTEN = OFF // Power-up Timer Enable bit->Power up timer disabled
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits->Brown-out Reset enabled in hardware only (SBOREN is disabled)
#pragma config BORV = 190 // Brown Out Reset Voltage bits->VBOR set to 1.90 V nominal
//CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits->Watch dog timer is always disabled. SWDTEN has no effect.
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits->1:32768
//CONFIG3H
#pragma config HFOFST = ON // HFINTOSC Fast Start-up->HFINTOSC output and ready status are not delayed by the oscillator stable status
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit->MCLR pin enabled, RE3 input pin disabled
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit->CCP2 input/output is multiplexed with RC1
#pragma config PBADEN = ON // PORTB A/D Enable bit->PORTB<5:0> pins are configured as analog input channels on Reset
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit->P3A/CCP3 input/output is multiplexed with RB5
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit->T3CKI is on RC0
#pragma config P2BMX = PORTD2 // ECCP2 B output mux bit->P2B is on RD2
//CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit->Stack full/underflow will cause Reset
#pragma config LVP = ON // Single-Supply ICSP Enable bit->Single-Supply ICSP enabled if MCLRE is also 1
#pragma config XINST = OFF // Extended Instruction Set Enable bit->Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
//CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0->Block 0 (000800-001FFFh) not code-protected
#pragma config CP1 = OFF // Code Protection Block 1->Block 1 (002000-003FFFh) not code-protected
#pragma config CP2 = OFF // Code Protection Block 2->Block 2 (004000-005FFFh) not code-protected
#pragma config CP3 = OFF // Code Protection Block 3->Block 3 (006000-007FFFh) not code-protected
//CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit->Boot block (000000-0007FFh) not code-protected
#pragma config CPD = OFF // Data EEPROM Code Protection bit->Data EEPROM not code-protected
//CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0->Block 0 (000800-001FFFh) not write-protected
#pragma config WRT1 = OFF // Write Protection Block 1->Block 1 (002000-003FFFh) not write-protected
#pragma config WRT2 = OFF // Write Protection Block 2->Block 2 (004000-005FFFh) not write-protected
#pragma config WRT3 = OFF // Write Protection Block 3->Block 3 (006000-007FFFh) not write-protected
//CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit->Configuration registers (300000-3000FFh) not write-protected
#pragma config WRTB = OFF // Boot Block Write Protection bit->Boot Block (000000-0007FFh) not write-protected
#pragma config WRTD = OFF // Data EEPROM Write Protection bit->Data EEPROM not write-protected
//CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0->Block 0 (000800-001FFFh) not protected from table reads executed in other blocks
#pragma config EBTR1 = OFF // Table Read Protection Block 1->Block 1 (002000-003FFFh) not protected from table reads executed in other blocks
#pragma config EBTR2 = OFF // Table Read Protection Block 2->Block 2 (004000-005FFFh) not protected from table reads executed in other blocks
#pragma config EBTR3 = OFF // Table Read Protection Block 3->Block 3 (006000-007FFFh) not protected from table reads executed in other blocks
//CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit->OFF
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "i2c.h"
#include "oled.h"
#include "font.h"
/*
*
*/
char dizi[16];
int main() {
OSCCON = 0x70; // 16 MHz
I2C_Init();
SSD1306_Init();
SSD1306_Clear();
while(1){
SSD1306_Clear();
float volt = 4.12;
snprintf(dizi, 16, "Volt: %.2f", volt);
SSD1306_WriteString(dizi,5, 8, 2);
__delay_ms(1000);
SSD1306_WriteString("Merhaba", 2, 10, 2);
SSD1306_Command(0xA5); // Bütün pikseller açık
__delay_ms(5000);
SSD1306_Command(0xA4); // Normal görüntü
__delay_ms(5000);
SSD1306_Command(0xA7); // Pikseller ters
__delay_ms(5000);
SSD1306_Command(0xA6); // Pikseller düz
__delay_ms(5000);
SSD1306_Command(0xAE); // Panel kapalı
__delay_ms(5000);
SSD1306_Command(0xAF); // Panel açık
__delay_ms(5000);
SSD1306_Command(0xA1); // Panel yatayda simetrik gösterir
__delay_ms(5000);
SSD1306_Command(0xA0); // Panel yatayda simetriği düzeltir
__delay_ms(5000);
SSD1306_Command(0xC8); // Panel düşeyde simetrik gösterir
__delay_ms(5000);
SSD1306_Command(0xC0); // Panel düşeyde simetriği düzeltir
__delay_ms(5000);
SSD1306_Command(0x26); // Sağa kaydırma ayarları
SSD1306_Command(0x0);
SSD1306_Command(0x1); // Başlangıç sayfası: 1
SSD1306_Command(0x1); // Bekleme: 64 kare
SSD1306_Command(0x6); // Son sayfa:6
SSD1306_Command(0x0);
SSD1306_Command(0xFF);
SSD1306_Command(0x2F); // Kaydırmayı başlat
__delay_ms(5000);
SSD1306_Command(0x2E); // Kaydırmayı durdur
SSD1306_Command(0x27); // Sola kaydırma ayarları
SSD1306_Command(0x0);
SSD1306_Command(0x1); // Başlangıç sayfası: 1
SSD1306_Command(0x1); // Bekleme: 64 kare
SSD1306_Command(0x6); // Son sayfa:6
SSD1306_Command(0x0);
SSD1306_Command(0xFF);
SSD1306_Command(0x2F); // Kaydırmayı başlat
__delay_ms(5000);
SSD1306_Command(0x2E); // Kaydırmayı durdur
SSD1306_Command(0xA3); // Düşey kaydırma ayarları
SSD1306_Command(0x00); // Yukarıdaki sabit satır sayısı
SSD1306_Command(0x40); // Kaydırmaya girecek satır sayısı
SSD1306_Command(0x2F); // Kaydırmayı başlat
SSD1306_Command(0x29); //
SSD1306_Command(0x00);
SSD1306_Command(0x00); // Kaydırmaya girecek ilk sayfa adresi
SSD1306_Command(0x02); // Kaydırma için beklenecek frame sayısı
SSD1306_Command(0x07); // Kaydırmaya girecek son sayfa adresi
SSD1306_Command(0x02); // Düşey kaydırmada bir kerede kaydırılacak satır sayısı
SSD1306_Command(0x2F); // Kaydırmayı başlat
__delay_ms(5000);
SSD1306_Command(0x2E); // Kaydırmayı durdur
__delay_ms(5000);
}
}ii) I2C fonksiyonları c dosyası: i2c.c
#include "i2c.h"
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <xc.h>
/*=====================================================
* I2C fonksiyonları
======================================================= */
static void I2C_Wait(void)
{
while ((SSP1CON2 & 0x1F) || (SSP1STAT & 0x04));
}
void I2C_Init(void)
{
TRISC3 = 1; // SCL
TRISC4 = 1; // SDA
ANSELC = 0x00;
SSP1CON1 = 0x28; // I2C master
SSP1CON2 = 0x00;
SSP1ADD = 39; // 100kHz @ 8MHz
SSP1STAT = 0x00;
}
void I2C_Start(void)
{
I2C_Wait();
SSP1CON2bits.SEN = 1;
}
void I2C_Stop(void)
{
I2C_Wait();
SSP1CON2bits.PEN = 1;
}
void I2C_Write(unsigned char data)
{
I2C_Wait();
SSP1BUF = data;
}iii) I2C fonksiyonları h dosyası: i2c.h
/*
* File: i2c.h
* Author: Celal
*
* Created on August 7, 2026, 3:13 PM
*/
#ifndef I2C_H
#define I2C_H
#include <xc.h>
#define _XTAL_FREQ 16000000
// LCD I2C adresi 0x27 ancak 0x27<1 | 0 -> 0x4E (Yani yazma için 0 eklenince))
#define LCD_ADDR 0x4E
static void I2C_Wait(void);
void I2C_Init(void);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_Write(unsigned char data);
#endif /* I2C_H */
iv) SSD1306 modül iletişim fonksiyonları c dosyası: oled.c
/*=============================================================================
* SSD1306 fonksiyonları bu dosyada
* ==========================================================================*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <xc.h>
#include "i2c.h"
#include "oled.h"
#include "font.h"
// SSD1306 Tanımları
#define SSD1306_ADDR 0x3C // 7 bit adres
#define SSD1306_CMD 0x00
#define SSD1306_DATA 0x40
#define SSD1306_WIDTH 128
#define SSD1306_HEIGHT 64
// Komut gönderme
void SSD1306_Command(uint8_t cmd)
{
I2C_Start();
I2C_Write((SSD1306_ADDR << 1) | 0); // Write
I2C_Write(SSD1306_CMD);
I2C_Write(cmd);
I2C_Stop();
}
// Tek Byte Veri Gönderme
void SSD1306_Data(uint8_t data)
{
I2C_Start();
I2C_Write((SSD1306_ADDR << 1));
I2C_Write(SSD1306_DATA);
I2C_Write(data);
I2C_Stop();
}
// Çoklu Byte Yazma
void SSD1306_DataBuffer(uint8_t *buffer, uint16_t length)
{
uint16_t i;
I2C_Start();
I2C_Write((SSD1306_ADDR<<1));
I2C_Write(SSD1306_DATA);
for(i=0;i<length;i++)
{
I2C_Write(buffer[i]);
}
I2C_Stop();
}
// İmleç (Sayfa ve Kolon) SSD1306'da satır yerine Page kullanılır.
void SSD1306_SetCursor(uint8_t page,uint8_t column)
{
SSD1306_Command(0xB0 | page);
SSD1306_Command(column & 0x0F);
SSD1306_Command(0x10 | (column>>4));
}
// Ekranı Temizleme
void SSD1306_Clear(void)
{
uint8_t page;
uint8_t i;
for(page=0;page<8;page++)
{
SSD1306_SetCursor(page,0);
I2C_Start();
I2C_Write(SSD1306_ADDR<<1);
I2C_Write(SSD1306_DATA);
for(i=0;i<128;i++)
I2C_Write(0x00);
I2C_Stop();
}
}
// Ekranı Açma/Kapatma
void SSD1306_DisplayOn(void)
{
SSD1306_Command(0xAF);
}
void SSD1306_DisplayOff(void)
{
SSD1306_Command(0xAE);
}
// Tüm Piksel Açık
void SSD1306_AllPixelsOn(void)
{
SSD1306_Command(0xA5);
}
// Normal moda dönüş:
void SSD1306_NormalDisplay(void)
{
SSD1306_Command(0xA4);
}
// Ters Göröntü
void SSD1306_InvertOn(void)
{
SSD1306_Command(0xA7);
}
void SSD1306_InvertOff(void)
{
SSD1306_Command(0xA6);
}
// Başlangıç (Initialization) En yaygın kullanılan ayarlar:
void SSD1306_Init(void)
{
SSD1306_Command(0xAE);
SSD1306_Command(0x20);
SSD1306_Command(0x00);
SSD1306_Command(0xB0);
SSD1306_Command(0xC8);
SSD1306_Command(0x00);
SSD1306_Command(0x10);
SSD1306_Command(0x40);
SSD1306_Command(0x81);
SSD1306_Command(0x7F);
SSD1306_Command(0xA1);
SSD1306_Command(0xA6);
SSD1306_Command(0xA8);
SSD1306_Command(0x3F);
SSD1306_Command(0xA4);
SSD1306_Command(0xD3);
SSD1306_Command(0x00);
SSD1306_Command(0xD5);
SSD1306_Command(0x80);
SSD1306_Command(0xD9);
SSD1306_Command(0xF1);
SSD1306_Command(0xDA);
SSD1306_Command(0x12);
SSD1306_Command(0xDB);
SSD1306_Command(0x40);
SSD1306_Command(0x8D);
SSD1306_Command(0x14);
SSD1306_Command(0xAF);
}
void SSD1306_WriteString(const char* str, uint8_t page, uint8_t column, uint8_t size) {
if (size == 1) {
SSD1306_SetCursor(page, column);
while (*str) {
char c = *str++;
if (c < 32 || c > 126) c = ' ';
uint16_t idx = (c - 32);
for (uint8_t i = 0; i < 5; i++) {
SSD1306_Data(ASCII_5x7[idx][i]);
}
SSD1306_Data(0x00); // Boşluk
}
}
else if (size == 2) {
// --- 2 SATIR BÜYÜKLÜK İÇİN MATEMATİKSEL ÖLÇEKLENDİRME ---
// Bölüm A: Üst Satırı Bas (Yazının üst 8 piksellik parçası)
SSD1306_SetCursor(page, column);
const char* temp_str = str;
while (*temp_str) {
char c = *temp_str++;
if (c < 32 || c > 126) c = ' ';
uint16_t idx = (c - 32);
for (uint8_t i = 0; i < 5; i++) {
uint8_t orig = ASCII_5x7[idx][i];
uint8_t upper = 0;
// Alt 4 biti dikeyde 2 kat büyüterek 8 bite yayıyoruz
if (orig & 0x01) upper |= 0x03;
if (orig & 0x02) upper |= 0x0C;
if (orig & 0x04) upper |= 0x30;
if (orig & 0x08) upper |= 0xC0;
SSD1306_Data(upper); // Yatay genişlik için 2 kez basılır
SSD1306_Data(upper);
}
SSD1306_Data(0x00); SSD1306_Data(0x00);
}
// Bölüm B: Alt Satırı Bas (Yazının alt 8 piksellik parçası - 1 sayfa aşağıya)
SSD1306_SetCursor(page + 1, column);
temp_str = str;
while (*temp_str) {
char c = *temp_str++;
if (c < 32 || c > 126) c = ' ';
uint16_t idx = (c - 32);
for (uint8_t i = 0; i < 5; i++) {
uint8_t orig = ASCII_5x7[idx][i];
uint8_t lower = 0;
// Üst 4 biti dikeyde 2 kat büyüterek 8 bite yayıyoruz
if (orig & 0x10) lower |= 0x03;
if (orig & 0x20) lower |= 0x0C;
if (orig & 0x40) lower |= 0x30;
if (orig & 0x80) lower |= 0xC0;
SSD1306_Data(lower);
SSD1306_Data(lower);
}
SSD1306_Data(0x00); SSD1306_Data(0x00);
}
}
}
v) SSD1306 modül iletişim fonksiyonları h dosyası: oled.h
/*
* File: oled.h
* Author: Celal
*
* Created on August 7, 2026, 3:17 PM
*/
#ifndef OLED_H
#define OLED_H
void SSD1306_Command(uint8_t cmd);
void SSD1306_Data(uint8_t data);
void SSD1306_DataBuffer(uint8_t *buffer, uint16_t length);
void SSD1306_SetCursor(uint8_t page,uint8_t column);
void SSD1306_Clear(void);
void SSD1306_DisplayOn(void);
void SSD1306_DisplayOff(void);
void SSD1306_AllPixelsOn(void);
void SSD1306_NormalDisplay(void);
void SSD1306_InvertOn(void);
void SSD1306_InvertOff(void);
void SSD1306_Init(void);
void SSD1306_WriteString(const char* str, uint8_t page, uint8_t column, uint8_t size);
#endif /* OLED_H */