I2C Haberleşmesinde hata

Başlatan Cemre., 05 Aralık 2015, 20:43:02

Cemre.

Herkese iyi akşamlar. Bir kaç gündür mpu6050 ile pic18f4550 arasında iletişim kurmaya çalışıyorum. İlk denemelerimi mikroC ile yapmıştım ancak bir noktada tıkandım ve sorunun donanımsal olmadığı çok açıktı. Bunu modülün devrede hiç bir değişiklik yapmadan arduino ile haberleşebiliyor olmasından anlıyorum.

XC8'de ilk kez yazıyorum, biraz uğraştırdı ancak hala LCD'de gördüğüm yazı Device not found. Kodu incelediğinizde ne demek istediğimi anlayacaksınız sanıyorum. Peki nerede hata yapıyorum?

#include <xc.h>
#define RS RD4
#define EN RD5
#define D4 RD0
#define D5 RD1
#define D6 RD2
#define D7 RD3
#define _XTAL_FREQ 20000000
#include "config_bits.h"
#include "lcd.h"
#include <plib.h>
#define LED1 LATEbits.LE0
#define LED2 LATEbits.LE1
#define LED3 LATEbits.LE2

unsigned char status,data;

void delay_ms(unsigned int dt){
    unsigned int i;
    for(i=0;i<dt;i++)
        __delay_ms(1);
}

void init_mcu(){
    ADCON1  = 0x0F;                         // Analog özellikli tüm pinler Dijital G/Ç yap?ld?.
    CMCON   = 0x07;                         // Kar??la?t?r?c?lar kapat?ld?.
    LATE    = 0x00;                         // PORTE Temizlendi.
    TRISE   = 0x00;                         // PORTE Ç?k?? yap?ld?.
    LATD    = 0x00;                         // PORTD Temizlendi.
    TRISD   = 0x00;                         // PORTD Ç?k?? yap?ld?.
    //SSPADD = ((Fosc/BitRate)/4)-1
    //SSPADD = ((20000000/100000)/4)-1
}

void check_device(unsigned char dev_address){
    IdleI2C();
    StartI2C();
    IdleI2C();
    do
    {
        status = WriteI2C(dev_address);
        if(status == -1)
        {
            data = SSPBUF; 
            SSPCON1bits.WCOL=0; 
        }
        Lcd_Set_Cursor(2,1);
        Lcd_Write_String("Device not found");
        delay_ms(50);
        LED3 = ~LED3;    //bu led gerçekten yanıp sönüyor, yani status 0 olmuyor ve sonsuz döngü söz konusu
    }while(status!=0);
    Lcd_Set_Cursor(2,1);
    Lcd_Write_String("Device is OK");
    IdleI2C();
    StopI2C();
}

void main(void) {
    init_mcu();
    Lcd_Init();
    CloseI2C();
    OpenI2C(MASTER,SLEW_OFF);
    SSPADD  = 49;
    Lcd_Clear();
    Lcd_Set_Cursor(1,1);
    Lcd_Write_String("Start");
    check_device(0x68);
    CloseI2C();
    return;
}


Önceki konularım;
https://www.picproje.org/index.php/topic,62272.0.html -  Lojik Seviye Dönüştürücü neden çalışmadı?
https://www.picproje.org/index.php/topic,62180.0.html - 18F4550 ve MPU-6050 ile haberleşmede takılıyor

Cemre.

Bu konuda yardımcı olabilecek ya da XC8 plib kullanarak I2C haberleşmesi sağlanabilmiş bir örnek paylaşabilecek yok mu acaba?

baran123

#2
MCU 5V MPU 3.3V ile çalıştırın.(Logic Converter)
http://www.microchip.com/forums/m757235.aspx
Burada böyle çözülmüş.
Örnek : https://github.com/jrowberg/i2cdevlib/tree/master/PIC18

Cemre.

Halihazirda kurduğum devrede lojik seviye dönüştürücü mevcut. Bunu yukarıdaki linkten de gorebilirsiniz. Yazilim hakkında bir görüşünüz var mı?
İyi akşamlar.

baran123

Vallahi ne söyleyebilirim bilmiyorum ama bu I2C STM de beni çileden çıkarmıştı.Anladığım kadarıyla en küçük bir şeyde bu while(flag) gibi kısımlardan birinde takılıyor.Kütüphanesi regisler kullanarak I2C init, send, receive gibi kısımları kendiniz yazarsanız debug yaparak hatanın nerede olduğunu bulabilirsiniz.Yoksa saç kafada bırakmaz :)

RaMu

#5
        status = WriteI2C(dev_address);
satırının yerine

        status = WriteI2C(0x68);
veya
        status = WriteI2C(0x69);

yazıp deneyebilir misin.


    check_device(0x68);
kısmında
    check_device(0x69);
deneyebilirmisin.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

iyildirim

@RaMu yazınca aklıma geldi.
0x68 ile Arduino da çalışıyorsa (arduino  vede bazı platformlar için device adress 7 bit verilir, belki sizin kullandığınız kütüphane 8 bit adres istiyordur.)
Device adress olarak 0xD0 deneyin.
   

Cemre.

Alıntı yapılan: iyildirim - 06 Aralık 2015, 23:13:42
@RaMu yazınca aklıma geldi.
0x68 ile Arduino da çalışıyorsa (arduino  vede bazı platformlar için device adress 7 bit verilir, belki sizin kullandığınız kütüphane 8 bit adres istiyordur.)
Device adress olarak 0xD0 deneyin.
Denedim hocam ancak maalesef. Sonuç değişmedi. Kullandığım kütüphane xc8'in kendi plib.idir.

Timucin

Merhaba;
PIC16F876A ve 24C32 I2C harici EEPROM için yazdığım kütüphane belki işinize yarar.
Derleyip toğarlamadan gönderdiğim için umarım beni bağışlarsınız.
Kod'lar hemproteus'da hem de gerçek devrede çalışmaktadır

Saygılarımla
Timuçin

#ifndef I2C_16FSERIES_H
#define	I2C_16FSERIES_H


//////////////////////////////////////////////////////////////////////////////////////////
//           			Kullanici Tanimlamalari - HARDWARE   		//
//////////////////////////////////////////////////////////////////////////////////////////

#define SCL_Dir		TRISCbits.TRISC3
#define SDA_Dir		TRISCbits.TRISC4

#define SCL_pin   	PORTCbits.RC3
#define SDA_pin   	PORTCbits.RC4

// 24C32 Harici EEPROM Device Adresi tanimla. PIC'in bu cihaza ulasabilmesi icin kullanacagi adres.
#define EEPROM_24C32_Address    0xA0

/////////////////////////////////////////////////////////////////////////////////////////

#define I2C_Write_CMD 0
#define I2C_Read_CMD 1

void INIT_I2C(void);
void I2C_WaitForIdle(void);
void I2C_Start(void);
void I2C_RepStart(void);
void I2C_Stop(void);
void I2C_Send_ACK(void);
void I2C_Send_NACK(void);
bit  I2C_Send_OneByte(unsigned char);
unsigned char I2C_Get_OneByte(void);

void Write_Byte_To_I2C_Slave(unsigned char, unsigned int, unsigned char);
unsigned char Read_Byte_From_I2C_Slave(unsigned char, unsigned int);
void Write_Page_To_I2C_Slave(unsigned char, unsigned,unsigned char*, unsigned char);
void Read_Page_From_I2C_Slave(unsigned char, unsigned int, unsigned char*, unsigned int);

#endif	/* I2C_16FSERIES_H */


// ***********************************************************************************************************
// ** ##################################################################################################### **
// ** 	Dosya Adi : 	I2C_Ext_EEPROM.c                                                                    **
// ** ##################################################################################################### **
// **  	Tarih		: Aralik 2015                                                                          	**
// **  	Hazirlayan	: Timucin                                                                               **
// ** 	Compiler  	: MPLABX IDE V1.60 -- XC8 Ver1.32                                                       **
// ** 	Bu program 24CXX serisi harici EEPROM'larin I2C protokolu ile kontrolu amaci ile yazilmistir   		**
// ** 	2 pin I2C interface -- SDA ve SCL I2C Seri Haberlesme protokolu										**
// ** 	Ilk bolum I2C fonksiyonlarini icermektedir; 2inci bolumde ise External EEPROM yordamlar bulunur		**
// ***********************************************************************************************************
#include <xc.h>
#include "main.h"
#include "I2C_16Fseries.h"

//    **************
// ****  INIT_I2C  *******************************************************************************************
// **	Bu altyordam, Harici EEPROM'un power-up kosullarini gercekler ve PIC'i Master I2C olarak sartlar    **
// **	Main'de bu fonksiyon cagirilmadan, Harici EEPROM'un power'inin max'a ulasmasi icin main'in basinda	**
// **	kisa bir bekleme koymakta fayda var.                                                                **
// **	SDA ve SCL pinleri, TRIS'de Input olarak sartlanmalidir. Programda 100 KHz Baud Rate kullanilacak   **
// **	Ben Interrupt'lari polling olarak kullandim. Programda Kesme bayraklarini kontrol ederek islemler   **
// **	gerceklesmektedir. Eger ISR(Interrupt Service Routin) kullanilacaksa bu kaynak dosya revize edilmeli**
// ***********************************************************************************************************
void INIT_I2C(void){
    SCL_Dir = 1;                // SCL pinini TRIS'de Input olarak sartla
    SDA_Dir = 1;                // SDA pinini TRIS'de Input olarak sartla
    SSPSTAT = 0x80;             // Slew Rate'i 10 KHz mod icin disable et.  
    SSPCON = 0x28;              // SDA and SCLpinlerini I2C Master mode olarak set et, BaudRate = FOSC/(4 * (SSPADD + 1))
    SSPCON2 = 0x00;             // MSSP Control Register' resetle
    
    // I2C Master Clock Speed:      BaudRate = 4000000 / (4*(9 + 1)) = 100KHz   -- En yakin degeri vermek gerekiyor.
    SSPADD = 10;                // 4MHz Clock frekansinda 100KHz Baud Rate
    
    PIR1bits.SSPIF = 0;              // SSPIF Interrupt flag'i sifirla
    PIR2bits.BCLIF = 0;              // Bus Collision Interrupt flag'i sifirla
}

//    *********************
// ****  I2C_WaitForIdle  ************************************************************************************
// **	Bu yardimci altyordam, SSPCON2 ve SSPSTAT.Read/Write'i kontrol ederek, islemlerin                   ** 
// **	tamamlanip tamamlanmadigini ve harici EEPROM'un idle moda gecip gecmedigini kontrol eder            **
// **	Ve harici EEPROM idle moda gecene kadar bekler.                                                     **
// ***********************************************************************************************************
void I2C_WaitForIdle(void){
  // I2C Bus ve Status Idle olana kadar bekle (ACKEN, RCEN, PEN, RSEN, SEN)
  while (( SSPCON2 & 0x1F ) || ( SSPSTATbits.R_nW));
}

//    ***************
// ****  I2C_Start  ******************************************************************************************
// **	Bu altyordamin amaci, transmisyona baslamadan Start biti gondermektir.                              ** 
// **	Oncelikle I2C bus'in Idle olup olmadigi kontrol edilir ve degilse Idle olmasi beklenir. Sonrasinda  ** 
// **	Start biti gondererek transmisyon baslatilir.                                                       **
// ***********************************************************************************************************
void I2C_Start(void){
    I2C_WaitForIdle();              // I2C modulun idle oldugundan emin ol, idle olana kadar bekle.
    SSPCON2bits.SEN = 1;			// Start biti gonder
	while(SSPCON2bits.SEN & !PIR1bits.SSPIF);		// Islemin tamamlanmasini bekle
	PIR1bits.SSPIF = 0;             // SSP Interrupt flag'i sifirla
}

//    ******************
// ****  I2C_RepStart  ***************************************************************************************
// **	Bu altyordamin amaci, Tekrarlanan Start biti gondermektir. Ust uste birden fazla byte icin islem    ** 
// **	yapilacaksa, I2C protokolune gore aralarda Tekrarlanan Start biti gonderilmeli                      ** 
// **	Oncelikle I2C bus'in Idle olup olmadigi kontrol edilir ve degilse Idle olmasi beklenir. Sonrasinda  ** 
// **	Tekrarlanan Start biti gondererek transmisyona devam edilir.                                        **
// ***********************************************************************************************************
void I2C_RepStart(void){
    I2C_WaitForIdle();              // I2C modulun idle oldugundan emin ol, idle olana kadar bekle.
    SSPCON2bits.RSEN = 1;			// Tekrarlanan Start biti gonder
    while(SSPCON2bits.RSEN & !PIR1bits.SSPIF);		// Islemin tamamlanmasini bekle
    PIR1bits.SSPIF = 0;             // SSP Interrupt flag'i sifirla
}

//    **************
// ****  I2C_Stop  *******************************************************************************************
// **	Bu altyordamin amaci, Stop biti gondermek ve o anki I2C Transmisyonunu sonlandirmaktir.             ** 
// **	Oncelikle I2C bus'in Idle olup olmadigi kontrol edilir ve degilse Idle olmasi beklenir. Sonrasinda  ** 
// **	Stop biti gondererek transmisyona son verilir                                                       **
// ***********************************************************************************************************
void I2C_Stop(void){
    I2C_WaitForIdle();              // I2C modulun idle oldugundan emin ol, idle olana kadar bekle.
	SSPCON2bits.PEN = 1;			// Stop biti gonder
	while(SSPCON2bits.PEN & !PIR1bits.SSPIF);		// Islemin tamamlanmasini bekle
	PIR1bits.SSPIF = 0;             // SSP Interrupt flag'i sifirla
}

//    ******************
// ****  I2C_Send_ACK  ***************************************************************************************
// **	Bu altyordamin amaci, en son yapilan transmisyonun basarili oldugunu Slave'e bildirmektir.          ** 
// **	Slave'e Positive ACKnowledge gonderir.																**
// ***********************************************************************************************************
void I2C_Send_ACK(void){
	SSPCON2bits.ACKDT = 0;          // 0 (sifir) ACK (basarili) anlamina gelir
	SSPCON2bits.ACKEN = 1;          // ACKDT degerini gonder.
	while(SSPCON2bits.ACKEN & !PIR1bits.SSPIF);		// Islemin tamamlanmasini bekle
	PIR1bits.SSPIF = 0;             // SSP Interrupt flag'i sifirla
}

//    *******************
// ****  I2C_Send_NACK  **************************************************************************************
// **	Bu altyordamin amaci, en son yapilan transmisyonun basarisiz oldugunu Slave'e bildirmektir.         ** 
// **	Slave'e Negative ACKnowledge gonderir.																**
// ***********************************************************************************************************
void I2C_Send_NACK(void){
	SSPCON2bits.ACKDT = 1;          // 1 NACK (basarisiz) anlamina gelir
	SSPCON2bits.ACKEN = 1;          // ACKDT degerini gonder.
	while(SSPCON2bits.ACKEN & !PIR1bits.SSPIF);		// Islemin tamamlanmasini bekle
	PIR1bits.SSPIF = 0;             // SSP Interrupt flag'i sifirla
}

//    **********************
// ****  I2C_Send_OneByte  ***********************************************************************************
// **	Bu altyordamin amaci, 1 byte'lik veriyi I2C bus'tan Slave'e iletmektir.                             **
// **  	Islem tamamlanana kadar bekler.																		**
// ***********************************************************************************************************
bit I2C_Send_OneByte(unsigned char ByteToWrite){
	SSPBUF = ByteToWrite;                                   // Gonderilecek byte'i Seri Buffer'a yaz
    if (SSPCONbits.WCOL)  return (SSPCON2bits.ACKSTAT);     // Write Collision'i (cakismayi) kontrol et; 1'se Slave'den gelen ACK/NACK bilgisini geri dondur.
     
	while(SSPSTATbits.BF & !PIR1bits.SSPIF);                // Write Cycle (Yazma islemi) tamamlanana kadar bekle
	PIR1bits.SSPIF = 0;                     // SSP Interrupt flag'i sifirla
    I2C_WaitForIdle();                      // I2C modulun idle oldugundan emin ol, idle olana kadar bekle.
	return (SSPCON2bits.ACKSTAT);           // Slave'den gelen ACK/NACK bilgisini geri dondur.
}

//    *********************
// ****  I2C_Get_OneByte  ************************************************************************************
// **	Bu altyordamin amaci, Slave'den 1 byte'lik veriyi I2C bus protokolu ile okumaktir.                  **
// **	Okunan 1 byte'lik DATA'yi geri dondurur.															**
// ***********************************************************************************************************
unsigned char I2C_Get_OneByte(void){
    I2C_WaitForIdle();          // I2C bus'in idle oldugundan emin ol, idle olana kadar burda bekle.
	SSPCON2bits.RCEN = 1;       // 8 bit I2C okuma icin SSP'yi enable et.
//    while(!SSPSTATbits.BF & !PIR1bits.SSPIF);		// Islemin tamamlanmasini bekle
    while(!PIR1bits.SSPIF);		// Islem tamamlanana kadar bekle
	PIR1bits.SSPIF = 0;         // SSP Interrupt flag'i sifirla
    return (SSPBUF);            // Okunan byte'i geri donder
}



// ***********************************************************************************************************
// ** ##################################################################################################### **
// ** #								EXTERNAL SLAVE ILE ILGILI YORDAMLAR								  	#	**
// ** ##################################################################################################### **
// ***********************************************************************************************************


//    *****************************
// ****  Write_Byte_To_I2C_Slave  ****************************************************************************
// **	Bu altyordamin amaci, Cihaz numarasi verilen Slave'in belirtilen adresine, verilen 1 bytelik 		**
// **	veriyi yazmaktir. Adres 0 - 0x4FFF arasi ve Data Byte 0 - 0xFF arasi olabilir.						**
// ***********************************************************************************************************
void Write_Byte_To_I2C_Slave(unsigned char My_Device_Address, unsigned int Mem_Address, unsigned char MyByteToWrite){
	I2C_Start();										// I2C haberlesmesine basla; Start biti gonder. 

// 	Slave'in Cihaz Adresi ile birlikte "YAZMA" yapilacagini bildirir komut gonder.
	while(I2C_Send_OneByte(My_Device_Address + I2C_Write_CMD) == 1){		// Slave Adresi ile birlikte Komut (0 = Yazma) gonder ve Slave'den
		I2C_RepStart();											//  ACK gelene kadar Tekrarlanan Start biti gondermeye devam et	
	}		

//	I2C_Send_OneByte(My_Device_Address + I2C_Write_CMD);
//	I2C_RepStart();									///  BU SANKIM OLMAYACAK ????????????????????????????????????????????????????????
	I2C_Send_OneByte(Mem_Address >> 8);					// Once Adres'in High Byte'ini Harici Slave'e gonder
	I2C_Send_OneByte((unsigned char) Mem_Address);		// Sonrasinda Adres'in Low Byte'ini Harici Slave'e gonderer
	I2C_Send_OneByte(MyByteToWrite);					// Data Byte'i yaz.
	I2C_Stop();											// I2C haberlesmesini sonuclandir (durdur); Stop biti gonder
		// 5 milisec bekleme koymali miyim????????????????????????????????????????????????????????????????????????????????????
}

//    ******************************
// ****  Read_Byte_From_I2C_Slave  ***************************************************************************
// **	Bu altyordamin amaci, Cihaz numarasi verilen Slave'in belirtilen 1 bytelik veriyi okumak ve bunu 	**
// **   geri dondurmektir. Adres 0 - 0xFFFF arasi olabilir.													**
// ***********************************************************************************************************
unsigned char Read_Byte_From_I2C_Slave(unsigned char My_Device_Address, unsigned int Mem_Address){
	volatile unsigned char MyByteToRead = 0;			// Okuma yapilip fonksiyondan dondurulecek datanin saklanacagi yazmac. Her ihtimale karsin sifirlandi
	I2C_Start();										// I2C haberlesmesine basla; Start biti gonder. 

// 	24C32'nin Cihaz Adresi ile birlikte "YAZMA" yapilacagini bildirir komut gonder.
	while(I2C_Send_OneByte(My_Device_Address + I2C_Write_CMD) == 1){ 		// Slave Adresi ile birlikte Komut (0 = Yazma) gonder ve Slave'den
		I2C_RepStart();											//  ACK gelene kadar Tekrarlanan Start biti gondermeye devam et	
	}	
	
//	I2C_Send_OneByte(My_Device_Address + I2C_Write_CMD);
//	I2C_RepStart();								///  BU SANKIM OLMAYACAK ????????????????????????????????????????????????????????
	I2C_Send_OneByte(Mem_Address >> 8);					// Once Adres'in High Byte'ini Slave'e gonder
	I2C_Send_OneByte((unsigned char) Mem_Address);		// Sonrasinda Adres'in Low Byte'ini Slave'e gonder
	I2C_RepStart();										// I2C Haberlesmesine devam et; Tekrarlanan Start biti gonder
	I2C_Send_OneByte(My_Device_Address + I2C_Read_CMD);				// Slave'in Cihaz Adresi ile birlikte "OKUMA" yapilacagini bildirir komut gonder.		

	MyByteToRead  = I2C_Get_OneByte();					// Harici EEPROM'dan ilgili adres'deki Data'yi oku ve yazmaca kopyala
	I2C_Send_NACK();									// Okumayi sonlandirmak icin NACK (Negative ACKnowledge) gonder.
	I2C_Stop();											// I2C haberlesmesini sonuclandir (durdur); Stop biti gonder

	return MyByteToRead ;								// Okunan ve de yazmaca alinan datayi geri donder.
}

//    *****************************
// ****  Write_Page_To_I2C_Slave  ****************************************************************************
// **	Bu altyordamin amaci, Slave'e 1'den fazla byte'i Page Write Modunda yazmayi saglamaktir				**
// **																										**
// **	EXTERNAL EEPROM 24C Serilei icin Onemli !.....														**
// **   MyAddress 0, 32, 64, 128, ..... degerlerini alabilir. Page Write Mode'da bir cirpida maksimum		**
// **	32 Byte veri yazilabilir. Bu yuzden NoOfBytesToWrite ancak 1-32 arasi deger alabilir.				**
// ***********************************************************************************************************
void Write_Page_To_I2C_Slave(unsigned char My_Device_Address, unsigned int Mem_Address,unsigned char* pBytesToWrite,unsigned char NoOfBytesToWrite){
	volatile unsigned int MySayac;							// Bu yordam icerisindeki dongude kullanilacak
	I2C_Start();											// I2C haberlesmesine basla; Start biti gonder.

//  24C32'nin Cihaz Adresi ile birlikte "YAZMA" yapilacagini bildirir komut gonder.
	while(I2C_Send_OneByte(My_Device_Address + I2C_Write_CMD) == 1){	// Slave Adresi ile birlikte Komut (0 = Yazma) gonder ve Slave'den
		I2C_RepStart();										//  ACK gelene kadar Tekrarlanan Start biti gondermeye devam et
	}	

//	I2C_Send_OneByte(My_Device_Address + I2C_Write_CMD); 
//	I2C_RepStart();									///  BU SANKIM OLMAYACAK ????????????????????????????????????????????????????????
	I2C_Send_OneByte(Mem_Address >> 8);							// Once Adres'in High Byte'ini Slave'e gonder
	I2C_Send_OneByte((unsigned char) Mem_Address);				// Sonrasinda Adres'in Low Byte'ini Slave'e gonder

	for(MySayac = 0; MySayac < NoOfBytesToWrite; MySayac++){	// Yazilacak Byte sayisi kadar dongu olustur
		I2C_Send_OneByte(pBytesToWrite[MySayac]);				// Bir sonraki Data Byte'i yaz.
	}
	
	I2C_Stop();												// I2C haberlesmesini sonuclandir (durdur); Stop biti gonder
}

//    ******************************
// ****  Read_Page_From_I2C_Slave  ***************************************************************************
// **	Bu altyordamin amaci, Verilen EEPROM adresinden, NoOfBytesToRead ile verilen sayidaki byte'lari 	**
// **   okumak ve pMyBytesToRead'a kopyalamaktir. Address 0xFFFF arasi ve de NoOfBytesToRead 0 - 0xFFFF 	**
// **	arasi herhangi bir degerlabilir, Ancak Slave'in kapasitesi max limit icin onem arz etmektedir. 		**
// **	Okunan Byte'lar pMyBytesToRead Array ile donmus olur.												**
// ***********************************************************************************************************
void Read_Page_From_I2C_Slave(unsigned char My_Device_Address, unsigned int Mem_Address, unsigned char* pBytesToRead, unsigned int NoOfBytesToRead){
	unsigned int MySayac;
	I2C_Start();										// I2C haberlesmesine basla; Start biti gonder.

// 		24C32'nin Cihaz Adresi ile birlikte "YAZMA" yapilacagini bildirir komut gonder.
	while(I2C_Send_OneByte(My_Device_Address + I2C_Write_CMD) == 1){	// Slave Adresi ile birlikte Komut (0 = Yazma) gonder ve Slave'den
		I2C_RepStart();										//  ACK gelene kadar Tekrarlanan Start biti gondermeye devam et	
    }
	
//	I2C_Send_OneByte(My_Device_Address + I2C_Write_CMD); 
//	I2C_RepStart();									///  BU SANKIM OLMAYACAK ????????????????????????????????????????????????????????
	I2C_Send_OneByte(Mem_Address >> 8);					// Once Adres'in High Byte'ini Slave'e gonder
	I2C_Send_OneByte((unsigned char) Mem_Address);		// Sonrasinda Adres'in Low Byte'ini Slave'e gonder
	I2C_RepStart();										// I2C Haberlesmesine devam et; Tekrarlanan Start biti gonder

	// 24C32'nin Cihaz Adresi ile birlikte "OKUMA" yapilacagini bildirir komut gonder.	
	I2C_Send_OneByte(My_Device_Address + I2C_Read_CMD);		

	pBytesToRead[0] = I2C_Get_OneByte();				// Harici Slave'den ilk Byte'i oku.

	for(MySayac = 1; MySayac < NoOfBytesToRead; MySayac++){		// Okunacak Byte sayisi kadar dongu olustur
		I2C_Send_ACK();									// Bir sonraki Byte'i alabilmek ve haberlesmeye devam edebilmek icin Slave'e Positive ACKnowledge gonder
		pBytesToRead[MySayac] = I2C_Get_OneByte();		// Bir sonraki Byte'i oku
	}

	I2C_Send_NACK();									// Okumayi sonlandirmak icin NACK (Negative ACKnowledge) gonder.
	I2C_Stop();											// I2C haberlesmesini sonuclandir (durdur); Stop biti gonder
}



// OKUMA SIRASINDA, STOP BIT GONDERMEDEN ONCE NEDEN NACK GONDERILIR?
// The Bus Pirate sends a Slave I2C read address. After the Slave ACKnowledges the address (bit 9), it immediately 
// starts sending data to the Bus Pirate and ignores the I2C STOP sequence sent by the address scanner. This caused 
// extra I2C addresses to appear at random.
// This is the purpose of the I2C NACK bit that concludes a transfer from the slave IC to the master device. If the 
// master ACKs the last byte and then attempts a STOP condition, the slave might put a 0 on the data line that blocks 
// the STOP condition. If the master NACKs the last byte then the slave IC gives up and everybody exits cleanly.


#include <xc.h>
#include <stdio.h>      //sprintf kullanacagiz, bu yuzden gerekli
#include "main.h"
#include "LCDchar.h"
#include "ds1302.h"
#include "I2C_16Fseries.h"

#define Pause_1Sec()    __delay_ms(250); __delay_ms(250); __delay_ms(250); __delay_ms(250)
 

/*************************************************************************************************/
void Initialize_System (void){
    CMCON = 0x07;           // PIC 16F876A Comparator Modul Off
    ADCON1 = 0x06;          // Tum Portlar Digital          
    
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    
    TRISA = 0x00;          
    TRISB = 0x00;  
    TRISC = 0x00;

    INIT_I2C();   
    
}       /*  End of Initialize_System() */

void Test_24C32 (void){
	unsigned char TxArray[] = { 'T','i','m','u','c','i','n',' ','2','0','1','5','-','-','\0'};

    unsigned char RxArray[sizeof(TxArray)];  
//    unsigned char RxByte;
    
	Write_Byte_To_I2C_Slave(EEPROM_24C32_Address, 0x0001, 'd');               			// Ext 24C32 EEPROM'un 0x0001 adresine 'd' yaz
//	RxByte = Read_Byte_From_I2C_Slave(24C32_EEPROM_Address, 0x0001);          			// Ext 24C32 EEPROM'un 0x0001 adresine 'd' oku ve RxByte'a yaz		
	Write_Page_To_I2C_Slave(EEPROM_24C32_Address, 0x0020, TxArray, sizeof(TxArray));	// Ext 24C32'nin 0x0020 adresinden başlayarak TxArray'in icerisindeki Data'yi yaz.
	Read_Page_From_I2C_Slave(EEPROM_24C32_Address, 0x0020, RxArray, sizeof(TxArray));	// Ext 24C32'nin 0x0020 adresinden başlayarak TxArray'in boyutu kadar Data'yi oku ve bunlari RxArray'e yaz.
 
   
}    /*  End of Test_24C32() */


/*************************************************************************************************/
/*************************************************************************************************/
/*************************************************************************************************/
/*************************************************************************************************/

void main(void) {
//    volatile unsigned char MySayac;					// main icerisinde kullanilacak olan donguler icin...
	Initialize_System ();
 

	lcd_clear(); 
	lcd_home(); 
//        	 0123456789ABCDEF
	sLCD_sc("DS1302 Denemesi"); 
    Pause_1Sec();
    
    
    Test_24C32();  
        Pause_1Sec();    Pause_1Sec();    Pause_1Sec();
    
//    Test_ds1302();

    
    
    
    while(1);			// Sonsuz dongu; burada bekle

    
    
}   /*  End of main */