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:
chương trình chính: main.c
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,
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
}
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;
}
- 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,