C dili ile ilgili bir soru

Başlatan psiko, 06 Mayıs 2005, 18:20:36

psiko

Hi-Tech Pic C compiler'ın sampples klasöründeki lcd.c dosyasında şöyle birşey var:

/* write a byte to the LCD in 4 bit mode */

void
lcd_write(unsigned char c)
{
	PORTB = (PORTB & 0xF0) |  (c >> 4);  //**********
	LCD_STROBE;
	PORTB = (PORTB & 0xF0) |  (c & 0x0F);   //**********
	LCD_STROBE;
	DelayUs(40);
}



/* write a string of chars to the LCD */

void
lcd_puts(const char * s)
{
	LCD_RS = 1;	// write characters
	while(*s)
		lcd_write(*s++);
}


özellikle yıldız koyduğum bölümler ile lcd_puts fonksiyonunun nasıl çalıştığını tam anlayamadım. yardımcı olursanız sevinirim.

SpeedyX

önce c öğrenerek bu işe başlamanı tavsiye ediyorum.
* lı değişkenler pointer'dır.

ayrıca bu konuyu zaten aşağıdaki adreste tartışıyorduk, neden ayrı konu açıyorsunuz.
http://picproje.org/index.php/topic,33431

@Aster, bu mesajı senin yazman gerekiyordu :)

psiko

burdaki sorum C diline ilişkin. diğerindeki asıl konu ise LCD.

sgokhan1

merhaba,
ANSI C: Programlama Dili, Sf.48, Bölüm 2.9'daki Bit Düzeyindeki Operatörler konusuna hafiften göz attıktan sonra, kodun açıklama beklediğiniz kısımları için şunları söyleyebilirim:

PORTB = (PORTB & 0xF0) |  (c >> 4);
bu deyimle LCD'ye yazdıracağımız karakterin üstteki 4 bitini (upper nibble) ayırıp yazdırıyoruz. Yani (PORTB & 0xF0) işlemi PORTB'nin üst 4 bitini maskeliyor, diğerlerini sıfırlıyor. Sonra (c >> 4) ifadesi c'deki bitleri  4 konum sağa kaydırıyor. (Boşalan bitler sıfırla doldurulacak biçimde.) Sonra bu değeri ilk ifade ile veya işlemine soktuğumuzda PORTB'ye 'c' karakterinin üst 4 bitini yüklemiş oluyoruz.

Diğerinde de mantık aynı ama orada alt 4 biti (lower nibble) PORTB'ye yükleyecek şekilde işlem yapılıyor.
Kolaylıklar...
**********************************************************
C18 derleyicisinde de durum şöyle:

#ifdef UPPER                            // Upper nibble interface
       DATA_PORT &= 0x0f;       // PORTx'in hangi 4lüsü
       DATA_PORT |= ((data<<4)&0xf0);  //data = karakterimiz

#else                                   // Lower nibble interface
       DATA_PORT &= 0xf0;
       DATA_PORT |= (data&0x0f);

psiko

sağol Gökhan. peki lcd_puts() fonksiyonu ile ilgili neler söyleyebilirsin?

Erkan Gench

Aslında SpeedyX haklı işe C öğrenerek başlamalısınız.

Sanırım takıldığınız konu while(*s) komutu. Burada yapılan şey s pointerinin  gösterdiği adresteki değerin sıfırdan farklı olduğu sürece yazma işinin sırayla devam ettirilmesi. C dilinde string'lerin sonuna NULL değeri yerleştirilir (genelde bu değer sıfırdır) böylece yapılan iş aslında stringin sonuna gelinceye kadar karakterlerin sırayla yazdırılmasıdır. sona gelindiğinde sıfır okunacak ve döngüden çıkılacak.

*s++ komutuda pointerin bellekte gösterdiği yeri bir arttırıyor. Yani bir sonraki karakteri okumak için.
Zorluklar, zamanında yapmamız gerekip de yapmadığımız kolay şeylerin birikmesiyle oluşur. Henry Ford ----------- Ya Rabbi Filistin'deki ve dünyanın her tarafındaki Müslüman kardeşlerime yardım et.

sgokhan1

Orada da s stringinde sonlandırma karakteri (NULL character = '\0') ile karşılaşıncaya kadar katar içindeki karakterler ilgili çıkışa gönderiliyor.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Bu durumda c18'de şöyle;

void putsXLCD(char *buffer)
{
       while(*buffer)                  // Write data to LCD up to null
       {
               while(BusyXLCD());      // Wait while LCD is busy
               WriteDataXLCD(*buffer); // Write character to LCD
               buffer++;               // Increment buffer
       }
       return;
}

psiko

Alıntı yapılan: "Erkan Gench"*s++ komutuda pointerin bellekte gösterdiği yeri bir arttırıyor. Yani bir sonraki karakteri okumak için.
öncekini anladım ama burda sorun var gibi.

*s değer olarak belli bir adresteki veri değil midir? yani bir adres değildir. s dizinin ilk elemanın bulunduğu adresi belirtir. s++ diyince bir sonraki elemanın adresine göstermez mi? *s++ değeri artırı gibi geldi bana. yanılıyor muyum?

psiko

yoksa ++ işlemi *'dan önce mi ele alınır? yani ilk önce s++ ile adres artırılır sonra * ile o adresteki bilgi alınır. sanırım böyle. tamam anladım sağolun.