Hello everybody.
I'm trying to operate a 24LC256 EEPROM with a PICDEM 2 board. Since I'm new on PIC and I2C bus, with the program below, I have some problems:
1. The data I got was always constant (0x01) whatever the memory address was.
2. The ACKEN bit was never cleared by the hardware for NACK sending sequences. So the program could never reach the i2c_stop() function of a read operation.
I compared my program with those I found on internet, there were no significant differences. Moreover, I had exactly the same problems when I operated a TC74A5 temperature sensor except that the constant value was different.
Could anybody be kind enough to figure out the errors for me? Thank you very much in advance!!!
Hardware: Microchip PICDEM 2 plus (24LC256 and TC74 on board) + PIC18F4520
Software: MPLAB IDE 8.3 + HI-TECH PICC18 compiler
Program:
I'm trying to operate a 24LC256 EEPROM with a PICDEM 2 board. Since I'm new on PIC and I2C bus, with the program below, I have some problems:
1. The data I got was always constant (0x01) whatever the memory address was.
2. The ACKEN bit was never cleared by the hardware for NACK sending sequences. So the program could never reach the i2c_stop() function of a read operation.
I compared my program with those I found on internet, there were no significant differences. Moreover, I had exactly the same problems when I operated a TC74A5 temperature sensor except that the constant value was different.
Could anybody be kind enough to figure out the errors for me? Thank you very much in advance!!!
Hardware: Microchip PICDEM 2 plus (24LC256 and TC74 on board) + PIC18F4520
Software: MPLAB IDE 8.3 + HI-TECH PICC18 compiler
Program:
Code:
[COLOR="Navy"]#include <pic18.h>
__CONFIG(1,IESODIS & FCMDIS & XT);
/* Clock switchover disabled
Fail-Safe Mode disabled
External Crystal oscillator */
__CONFIG (2, BORDIS & PWRTEN & WDTDIS);
/* Brown-out Reset disabled
Power-up Timer disabled (for ICD2 debugger)
Watch Dog disabled */
__CONFIG (3, MCLREN & LPT1DIS & PBDIGITAL);
/* Master Clear enabled
Timer1 Low Power Mode disabled
PortB 0:4 configured as digital */
__CONFIG (4, DEBUGEN & LVPDIS);
/* ICD enabled
LV ICSP disabled
Stack Full/Overflow Reset enabled (default)
Extended Instruction disabled (default) */
/* Code/Write/Read Protection bits
__CONFIG (5, );
__CONFIG (6, );
__CONFIG (7, );
Default Values : No protections */
#define WADD 0b10100000 //1001101+0 write
#define RADD 0b10100001 //1001101+1 read
void init()
{
[INDENT] GIE =0; //Disable all interrupts
//**********************************************
TRISC3 =1; //RC3 as INPUT (SCL)
TRISC4 =1; //RC4 as INPUT (SDA)
//**********************************************
//MSSP Configuration
SSPCON1 =0x28; //Enable MSSP in I2C Master mode
SSPCON2 =0;
SMP =1; //Disable slew rate control
CKE =0; //I2C compatible
SSPADD =0x09; //Fscl = 100kHz pour Fosc=4MHz
//Fscl = Fosc/(4*(SSPADD+1))[/INDENT]
}
void i2c_idle() //Wait until the bus is idle
{
[INDENT] while ((SSPCON2 & 0x1F) | RW);[/INDENT]
}
void i2c_start()
{
[INDENT] SEN =1; //Start Sequence[/INDENT]
}
void i2c_stop()
{
[INDENT] PEN =1; //Stop Sequence[/INDENT]
}
void i2c_restart()
{
[INDENT] RSEN =1; //Restart Sequence[/INDENT]
}
void i2c_nack()
{
[INDENT] ACKDT =1;
ACKEN =1; //Start not acknowledge sequence[/INDENT]
}
void i2c_ack()
{
[INDENT] ACKDT =0;
ACKEN =1; //Start acknowledge sequence[/INDENT]
}
void i2c_write(unsigned char data)
{
[INDENT] SSPBUF =data; //Write data or command or address + R/W bit
i2c_idle(); //Wait for the end of write (RW cleared)
while (ACKSTAT); //Wait for ACK from slave[/INDENT]
}
unsigned char i2c_read ()
{
[INDENT] RCEN =1; //Receive data
i2c_idle(); //Waiting for the end of read (RCEN cleared)
return (SSPBUF);[/INDENT]
}
void main ()
{
[INDENT] unsigned char temp=0,i;
init();
while (1)
{
[INDENT] //write (page write)
i2c_start();
i2c_idle();
i2c_write(WADD); //EEPROM selected in write mode
i2c_write(0x00); //Address HIGH
i2c_write(0x00); //Address LOW
for (i=1;i<5;i++)
[INDENT] i2c_write(i+1); //Page write (4 bytes)[/INDENT]
i2c_idle();
i2c_stop();
i2c_idle();
delay_ms(50); //EEPROM executing internal writing cycles
//read (sequential read)
i2c_start();
i2c_idle();
i2c_write(WADD); //EEPROM selected in write mode
i2c_write(0x00); //Address HIGH
i2c_write(0x00); //Address LOW
i2c_restart();
i2c_idle();
i2c_write(RADD); //EEPROM selected in read mode
for (i=1;i<5;i++)
{
[INDENT] temp=i2c_read();
if (i==4)
i2c_nack(); //NACK before STOP
else
i2c_ack(); //ACK for next read
i2c_idle();[/INDENT]
}
i2c_stop();
i2c_idle();[/INDENT]
}[/INDENT]
}[/COLOR]
Last edited: