Arduino'nun standart digitalWrite() fonksiyonu pin durumunu değiştirmek için arka planda yaklaşık 40-50 işlemci çevrimi (cycle) harcar. Ekranı ters çevirip doğrudan D0-D7 pinlerine oturtmamızın bize sağladığı en büyük avantaj, bu pinlerin tamamının ATmega328P işlemcisinin donanımsal PORTD yazmacına (register) bağlı olmasıdır. İşlemciye doğrudan port seviyesinde emir vererek, ekran yenileme ve veri transfer hızını 10 kattan fazla artırabilir ve işlemci yükünü neredeyse sıfıra indirebiliriz.
Aşağıdaki kod, hx1230_byteYaz fonksiyonu içindeki tüm yavaş pin komutlarını tek satırlık bit maskeleme işlemlerine dönüştürür. Zamanlama (Clock) sinyali işlemci hız sınırında üretilir:
// HX1230 PORTD Donanımsal Bit Karşılıkları (D0-D7 Arası)
// Pinlerin PORTD üzerindeki bit pozisyonları:
// D0=Bit0 (RESET), D1=Bit1 (CE), D2=Bit2 (NC), D3=Bit3 (DIN)
// D4=Bit4 (CLK), D5=Bit5 (VCC), D6=Bit6 (BL), D7=Bit7 (GND)
#define BIT_RESET 0 // PORTD0
#define BIT_CE 1 // PORTD1
#define BIT_DIN 3 // PORTD3
#define BIT_CLK 4 // PORTD4
// Süper Hızlı 9-Bit Port Manipülasyonu İletişim Fonksiyonu
void hx1230_byteYaz(uint8_t veri, uint8_t is_veri) {
// 1. Çip Seçimini Aktif Et (CE -> LOW)
PORTD &= ~(1 << BIT_CE);
// 2. İlk Bit: D/C (0: Komut, 1: Veri)
PORTD &= ~(1 << BIT_CLK); // CLK -> LOW
if (is_veri) {
PORTD |= (1 << BIT_DIN); // DIN -> HIGH
} else {
PORTD &= ~(1 << BIT_DIN); // DIN -> LOW
}
PORTD |= (1 << BIT_CLK); // CLK -> HIGH (Veri kilitlendi)
// 3. Geri kalan 8 bitlik veri bloğunu döngüyle uçuruyoruz
for (int i = 7; i >= 0; i--) {
PORTD &= ~(1 << BIT_CLK); // CLK -> LOW
if ((veri >> i) & 0x01) {
PORTD |= (1 << BIT_DIN); // DIN -> HIGH
} else {
PORTD &= ~(1 << BIT_DIN); // DIN -> LOW
}
PORTD |= (1 << BIT_CLK); // CLK -> HIGH (Veri kilitlendi)
}
// 4. İşlem Bitti, Çip Seçimini Kapat (CE -> HIGH)
PORTD |= (1 << BIT_CE);
}
// Komut ve Veri sarmalayıcıları aynı kalıyor
void hx1230_komutYaz(uint8_t komut) { hx1230_byteYaz(komut, LOW); }
void hx1230_veriYaz(uint8_t veri) { hx1230_byteYaz(veri, HIGH); }
// Orijinal Kararlı Başlatma Protokolü
void hx1230_init() {
// Donanımsal Reset (Port Seviyesinde)
PORTD &= ~(1 << BIT_RESET); // RESET -> LOW
delay(5);
PORTD |= (1 << BIT_RESET); // RESET -> HIGH
delay(5);
hx1230_komutYaz(0xE2); // Software Reset
delay(2);
hx1230_komutYaz(0x2F); // Power Control ON
hx1230_komutYaz(0xA4); // Normal RAM Modu
hx1230_komutYaz(0xA6); // Normal Renk Modu
hx1230_komutYaz(0xA0); // Sütun yönü
hx1230_komutYaz(0xC0); // Satır yönü
hx1230_komutYaz(0x40);
hx1230_komutYaz(0x8B); // Orijinal Kontrast Sabiti (0x8B)
hx1230_komutYaz(0xAF); // Display ON
delay(10);
}
// 5x7 Standart ASCII Font Tablosu (Harfler, Rakamlar ve Temel Semboller)
const uint8_t PROGMEM font_haritasi[][5] = {
{0x00, 0x00, 0x00, 0x00, 0x00}, // Boşluk
{0x00, 0x00, 0x5f, 0x00, 0x00}, // !
{0x00, 0x07, 0x00, 0x07, 0x00}, // "
{0x14, 0x7f, 0x14, 0x7f, 0x14}, // #
{0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $
{0x23, 0x13, 0x08, 0x64, 0x62}, // %
{0x36, 0x49, 0x55, 0x22, 0x50}, // &
{0x00, 0x05, 0x03, 0x00, 0x00}, // '
{0x00, 0x1c, 0x22, 0x41, 0x00}, // (
{0x00, 0x41, 0x22, 0x1c, 0x00}, // )
{0x14, 0x08, 0x3e, 0x08, 0x14}, // *
{0x08, 0x08, 0x3e, 0x08, 0x08}, // +
{0x00, 0x50, 0x30, 0x00, 0x00}, // ,
{0x08, 0x08, 0x08, 0x08, 0x08}, // -
{0x00, 0x60, 0x60, 0x00, 0x00}, // .
{0x20, 0x10, 0x08, 0x04, 0x02}, // /
{0x3e, 0x51, 0x49, 0x45, 0x3e}, // 0
{0x00, 0x42, 0x7f, 0x40, 0x00}, // 1
{0x42, 0x61, 0x51, 0x49, 0x46}, // 2
{0x21, 0x41, 0x45, 0x4b, 0x31}, // 3
{0x18, 0x14, 0x12, 0x7f, 0x10}, // 4
{0x27, 0x45, 0x45, 0x45, 0x39}, // 5
{0x3c, 0x4a, 0x49, 0x49, 0x30}, // 6
{0x01, 0x71, 0x09, 0x05, 0x03}, // 7
{0x36, 0x49, 0x49, 0x49, 0x36}, // 8
{0x06, 0x49, 0x49, 0x29, 0x1e}, // 9
{0x00, 0x36, 0x36, 0x00, 0x00}, // :
{0x00, 0x56, 0x36, 0x00, 0x00}, // ;
{0x08, 0x14, 0x22, 0x41, 0x00}, // <
{0x14, 0x14, 0x14, 0x14, 0x14}, // =
{0x00, 0x41, 0x22, 0x14, 0x08}, // >
{0x02, 0x01, 0x51, 0x09, 0x06}, // ?
{0x32, 0x49, 0x79, 0x41, 0x3e}, // @
{0x7e, 0x11, 0x11, 0x11, 0x7e}, // A
{0x7f, 0x49, 0x49, 0x49, 0x36}, // B
{0x3e, 0x41, 0x41, 0x41, 0x22}, // C
{0x7f, 0x41, 0x41, 0x22, 0x1c}, // D
{0x7f, 0x49, 0x49, 0x49, 0x41}, // E
{0x7f, 0x09, 0x09, 0x09, 0x01}, // F
{0x3e, 0x41, 0x49, 0x49, 0x7a}, // G
{0x7f, 0x08, 0x08, 0x08, 0x7f}, // H
{0x00, 0x41, 0x7f, 0x41, 0x00}, // I
{0x20, 0x40, 0x41, 0x3f, 0x01}, // J
{0x7f, 0x08, 0x14, 0x22, 0x41}, // K
{0x7f, 0x40, 0x40, 0x40, 0x40}, // L
{0x7f, 0x02, 0x0c, 0x02, 0x7f}, // M
{0x7f, 0x04, 0x08, 0x10, 0x7f}, // N
{0x3e, 0x41, 0x41, 0x41, 0x3e}, // O
{0x7f, 0x09, 0x09, 0x09, 0x06}, // P
{0x3e, 0x41, 0x51, 0x21, 0x5e}, // Q
{0x7f, 0x09, 0x19, 0x29, 0x46}, // R
{0x46, 0x49, 0x49, 0x49, 0x31}, // S
{0x01, 0x01, 0x7f, 0x01, 0x01}, // T
{0x3f, 0x40, 0x40, 0x40, 0x3f}, // U
{0x1f, 0x20, 0x40, 0x20, 0x1f}, // V
{0x3f, 0x40, 0x38, 0x40, 0x3f}, // W
{0x63, 0x14, 0x08, 0x14, 0x63}, // X
{0x07, 0x08, 0x70, 0x08, 0x07}, // Y
{0x61, 0x51, 0x49, 0x45, 0x43} // Z
};
void hx1230_ekranTemizle() {
for (int sayfa = 0; sayfa < 9; sayfa++) {
hx1230_komutYaz(0xB0 + sayfa);
hx1230_komutYaz(0x00);
hx1230_komutYaz(0x10);
for (int sutun = 0; sutun < 96; sutun++) { hx1230_veriYaz(0x00); }
}
}
void hx1230_yaziYaz(int satir, int sutun, const char* metin) {
hx1230_komutYaz(0xB0 + satir);
hx1230_komutYaz(sutun & 0x0F);
hx1230_komutYaz(0x10 | ((sutun >> 4) & 0x0F));
while (*metin) {
char karakter = *metin;
if (karakter >= 'a' && karakter <= 'z') karakter -= 32;
int idx = karakter - 32;
if (idx >= 0 && idx < 95) {
for (int i = 0; i < 5; i++) {
hx1230_veriYaz(pgm_read_byte(&(font_haritasi[idx][i])));
}
hx1230_veriYaz(0x00);
}
metin++;
}
}
void setup() {
// DDRD (Data Direction Register D) ile D0-D7 pinlerinin hepsini TEK SEFERDE çıkış yapıyoruz.
// B11111111 ifadesi tüm pinlerin OUTPUT olduğunu gösterir.
DDRD = B11111111;
// Ekran Güç Düzenlemesi (VCC ve Arka Işık HIGH, GND ve NC LOW)
// PORTD üzerinde bit 5 (VCC) ve bit 6 (BL) aktif ediliyor, diğer veri hatları başlangıç durumuna alınıyor.
PORTD = B01110010;
delay(100);
hx1230_init();
hx1230_ekranTemizle();
hx1230_yaziYaz(1, 10, "PORT MANIPULASYONU");
hx1230_yaziYaz(3, 22, "HIZ ASIRTMA");
hx1230_yaziYaz(5, 30, "10X FAST!");
}
void loop() {
// Boş döngü
}
pinMode(pin, OUTPUT); yazmamız gerekirken, bu komutla işlemcinin D Portundaki tüm pinleri (D0-D7) tek bir işlemci çevriminde çıkış moduna alıyoruz.HIGH seviyesine çeker.LOW seviyesine indirir.Henüz yorum yapılmamış. İlk yorumu siz yapın!