Book Appointment Now

PIC ile I2C ile 2×16 LCD kullanma
2×16 Karakter LCD
2 satırda 16 karakter görüntüleyebilen ekran. Bu ekranlarda genellikle Hitachi üretimi HD44780U entegresi kullanılır. Entegre ile birlikte LCD’nin uçları 3 besleme, 3 komut, 8 veri ve 2 arka aydınlanmadır. Besleme uçları; VDD artı besleme, VSS eksi besleme, VEE LCD aydınlatmasıdır. Bu uç bir potansiyometre ile bağlanır ve ekran parlaklığı ayarlanır. Komut uçları; RS, komut ve veri seçimidir. RS=0 komut, RS=1 veri içindir. R/W okuma ve yazma ucudur. R/W = 0 yazma, R/W = 1 okuma içindir. Bu projede LCD’den veri okunmayacaktır. Dolayısıyla R/W her zaman 0 olacaktır. E etkinleştirme ucudur. Veri uçlarına yazılan verinin entegre tarafından işlenmesini sağlar. Düşen kenarda çalışır. Yani E 1 den 0 a inerken işlem yapılır. Bunun uygulaması E=1 olarak veri, veri uçlarına yüklenir. Sonra E= 0 yapılarak bu verinin entegre tarafından işlenmesi sağlanır.
HD44780U Entegresi
Bu entegrenin 3 çeşit belleği vardır. Ekrana yazılacakların tutulduğu DDRAM. Bu bellek 80×8 bit büyüklüğündedir. Buda 80 karakter uzunluğunda olduğunu gösterir. Karakterlerin tutulduğu sadece okunabilen CGROM. Bu bellek 9.920 bit büyüklüğündedir. Bu bellekte ASCI karakteri ve Japonca karakterler bulunmaktadır. Karakterlerin listesi Veri Sayfalarının 17. Sayfasında verilmektedir. Kullanıcıların tanımlayacağı karakterlerin tutulacağı CGRAM. Bu bellek 64 bayt uzunluğundadır.
DDRAM’a yazılan karakterlerin yalnızca 16’sı ekranda görünür. Kalan karakterlerin görünmesi için ekranın kaydırılması gerekir.
Bu entegrede kullanılacak komutlar Veri Sayfalarının 24. Sayfasındadır. Aşağıda tabloda bu komutların listesi verilmiştir.

Bu tablodaki kısaltmaların anlamları aşağıdadır:
| I/D | = 1 : | Her karakterde DDRAM adresini artır |
| I/D | = 0 : | Her karakterde DDRAM adresini azalt |
| S | = 1 : | Her karakterde ekranı kaydır |
| S | = 0 : | Her karakterde ekranı kaydırma |
| S/C | = 1 : | Ekranı kaydır |
| S/C | = 0 : | İmleci kaydır |
| R/L | = 1 : | Sola kaydır |
| R/L | = 0 : | Sağa kaydır |
| DL | = 1 : | 8 bit iletişim |
| DL | = 0 : | 4 bit iletişim |
| N | = 1 : | 2 satır |
| N | = 0 : | 1 satır |
| F | = 1 : | 5×10 nokta |
| F | = 0 : | 5×8 nokta |
| BF | = 1 : | Modül meşgul |
| BF | = 0 : | Komut alınabilir |
Modülü başlatırken bir dizi komut verilmesi gereklidir. 4 bit uygulama için gereken komutlar Veri Sayfalarının 46. Sayfasında verilmiştir. Bu komutların Türkçe çevirisi aşağıdaki tablodadır.

PCF8574 Modülü
PCF8574, I2C veri yolundan alınan 8 bit veriyi paralel hale getiren modüldür. Bunu LCD ekrana bağlayarak, LCD’yi I2C üzerinde yönetmek mümkündür. I2C veri yolunda her elemanın farklı adresinin olması gereklidir. Bu modülün 2 cinsinde 2 ayrı adres vardır. PCF8574 adres 0x27 ve PCF8574A adres 0x3F. Ayrıca üzerlerin bulunan A0, A1, A2 jamperleri değiştirerek 8 ayrı adres belirlemek olanaklıdır. Modülün 8 çıkışına karşılık LCD 11 girişe sahiptir. Bu fark yüzünden 4 bit iletişim kullanılması zorunludur. LCD’nin 3 komut girişi ve 4 veri girişi bu entegreye bağlanır. Fazla olan bir uç LCD’nin arka aydınlatmasını denetlemekte kullanılır. Aşağıdaki görselde bağlantıların nasıl olduğu görünmektedir.

PIC18F45K22 Mikro denetleyicisi
Bu PIC 40 uçlu, 64 MHz frekansında çalışan, 2 adet I2C modülü, başka birçok modülü olan mikro denetleyicidir. Türkiye piyasasında bulunmaktadır.
PIC ile LCD arasında iletişim 2 aşamalı olmaktadır. Önce PIC’ten PCF8574 modülüne, sonra PCF8574 modülünden HD44780U entegresine. İletişim sorunu genellikle ikinci aşamada ortaya çıkmaktadır.
MPLAB X IDE DE MCC ( MPLAB Code Configurator ) MODÜLÜ İLE I2C FONKSİYONLARI HAZIRLAMA
MPLAB X IDE hazır fonksiyonları olan MCC modülü vardır. Bu modülle seçimler yapılarak gerekli fonksiyonların hazırlanması sağlanabilir. Bu yazıda I2C için fonksiyonların hazırlanışı anlatılacaktır.
MCC’nin açılması
Aşağıdaki görselde MCC açmak için gerekli düğme gösterilmektedir. Bu düğmeye tıklanarak MCC sayfası açılır.

MCC sayfası açılınca aşağıdaki görsel ortaya çıkar. Bu görüntü Application Builder seçili iken alınmıştır. Seçilebilecek sekmeler sol üstte görünmektedir. Pin Package View sekmesi PIC’in uçlarını şematik gösterir. Project Resource sekmesinde projenin frekans, konfigürasyon bitleri gibi ayarların yapıldığı seçenekler vardır. Device Resource sekmesindeki PIC modüllerinin seçilip ayarlanacağı seçenekler vardır.

MCC sayfasının sol altında bulunan sekmelerden Pin Grid View kullanılacaktır. Burada uçlardan kullanılan, kullanılmayan gibi bilgiler bulunmaktadır. Aşağıda ilgili görsel bulunmaktadır.

MCC sayfasının sol üstündeki sekmeler aşağıda gösterilmiştir.

Frekans Ayarı:
Application Builder seçiliyken Clock Control seçilerek frekans ayarları yapılır. Aşağıdaki görselde yapılan ayarlar vardır. Dahili osilatör için System Clock Select’ten INTOSC seçilir. Internal Clock’dan 16 MHz seçilir. Eğer daha yüksek frekans istenirse Configuration bitlerinden PLL ON seçilir. Böylece PIC 4×16 = 64 MHz çalışabilir.

I2C Ayarları:
Sol üstte Application Builder ve ardından Device Resourses sekmeleri seçilir. Burada Drivers altında I2C sekmesi açılınca I2C_Client ve I2C_Host seçenekleri ortaya çıkar. Bu projede I2C_Host kullanılacaktır. Onun + işaretine tıklayınca I2C_Host, Application Builder sekmesine eklenir. Aşağıdaki görselde eklenmiş hali görünmektedir.

Üzerine tıklayınca sağ üst tarafta I2C_Host (None) sekmesi açılır. Bu sekmeden hangi MMSP modülünün kullanılacağı seçilir. Bu projede MSSP1 kullanılacaktır. Bu seçim yapılınca frekans ayarları görünür. 100 kHZ, 400 kHz ve 1 Mhz seçenekleri vardır. LCD için 100 kHz uygundur. Bu seçim yapılınca Calculated Speed satırında hesaplanan frekans görünür. Bu değer seçilenle aynı olmalıdır. Bu ayarı MCC yapacaktır. Aşağıda yapılan ayarlar gösterilmiştir.

Giriş Çıkış ayarları:
Sol üsteki Pin Package View seçilerek uçların göründüğü görsel ortaya çıkar. Sol altta Pin Grid View seçilerek uçların giriş çıkış ayarlarının yapılacağı görsel ortaya çıkar. Buradan istenilen uçların giriş yada çıkış olarak ayarlanması sağlanır. Bu projede RC1 ucunu çıkış olarak ayarlandı. Sağ üstteki Pins sekmesi ile uçların, analog dijital gibi detaylı ayarları yapılabilir. Aşağıdaki görsel yapılan ayarları göstermektedir.

Diğer Ayarlar:
Eğer gerekli ise benzer yollarla bunlarda hazırlanır.
Her şey tamamlanınca sol üstteki Generate butonuna tıklanarak fonksiyonların hazırlanması sağlanır.
Kullanılacak Fonksiyonun yeri:
En soldaki Projects sekmesine tıklanınca dizin yapısı ortaya çıkar. Buradan Source Files -> MCC Generated Files -> i2c_host -> src -> yolu ile mssp1.c dosyasına ulaşılır. Bu sayfa açılınca çok sayıda fonksiyon olduğu görülecektir. Bu projede bunlardan 2 tanesi kullanılacaktır. Bunlar
void I2C1_Initialize(void) ve
bool I2C1_Write(uint16_t address, uint8_t *data, size_t dataLength) dir.
I2C1_Initialize, programın başında bir kez çalıştırılması yeterlidir. Bunu MCC system.c dosyasında yapmaktadır.
I2C1_Write fonksiyonunu kullanılması:
address: LCD’nin I2C adresidir. Kullanılan LCD için adres 0x27’dir.
*data: Gönderilecek veri dizisidir.
dataLength: Gönderilecek veri dizisinin eleman sayısıdır.
Bu fonksiyon geriye değer döndürür. Bu değer iletişim başarılı olmuşsa 1 olmamışsa 0 dır.
Bu değer kullanılarak eğer iletişim başarılı olmamışsa iletişim tekrarlanabilir. Ancak yapılan denemelerde sorun çıkmadığı için bu kontrol yapılmayacaktır.
MCC’nin hazırladığı fonksiyonlar kesme ile çalışmaktadır. Onun için ana fonksiyonda mutlaka INTERRUPT_GlobalInterruptEnable(); ve
INTERRUPT_PeripheralInterruptEnable(); fonksiyonları çalıştırılmalıdır.
LCD’nin E’nin düşen kenarında verileri işlediği göz önünde bulundurularak, bir veri önce E=1 olarak gönderilecek, sonrasında aynı veri E=0 olarak gönderilip LCD’nin veriyi işlemesi sağlanacaktır.
Öncelikle I2C1_Write fonksiyonunu kullanarak özelleştirilmiş veri gönderecek bir fonksiyon hazırlanır. Aşağıda bu fonksiyon verilmiştir:
#define LCD_adres 0x27
#define LCD_RS 1U
#define LCD_Enable 4U
#define LCD_aydinla 8U
void I2C_gonder(uint8_t veri ){
uint8_t dizi[]={veri | LCD_Enable | LCD_aydinla, (veri & ~LCD_Enable) | LCD_aydinla};
I2C1_Write(LCD_adres, &dizi[0], 1);
__delay_us(500);
I2C1_Write(LCD_adres, &dizi[1], 1);
__delay_ms(5);
}CLCD 4 bit çalıştığı için, 8 bit veriyi ikiye bölerek göndermek gereklidir. Bunu yapacak fonksiyon aşağıda verilmiştir:
/*
LCD'ye veri gönderir. Kumut için RS=0, yazı için RS=LCD_RS olmalıdır.
*/
void LCD_gonder(uint8_t bilgi, uint8_t RS){
I2C_gonder((bilgi & 0xF0) | RS); //Üst 4 bit
I2C_gonder(((bilgi << 4) & 0xF0) | RS); //Alt 4 bit
}Yukarıda verilmiş bulunan LCD’yi başlatacak komutları uygulayacak fonksiyon aşağıda verilmiştir:
/* LCD ekranı başlatır. Önce bu fonksiyon çağrılmalıdır. */
void LCD_baslat(void){
__delay_ms(50);
I2C_gonder(0x30);
I2C_gonder(0x30);
I2C_gonder(0x30);
I2C_gonder(0x20);
LCD_gonder(0x28, 0x00);
LCD_gonder(0x08, 0x00);
LCD_gonder(0x01, 0x00);
LCD_gonder(0x06, 0x00);
LCD_gonder(0x0C, 0x00);
__delay_ms(50);
}LCD’de imlecin istenen yere götüren fonksiyon aşağıda verilmiştir:
/* İmleçi verilen satır ve sütun numarasına götürür */
void lcd_git(uint8_t satir, uint8_t sutun) {
uint8_t temp;
switch (satir) {
case 1:
temp = sutun - 1 + 0x80;
break;
case 2:
temp = sutun - 1 + 0xc0;
break;
}
LCD_gonder(temp, 0x00);
}Verilen satır ve sütuna yazı yazacak fonksiyon aşağıda verilmiştir:
/* Verilen satır sütun numarasından başlayarak ekrana mesaj yazar*/
void lcd_mesajyaz(uint8_t satir, uint8_t sutun, const char *mesaj) {
lcd_git(satir, sutun);
do {
LCD_gonder(*mesaj++, LCD_RS);
__delay_us(200);
} while (*mesaj);
}Bu projenin tamamlanması için gereken adımlar aşağıda belirtilmiştir: