Giao tiếp I2C với EEPROM 24C02

naebolo

Thành Viên PIF
Chào mọi người. Mình đang gặp một số vấn đề trong giao tiếp I2C với EEPROM 24C02.

code như sau:
i2c.c:
Code:
#include <htc.h>
#include "i2c.h"
 
void i2c_start(){
    SEN = 1;
    while(SEN);//wait the required start time before any other operation takes place.
}
void i2c_stop(){
    PEN = 1;
    while(PEN);
}
unsigned char i2c_read(unsigned char ack){
    RCEN = 1;
    while(RCEN);
    ACKDT = ack;
    ACKEN = 1;
    while(ACKEN);
    while(!BF);        //Byte Full is set when SSPSR are loaded into the SSPBUF, automatically cleared when the buffer is read by the CPU
    return SSPBUF;
}
unsigned char i2c_write(unsigned char d){
    WCOL = 0;    //Clear WCOL to indicate to be able to write.
    SSPIF = 0;
    SSPBUF = d;
    asm("nop");
    asm("nop");
    asm("nop");
    if(WCOL) return 2;            // write collision
    else {
        while(!SSPIF);
        if(ACKSTAT) return 1;    // not acknowledge
        return 0;                // everything is ok
    }
}
 
void i2c_init(){
 
    RC3 = 1;
    RC4 = 1;
    TRISC3 = 1;
    TRISC4 = 1; //    control by mssp
 
    SSPADD = 9;        // Baudrate = Fosc/4/(SSPADDR+1)
    SMP = 1;        // slew rate control disabled for 100KHz baudrate
    SSPCON2 = 0; 
    SSPCON = 0x28; //I2C Master Hardware mode
}
chương trình chính: main.c

Code:
/*********************************************************************
*
*    MAIN
*
*********************************************************************
* FileName:        Main.c
* Processor:      PIC16
* Writer:            Naebolo
* Time:            20/07/12 
********************************************************************/
#include "LCD.h"
#include "NaeboloUART.h"
#include "i2c.h"
#include <htc.h>
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN & IESODIS & FCMDIS & LVPDIS & DEBUGDIS); //1st config. Word
__CONFIG(BORV21);
#define _XTAL_FREQ    4000000
#define PointLed 0b00100000
 
void NaeboloInit(void);
 
long NAEnumber;
 
 
void write_ext_eeprom_4byte(unsigned char address, long data){
    unsigned char temp;
    i2c_start();
    i2c_write(0xa0);
    i2c_write(address);
    temp = data & 255;
    i2c_write(temp);
    temp = (data >> 8) & 255;
    i2c_write(temp);
    temp = (data >> 16) & 255;
    i2c_write(temp);
    temp = (data >> 24) & 255;
    i2c_write(temp);
    i2c_stop();
} 
 
long read_ext_eeprom_4byte(unsigned char address){
    long temp;
    long value;
    i2c_start();
    i2c_write(0xa0);
    //Send register address (register of Slave – the first register need to read data)
    i2c_write(address);                                    //resister first
    i2c_stop();
    i2c_start();                                 
    i2c_write(0xa1);
    value = i2c_read(0);
    temp = 0;
    temp = i2c_read(0);
    value = value | (temp << 8);
    temp = 0;
    temp = i2c_read(0);
    value = value | (temp << 16);
    temp = 0;
    temp = i2c_read(1);                                    //read end-byte and finish read
    value = value | (temp << 24);                     
    i2c_stop();                                            //end read
    return value;
}
 
void main(void){
    long k, numbertmp, i, j; 
    unsigned char abc;
 
    NaeboloInit();
 
    NAEnumber = 123456;
    write_ext_eeprom_4byte(0, NAEnumber);
    NAEnumber = 0;
    NAEnumber = read_ext_eeprom_4byte(0);
    while(1){
    } 
}
 
void NaeboloInit(){
    ANSEL = 0;
    ANSELH = 0;    //Config all port that is digital
 
    //SSPSTAT
    SMP = 1; // data in sampled at middle
    CKE = 1; // data out at rising edge (with CKP = 0)
    //SSPCON
    SSPCON = 0b00100000;    // CKP = 0, SPI mode baudrate = Fosc/4
 
    //External Interrupt Config
    INTF = 0;
    INTEDG = 0;
    INTE = 1;
 
    //LCD INIT
    lcd_init();
 
    //UART INIT
    uart_init();
    //I2C INIT
    i2c_init();
    //UART INTERRUPT
    RCIE = 1;
    PEIE = 1;
    GIE = 1;
}
Lỗi như sau:

- Nếu trong hàm main mình chạy debug từng dòng lệnh thì quá trình ghi và đọc ok?
Ghi giá trị NAEnumber = 123456 vào EEPROM rồi đọc ra đúng giá trị 123456.
- Nhưng nếu để cho nó chạy một mạch thì có 2 trường hợp xảy ra:
+ Nó sẽ bị đứng tại vòng "while(ACKEN);" hoặc "while(!SSPIF);" trong i2c.c.
+ Đọc được giá trị là NAEnumber = 0b1111111....111

Ai có kinh nghiệm chỉ giúp.

Thanks and best regards,
 

tungbk

Cố Vấn CLB
Staff member
Trong con EEPROM này có cái Write Cycle Timing là 5ms. Mỗi lần ghi xong thì phải delay >=5ms rồi thì mới làm tiếp được. Lợi thêm cái delay xem sao.
 
Top