(I2C)24C02'den Veri Okuma Sorunu

Başlatan NaMcHo, 16 Mayıs 2011, 21:59:57

NaMcHo

main.c
#include <p18f4520.h>
#include "LCD216_benim.h"
#include "i2c.h"

#pragma config OSC = HS , LVP = OFF , WDT = OFF , PWRT = ON , BOREN = SBORDIS
#pragma config PBADEN = OFF ,CP1 = OFF ,CP2 = OFF , CP3 = OFF ,  CPB = OFF, WRTC = OFF
#pragma config WRTB = OFF

volatile unsigned char x=0;
unsigned short y=0;

void INT(void);
void delay(unsigned long gecikme);
void _24C02_yaz(unsigned char veri,unsigned char wadres);
unsigned char _24C02_oku(unsigned char wadres);

void main(void)
{
    unsigned char veri=0;
	ADCON1 &= 0x0F;				//Tüm AN pinleri dijital.
	TRISD=0x00;
	TRISA=0x00;
	TRISCbits.TRISC7=0;
	TRISBbits.TRISB0=1;
	LATCbits.LATC7=0;
	LATD=0;
	LATA=0;

	INTCONbits.INT0IE=1;
	INTCONbits.INT0IF=0;
	INTCON2bits.INTEDG0=1;
	INTCONbits.GIE=1;
	INTCONbits.PEIE=1;

	i2c_init(NORMAL,MASTER);
	lcd_init();
	lcd_clear();
	cursor(1,1);
	lcd_send_data('V');lcd_send_data('E');lcd_send_data('R');
	lcd_send_data('I');
	lcd_send_data(':');
        /*
        _24C02_yaz('Y',0x08);
        _24C02_yaz('A',0x18);
        lcd_send_data(_24C02_oku(0x08));
        lcd_send_data(_24C02_oku(0x18));
        delay(0x00000FFF);
        LATCbits.LATC7=1;*/
        i2c_start();
        i2c_write(0xA0);
        i2c_write(0x80);
        i2c_write('N');
        i2c_stop();
        delay(0x00005FFF);
        i2c_start();
        i2c_write(0xA0);
        i2c_write(0x88);
        i2c_write('A');
        i2c_stop();
        delay(0x00005FFF);
        i2c_start();
        i2c_write(0xA0);
        i2c_write(0x90);
        i2c_write('Z');
        i2c_stop();
        delay(0x00005FFF);
        i2c_start();
        i2c_write(0xA0);
        i2c_write(0x98);
        i2c_write('I');
        i2c_stop();
        delay(0x00005FFF);
        i2c_start();
        i2c_write(0xA0);
        i2c_write(0xA0);
        i2c_write('M');
        i2c_stop();
        delay(0x00005FFF);
        lcd_send_data(_24C02_oku(0x80));
        lcd_send_data(_24C02_oku(0x88));
        lcd_send_data(_24C02_oku(0x90));
        lcd_send_data(_24C02_oku(0x98));
        lcd_send_data(_24C02_oku(0xA0));
	for(;;)
	{
		if(x==1)
		{
                    cursor(1,7);
                    lcd_send_data(_24C02_oku(0x18));
                    delay(0x00000FFF);
                    lcd_send_data(_24C02_oku(0x08));
                    delay(0x00000FFF);
		}
                else if(x==2)
                {
                    _24C02_yaz('B',0x70);              //A
                    cursor(2,1);
                    lcd_send_data(_24C02_oku(0x70));
                    delay(0x00000FFF);
                }
                else if(x==3)
                {
                    cursor(2,10);
                    lcd_send_data(_24C02_oku(0x90));
                    delay(0x00000FFF);
                    x=0;
                }
	}

}

void _24C02_yaz(unsigned char veri,unsigned char wadres)
{
	i2c_start();
	i2c_write(0xA0);
	i2c_write(wadres);
	i2c_write(veri);
	i2c_stop();
	delay(0x00006FFF);
}
unsigned char _24C02_oku(unsigned char wadres)
{
    unsigned char i2c_veri;
	i2c_start();
	i2c_write(0xA0);
	i2c_write(wadres);
	i2c_restart();
        i2c_write(0xA1);
        i2c_veri=i2c_read();
	i2c_stop();
        return i2c_veri;
	delay(0x00006FFF);
}
void delay(unsigned long gecikme)
{
	while(gecikme--);
}

#pragma code Interrupt_Vector_High = 0x08
void Interrupt_Vector_High(void)
{
	_asm
		goto INT
	_endasm
}
#pragma code

#pragma interrupt INT
void INT(void)
{
	if(INTCONbits.INT0IF)
	{
            INTCONbits.INT0IF=0;
            x++;
            if(x==1)
                LATCbits.LATC7=0;
            else if(x==2)
                LATCbits.LATC7=1;
	}
}


i2c.c
#include <p18f4520.h>
#include "i2c.h"

void i2c_init(unsigned short hizsec,unsigned short type)
{
    TRISCbits.TRISC3=1;             //SCL input open drain
    TRISCbits.TRISC4=1;             //SDA input open drain
    SSPCON1bits.SSPEN=1;            //RC3,RC4 i2c için ayarlandı.
    SSPCON1bits.WCOL=0;             //ilk anda veri çakışma yok.
    SSPCON1bits.SSPOV=0;            //ilk anda overflow yok.
    //I2C cihaz modu seçiliyor.
    SSPCON1 = (0x0F & (SSPCON1 | type));

    SSPCON2bits.ACKEN=1;            //ACKDT donanım tarafından temizlencek SCL,SDA da.
    
    if(hizsec)
        SSPSTATbits.SMP=0;      //400khz
    else
        SSPSTATbits.SMP=1;      //100khz

    SSPSTATbits.CKE=0;          //SMBus iptal.
    SSPSTATbits.BF=0;           //Buffer temizleniyor.
    SSPADD=0x63;                //Fosc=10MHz , 100Khz lik haberlesme için Baundrate ayarlanıyor.
                                //SSPADD cihaz master ise Baundrate degerini tutar
                                //Slave ise cihazın slave adresini buraya yazarız
                                //istediğimiz bir adresi atayabiliriz.
}
void i2c_start(void)
{
    i2c_wait();
    SSPCON2bits.SEN=1;              //Start verildi.
    i2c_wait();
}
void i2c_stop(void)
{
    i2c_wait();
    SSPCON2bits.PEN=1;              //Stop verildi.
    i2c_wait();
}
void i2c_restart(void)
{
    i2c_wait();
    SSPCON2bits.RSEN=1;             //restart verildi.
    i2c_wait();
}
void i2c_write(unsigned char data)
{
    i2c_wait();
    if(SSPCON1bits.WCOL)
        SSPCON1bits.WCOL=0;
    SSPBUF=data;
    i2c_wait();
    SSPSTATbits.BF=0;               //Bufferı temizle
}
unsigned char i2c_read(void)
{
    unsigned char gecici;
    SSPCON2bits.RCEN=1;         //Alıcı mod aktif
    i2c_wait();
    gecici=SSPBUF;
    delay_i2c(0x0FFF);
    if(SSPSTATbits.BF)
    {
        SSPSTATbits.BF=0;
        return gecici;
    }
    else if(SSPCON1bits.SSPOV)
    {
        SSPCON1bits.SSPOV=0;
        return 0;
    }
}
void i2c_wait(void)
{
    while(SSPSTAT&0x04);       //Hat idle durumuna geçene kadar bekle.RW biti
}
void delay_i2c(unsigned int delay)
{
    while(delay--);
}


i2c.h
#define FAST 1
#define NORMAL 0
#define ACK     SSPCON2bits.ACKSTAT
#define ACKDT   SSPCON2bits.ACKDT
#define MASTER  8                   //1000 = I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))
#define SLAVE7bit   6               //0110 = I2C Slave mode, 7-bit address
#define SLAVE10bit  7               //0111 = I2C Slave mode, 10-bit address
//Birkac mod daha var şimdilik gerek yok onlara.

extern void i2c_init(unsigned short hizsec,unsigned short type);
extern void i2c_start(void);
extern void i2c_stop(void);
extern void i2c_restart(void);
extern void i2c_write(unsigned char data);
extern unsigned char i2c_read(void);
extern void i2c_wait(void);
extern void delay_i2c(unsigned int delay);





video ve resim : http://hotfile.com/dl/118029461/eb4095c/Desktop.rar.html


İlk denenemde 24C02'nin 0x00 adresine N harfini yazıp okumustum, fakat diğer denemelerimde eeproma yazdığım değerleri düzgün okumayamadım fotorafda gözüküyor.

izwirlee_35

ack yı hiç kontrol etmemişsin galiba
keep learning . . .

yamak

i2c_wait in içini şu şekilde değiştirir misiniz?
while ( ( SSPCON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );