Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => Picproje Kütüphane (Library) => Konuyu başlatan: XX_CİHAN_XX - 26 Ağustos 2009, 12:39:10

Başlık: MSSP - I2C versiyon 2 [Detaylı Bilgi]
Gönderen: XX_CİHAN_XX - 26 Ağustos 2009, 12:39:10

ÖRNEK KULLANIM ŞEKİLLERİ:
// 0x1010 ADRESİNE 0x04, 0x1011 ADRESİNE 0x02 DATASINI YAZAR
while(WRITE24C512_INT(0x1010, 0x402)); //INT TÜRÜNDE DATA YAZMA ÖRNEĞİ
// 0x1010 ADRESİNE 0x40 DATASINI YAZAR
while(WRITE24C512_CHAR(0x1012, 0x40)); //CHAR TÜRÜNDE DATA YAZMA ÖRNEĞİ

//YAKLAŞIK 600uS DE INT TÜRÜNDEN DATAYI OKUR
INT_DATA = READ24C512_INT(0x1010); //0x1010 VE 0x1011 ADRESLERİNDEKİ 2 BYTE LIK DATAYI OKUR
//YAKLAŞIK 500uS DE CHAR TÜRÜNDEN DATAYI OKUR
CHAR_DATA = READ24C512_CHAR(0x1012); //1012 ADRESİNDEKİ 1 BYTE LIK DATAYI OKUR

// BİR BAŞKA OKUMA ŞEKLİ!
INT_DATA = READ24C512_INT(0x1010); //0x1010 VE 0x1011 ADRESLERİNDEKİ 2 BYTE LIK DATAYI OKUR
if(INT_DATA==0xFFFF) //okuma hatalı yada boş bölgede mi
goto HATA; //evet ise değerlendirme yapma
.....
CHAR_DATA = READ24C512_CHAR(0x1012); //1012 ADRESİNDEKİ 1 BYTE LIK DATAYI OKUR
if(CHAR_DATA==0xFF) //okuma hatalı yada boş bölgede mi
goto HATA; //evet ise değerlendirme yapma
.....



#include <pic.h>

#define _XTAL_FREQ 20000000 //kristal frekansı
#define ACK 0 //Bilgi kabul edildi tanımlaması
#define NACK 1 //Bilgi kabul edilemedi tanımlaması
#define BAUD 100 //I2C baud rate 100Kbps
#define FOSC (_XTAL_FREQ / 1000) //Khz cinsinden osilatör
#define SSPAD_VALUE ((FOSC / (4 * BAUD)) - 1) //I2C clock frekansı

void I2CInit (void)
{
PORTC &= 0b11100111; //SCL ve SDA Clear edildi
TRISC |= 0b00011000; //i2c için SLC ve SDA pinleri giriş yapıldı
SSPCON = 0b00101000; //Master MODE, clock = FOSC/(4 * (SSPADD + 1))
SSPSTAT = 0b10000000; //standart hız (clock = 100Khz)
SSPADD = SSPAD_VALUE; //Kristal frekansına göre gerekli değeri yükle
SSPIF = 0; //I2C kesme bayrağı temizlendi
}
void I2CSTOP (void)
{
PEN = 1; //STOP biti gönder
while(PEN); //stop bitinin tamamlanmasını bekle
}
bit I2CSendByte (unsigned char data)
{
SSPIF = 0;
SSPBUF = data; //1 byte lık veriyi gönder
if(WCOL) //YAZIM ÇAKIŞMASI OLDU MU
WCOL = 0; //OLDUYSA TEMİZLE
while(!SSPIF); //Buffer ın boşalmasını bekle

if(ACKSTAT) //NACK cevabı mı alındı ?
{
I2CSTOP();
return 1; //hata kodunu döndür
}
return 0; //HATASIZ GONDERILDI
}
void I2CSTART (void)
{
SEN = 1; //Start bitini gönder
while(SEN); //Start bitinin tamamlanmasını bekle
}
bit WRITE24C512_CHAR (unsigned int adr, unsigned char dt)
{
I2CSTART();
if(I2CSendByte(0xA0)) //device adresi gönder
return 1; //gönderme hatası varsa çık
if(I2CSendByte(adr>>8)) //adres üst baytını gönder
return 1; //gönderme hatası varsa çık
if(I2CSendByte(adr)) //adres alt baytını gönder
return 1; //gönderme hatası varsa çık
if(I2CSendByte(dt)) //datayı gönder
return 1; //gönderme hatası varsa çık
I2CSTOP();
return 0;
}
bit WRITE24C512_INT (unsigned int adr, unsigned int dt)
{
I2CSTART();
if(I2CSendByte(0xA0)) //device adresi gönder
return 1; //gönderme hatası varsa çık
if(I2CSendByte(adr>>8)) //adres üst baytını gönder
return 1; //gönderme hatası varsa çık
if(I2CSendByte(adr)) //adres alt baytını gönder
return 1; //gönderme hatası varsa çık
if(I2CSendByte(dt>>8)) //datayı gönder (high byte)
return 1; //gönderme hatası varsa çık
if(I2CSendByte(dt)) //datayı gönder (low byte)
return 1; //gönderme hatası varsa çık
I2CSTOP();
return 0;
}
void I2CRESTART (void)
{
RSEN = 1; //Restart yolla
while(RSEN); //Restart sinyalinin bitmesini bekle
}
void READSTART (void)
{
RCEN = 1; //Okuma moduna geç
while(RCEN); //Datanın alınmasını bekle
if(SSPOV) //TAŞMA HATASI VAR MI ?
SSPOV = 0; //VARSA TEMİZLE
while(!BF); //veri alımının tamamlanmasını bekle
}
void SENDACKNACK (char b)
{
ACKDT = b; //NACK GONDERILEREK ISLEM SONLANIYOR
ACKEN = 1; //ACK DATA GONDERILIYOR
while(ACKEN); // işlemin tamamlanmasını bekle
}
//1 BYTE LIK DATA OKUR VE CHAR TIPINDE DEĞER DÖNDÜRÜR
unsigned char READ24C512_CHAR (unsigned int adr)
{
unsigned char _data;
I2CSTART();
if(I2CSendByte(0xA0)) //device adresi gönder
return 0xFF; //gönderme hatası varsa çık
if(I2CSendByte(adr>>8)) //adres üst baytını gönder
return 0xFF; //gönderme hatası varsa çık
if(I2CSendByte(adr)) //adres alt baytını gönder
return 0xFF; //gönderme hatası varsa çık
I2CRESTART();
if(I2CSendByte(0xA1)) //Okuma bilgisini gönder
return 0xFF; //gönderme hatası varsa çık
READSTART();
_data = SSPBUF;
SENDACKNACK(NACK);
I2CSTOP();
return _data; //Okunan datayı geri döndür
}
//2 BYTE LIK DATA OKUR VE INT TIPINDE DEĞER DÖNDÜRÜR
unsigned int READ24C512_INT (unsigned int adr)
{
unsigned int _GETDATA = 0;
I2CSTART();
if(I2CSendByte(0xA0)) //device adresi gönder
return 0xFFFF; //gönderme hatası varsa çık
if(I2CSendByte(adr>>8)) //adres üst baytını gönder
return 0xFFFF; //gönderme hatası varsa çık
if(I2CSendByte(adr)) //adres alt baytını gönder
return 0xFFFF; //gönderme hatası varsa çık
I2CRESTART();
if(I2CSendByte(0xA1)) //Okuma bilgisini gönder
return 0xFFFF; //gönderme hatası varsa çık
READSTART();
_GETDATA = SSPBUF; //ILK OKUNAN DATAYI AL
_GETDATA = _GETDATA << 8;
SENDACKNACK(ACK);
READSTART();
_GETDATA += SSPBUF; //IKINCI OKUNAN DATAYI AL VE ILKI ILE BIRLESTIR
SENDACKNACK(NACK);
I2CSTOP();
return _GETDATA; //Okunan datayı geri döndür
}


I2C VE MSSP MODÜLÜ İLE İLGİLİ ÖNEMLİ BİLGİLER
I2C MSSP MODÜLÜNDE 6 ADET REGİSTER KULLANILIR
SSPCON  -> MSSP CONTROL REGİSTERİ
SSPCON2 -> MSSP CONTROL REGİSTERİ 2
SSPSTAT   -> MSSP STATUS REGISTERI
SSPBUF   -> SERIAL RECIEVE / TRANSMIT BUFFER
SSPSR   -> MSSP SHIFT REGISTER (direk erişim imkanı yoktur)
SSPADD   -> MSSP ADDRESS REGISTER

WCOL biti yazım çakışması bitidir.
MASTER GÖNDERME MODUNDA:
I2C durumu yazım için uygun olmadığı halde SSPBUF kaydedicisine
yazılmaya çalışılırsa çakışma ortaya çıkar ve bu bit SET olur.
Yazılım içersinde temizlenmelidir.
Bit CLEAR ise çakışma yoktur.

SSPOV biti alma taşmasını gösterir.
ALMA MODUNDA:
Bu bit SET ise SSPBUF kaydedicisinde önceki veri henüz işlenmemişken
yeni veri gelmiştir. Bu bit veri taşmasını gösterir. Yazılım içinde
temizlenmelidir. Bit Clear ise taşma yoktur.

BF biti BUFFER doluluk oranını gösterir (Sadece okunabilir)
BF biti SET olduğu zaman SSPBUF dolmuştur ve okunmak zorundadır.
Bu bit set olduğu zaman SSPBUF ın içinde henüz okunmamış bir data var demektir.
SSPBUF taki data okunmadan önce, buraya her hangi bir data gönerilmemeli yada alınmamalıdır.


ACKSTAT biti, SLAVE aygıttan gönderilen ACK yada NACK bilgisini içerir.
SLAVE aygıt her bir BYTE transferinden sonra ACK yada NACK bilgisini gönderir.

ACKDT biti, MASTER aygıt I2C (SLAVE)aygıtına ACK yada NACK bilgisi göndereceği zaman kullanılır.
Bu bite yüklenen "0" ACK, "1" NACK anlamını taşımaktadır.

ACKEN biti SET edilerek ACKDT bitine yüklenen ACK yada NACK bilgisi gönderilir.

RCEN biti set edilerek I2C aygıtı alma moduna geçilir.
RCEN biti bir byte lık data alındıktan sonra otomatik olarak CLEAR olur!
Alınacak her bir BYTE için bu bit tekrardan set edilmelidir.

PEN biti SET edilince STOP biti gönderilmiş olur. Gönderme işlemi
tamamlanınca bu bit otomatik olarak CLEAR olur.

RSEN biti SET edilince RESTART sinyali gönderilir. İşlem tamamlanınca
bu bit otomatik olarak CLEAR olur.

SEN biti SET edilince START sinyali gönderilir. İşlem tamamlanınca
bu bit otomatik olarak CLEAR olur.

İyi Çalışmalar.