16x2 ve 20x4 Ekranlar için LCD Özel Karakter Oluşturucu
Hücrelere tıklayarak 5x8 karakterinizi çizin, hazır createChar() kodunu kopyalayın. 16x2, 16x4, 20x2 veya 20x4 fark etmeden bütün HD44780 karakter LCD'lerinde, paralel bağlantıda da I2C modülünde de çalışır. Her şey tarayıcınızda hesaplanır.
HD44780 LCD'de özel karakter nasıl çalışır?
16x2 bir modül serbest piksel çizmez, denetleyicinin içine gömülü font tablosundan karakter basar. Bu sabit tablonun adı CGROM. Onun yanında 64 baytlık yazılabilir bir alan daha vardır, CGRAM, ve yukarıdaki ızgarada düzenlediğiniz yer tam olarak burasıdır.
Bir karakter hücresi 5 piksel geniş, 8 piksel yüksektir. Yani bir karakter 8 bayt tutar, her satır için bir bayt. Her baytın yalnızca alt 5 biti kullanılır, üretilen değerlerin 31'i (B11111) geçmemesinin sebebi budur. 64 baytı 8'e böldüğünüzde bilinen sınır çıkar: aynı anda sekiz özel karakter, 0'dan 7'ye kadar slotlarda.
Denetleyicinin gördüğü haliyle bir kalp karakteri:
| Satır | Pikseller | İkilik | Onaltılık |
|---|---|---|---|
| 0 | . . . . . | B00000 | 0x00 |
| 1 | . # . # . | B01010 | 0x0A |
| 2 | # # # # # | B11111 | 0x1F |
| 3 | # # # # # | B11111 | 0x1F |
| 4 | # # # # # | B11111 | 0x1F |
| 5 | . # # # . | B01110 | 0x0E |
| 6 | . . # . . | B00100 | 0x04 |
| 7 | . . . . . | B00000 | 0x00 |
İkilik ve onaltılık aynı bitleri anlatır, hangisi size kolay geliyorsa onu seçin. İkilik yazım çizimle birebir hizalanır, onaltılık ise birkaç karakteri bir arada saklarken daha kısa durur.
Üretilen kodu projenizde kullanmak
Paralel bağlantı, LiquidCrystal:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // RS, E, D4, D5, D6, D7
byte kalp[8] = {
B00000, B01010, B11111, B11111,
B11111, B01110, B00100, B00000
};
void setup() {
lcd.begin(16, 2);
lcd.createChar(0, kalp); // begin() sonrasinda, oncesinde degil
lcd.home(); // CGRAM adres alanindan cik
lcd.write((uint8_t)0);
}
void loop() { }I2C modülü, LiquidCrystal_I2C:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // bazi modullerde 0x3F
void setup() {
lcd.init();
lcd.backlight();
lcd.createChar(0, kalp);
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
}İki durumda da baytlar aynıdır. I2C modülü, aynı HD44780'in önüne takılmış bir port genişleticiden ibarettir, karakterle ilgili hiçbir şeyi değiştirmez. 20x4 bir ekran için kurucuyu LiquidCrystal_I2C lcd(0x27, 20, 4) yapın, diziye dokunmayın.
Birden fazla karakter:
lcd.createChar(0, kalp);
lcd.createChar(1, derece);
lcd.createChar(2, pil);
lcd.setCursor(0, 0);
lcd.write((uint8_t)0);
lcd.print(" 23");
lcd.write((uint8_t)1); // derece isareti
lcd.print("C");MicroPython, aynı baytlar:
lcd.custom_char(0, bytearray([0x00, 0x0A, 0x1F, 0x1F,
0x1F, 0x0E, 0x04, 0x00]))
lcd.putstr(chr(0))Sekiz karakter sınırını aşmak
Sekiz sayısı kütüphanenin değil CGRAM'in donanımsal sınırıdır, hiçbir kütüphane bunu artıramaz. Yapabileceğiniz şey sekiz slotu bir önbellek gibi kullanıp çalışma anında üzerine yazmaktır:
- Ekran başına değiştirin. Ok işaretleri isteyen bir menü sayfası ile pil simgesi isteyen ayar sayfası aynı slotu paylaşabilir, sayfa değişirken
createChar()yeniden çağrılır. - Tek slotu canlandırın. Zamanlayıcıyla 0. slota her seferinde yeni bir 8 baytlık kare yazarsanız, ekstra slot harcamadan dönen bir animasyon veya dolan bir çubuk elde edersiniz.
- Geniş grafikleri hücrelerden kurun. İlerleme çubuğu genelde tek büyük görsel değil, yan yana dizilen beş altı karakter durumudur.
Bir slotun üzerine yazmak denetleyiciye 8 bayt göndermek demektir ve bu özellikle I2C üzerinden gerçek zaman harcar. loop() her döndüğünde değil, ekran gerçekten değiştiğinde çağırın.
Küçük kartlar için bir ayrıntı daha: createChar() RAM'den okur, bu yüzden PROGMEM dizisini doğrudan veremezsiniz. Önce memcpy_P(tampon, karakter, 8) ile kopyalayıp tampon değişkenini verin.
Sık karşılaşılan sorunlar
| Belirti | Sebep | Çözüm |
|---|---|---|
| Hiçbir şey yazılmıyor | 0. slot için lcd.print(0) | 0 kodu dizgi sonlandırıcısıdır, lcd.write((uint8_t)0) kullanın |
| Karakter boş çıkıyor | createChar(), begin() öncesinde çağrılmış | begin() veya init() sonrasına alın |
| İlk hücrede rastgele pikseller | İmleç CGRAM adres alanında kalmış | createChar() sonrasında lcd.home() veya lcd.setCursor() çağırın |
| Karakter kaymış veya ezilmiş | Dizi 8 bayt değil ya da değerler 31'i geçiyor | Diziyi elle düzenlemeyin, yukarıdan yeniden üretin |
| Alt satır çizdiğimden kalın | Alt çizgi imleci 8. satırda duruyor | lcd.noCursor() çağırın veya 8. satırı boş bırakın |
| Ekran komple blok veya bomboş | Kontrast potu ya da yanlış I2C adresi | Potu çevirin, veri yolunu tarayın, 0x3F deneyin |
Sıkça sorulan sorular
16x2 LCD'de kaç tane özel karakter kullanılabilir?
Sekiz tane. HD44780'de 64 bayt CGRAM var ve 5x8 bir karakter 8 bayt tuttuğu için aynı anda elinizde 0-7 arası slotlar oluyor. Slotun üzerine çalışma anında yazabildiğiniz için sınır ekran başına sekizdir, program başına değil.
Bu araç 20x4 LCD ile çalışır mı?
Evet. 16x2, 16x4, 20x2 ve 20x4 modüllerin hepsi aynı HD44780 denetleyicisini ve aynı CGRAM'i kullanır, bayt dizisi birebir aynıdır. Yalnızca kurucu değişir, örneğin LiquidCrystal_I2C lcd(0x27, 20, 4).
I2C LCD'de özel karakter kullanılabilir mi?
Evet. Yukarıdaki Arayüz seçeneğini I2C yapın, araç LiquidCrystal_I2C kodu üretsin. Karakter baytları değişmez, modül yalnızca baytların denetleyiciye ulaşma yolunu değiştirir.
CGRAM nedir?
CGRAM, denetleyicinin yazılabilir küçük font alanıdır. Sabit hazır font CGROM'da, sizin düzenlediğiniz sekiz karakter CGRAM'de durur. createChar() buraya 8 bayt yazar ve her bayt yalnızca alt 5 bitini kullanır, çünkü hücre 5 piksel geniştir.
lcd.print(0) neden karakteri göstermiyor?
0 karakter kodu aynı zamanda C dizgi sonlandırıcısıdır, print() orada durur. lcd.write((uint8_t)0) veya lcd.write(byte(0)) kullanın. 8-15 arası kodlar 0-7 arası slotların aynısını gösterdiği için lcd.write(8) de işinizi görür.
Karakterim neden boş veya bozuk çıkıyor?
Genelde üç şeyden biri: createChar(), begin() öncesinde çağrılmıştır, imleç CGRAM adres alanında kalmıştır, ya da dizi tam 8 bayt değildir veya değerler 0-31 aralığının dışındadır. Yukarıdaki tabloda her birinin çözümü var.
Üretilen baytları MicroPython'da kullanabilir miyim?
Evet. Standart MicroPython HD44780 sürücüsünde lcd.custom_char(0, bytearray([...])) ve ardından lcd.putstr(chr(0)) yazmanız yeterli. Yalnızca sözdizimi değişir, sekiz bayt aynı kalır.
İndirilebilir veya çevrimdışı sürümü var mı?
Kurulacak bir şey yok. Editör tarayıcınızda çalışan sade JavaScript, çizdiğiniz hiçbir şey sunucuya gitmiyor ve sayfa yüklendikten sonra bağlantınız kesilse de çalışmaya devam ediyor.
5x10 font ne oluyor?
Bazı HD44780 modülleri 5x10 font çalıştırabilir, o modda CGRAM sekiz değil dört karakter tutar. Bugün satılan neredeyse bütün 16x2 ve 20x4 modüller 5x8'dir, bu araç da onu üretir.