• AVR Freaks

Hot!External EEPROM(ATC024) interface with PIC24EP256GP206

Page: 12 > Showing page 1 of 2
Author
Gouthami c v
Starting Member
  • Total Posts : 79
  • Reward points : 0
  • Joined: 2019/07/11 01:55:44
  • Location: 0
  • Status: offline
2019/09/11 04:34:56 (permalink)
0

External EEPROM(ATC024) interface with PIC24EP256GP206

I am using external eeprom (at24c04d) to interface with pic24ep256gp206 to read and write data, for this i have written simple code to store character A to Z, and to display same on UART.
here is my code

 
/* 
* File: MAIN.c
* Author: gouthami
*
* Created on September 10, 2019, 12:10 PM
*/
 
// PIC24EP256GP206 Configuration Bit Settings
 
// 'C' source line config statements
 
// FICD
#pragma config ICS = PGD2 // ICD Communication Channel Select bits (Communicate on PGEC2 and PGED2)
#pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
 
// FPOR
#pragma config ALTI2C1 = OFF // Alternate I2C1 pins (I2C1 mapped to SDA1/SCL1 pins)
#pragma config ALTI2C2 = OFF // Alternate I2C2 pins (I2C2 mapped to SDA2/SCL2 pins)
#pragma config WDTWIN = WIN25 // Watchdog Window Select bits (WDT Window is 25% of WDT period)
 
// FWDT
#pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits (1:32,768)
#pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit (1:128)
#pragma config PLLKEN = OFF // PLL Lock Enable bit (Clock switch will not wait for the PLL lock signal.)
#pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = ON // Watchdog Timer Enable bit (Watchdog timer always enabled)
 
// FOSC
#pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
#pragma config OSCIOFNC = OFF // OSC2 Pin Function bit (OSC2 is clock output)
#pragma config IOL1WAY = ON // Peripheral pin select configuration (Allow only one reconfiguration)
#pragma config FCKSM = CSDCMD // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are disabled)
 
// FOSCSEL
#pragma config FNOSC = FRC // Oscillator Source Selection (Internal Fast RC (FRC))
#pragma config IESO = OFF // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
 
// FGS
#pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written)
#pragma config GCP = OFF // General Segment Code-Protect bit (General Segment Code protect is Disabled)
 
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
 
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _XTAL_FREQ 7370000UL
#define FP 3685000UL
#define BAUDRATE 9600
#define BRGVAL ((FP/BAUDRATE)/16)-1
#include <libpic30.h> //for delay routines#
#include "AT24C04DEEPROM.h"
#include "uart.h"
#define SDA SDA2
#define SCL SCL2
int main(void)
{
//TRISC=0x3FFF;
char buffer[40]; //array to hold the strin
unsigned char read_int,write_int;
 
char address=0, byte_High, byte_Low;
uart_init();
I2CInit();
while (1)
 
{
for(write_int='A';write_int<='Z';write_int++)
{

sprintf(buffer,"\n\rFlash Write: %c ",write_int); //Print the message on UART
uartputs(buffer); // output the string we created 
I2CWriteReg(address, byte_High, byte_Low,write_int); // Write the data at

read_int=I2CReadReg(address, byte_High, byte_Low); // Read the data from memoryLocation 0x00
sprintf(buffer,"Flash Read: %c",read_int); //transmit the data read from Eeprom
uartputs(buffer);// output the string we created

}

}
return 1;
}
 

EEPROM code

 
/* 
* File: AT24C04DEEPROM.h
* Author: gouthami
*
* Created on September 10, 2019, 12:03 PM
*/
 
void I2CInit(void)
{
I2C2BRG = 0x23; // Baud Rate Generator Value: I2CBRG 35; 
I2C2CONbits.I2CEN = 0; // Disable I2C
I2C2CONbits.DISSLW = 1; // Disable slew rate control
I2C2CONbits.A10M = 0; // 7-bit slave addr
I2C2CONbits.SCLREL = 1; // SCL release control
I2C2CONbits.I2CEN = 1; // Enable I2C
IFS3bits.MI2C2IF = 0;
// enable the master interrupt
IEC3bits.MI2C2IE = 0;
}

void I2CAck(void)
{
I2C2CONbits.ACKDT = 0; // Send ACK
I2C2CONbits.ACKEN = 1; // Initiate Acknowledge and transmit ACKDT
while(I2C2CONbits.ACKEN);
}

void I2CNack(void)
{
I2C2CONbits.ACKDT = 1; // Send NACK
I2C2CONbits.ACKEN = 1; // Initiate Acknowledge and transmit ACKDT
while(I2C2CONbits.ACKEN); 
}

void I2CStop(void)
{
I2C2CONbits.RCEN = 0; // receive mode not in progress
I2C2CONbits.PEN = 1; // Stop condition
while(I2C2CONbits.PEN);
}

void I2CStart(void)
{
I2C2CONbits.ACKDT = 0; // Reset any ACK
I2C2CONbits.SEN = 1; // Start
while(I2C2CONbits.SEN);
}

void I2CRestart(void)
{
I2C2CONbits.RSEN = 1; // Repeated Start Condition
while(I2C2CONbits.RSEN);
I2C2CONbits.ACKDT = 0; // Send ACK
I2C2STATbits.TBF = 0; // I2C1TRN is empty
}

void I2CWaitACK(void)
{
while(I2C2STATbits.ACKSTAT);
}

void I2CIdle(void)
{
while(I2C2STATbits.TRSTAT);
}

void I2CWrite(unsigned char c)
{
I2C2TRN = c;
while(I2C2STATbits.TBF);
}

void I2CRead(void)
{
I2C2CONbits.RCEN = 1;
Nop();
while(!I2C2STATbits.RBF);
}

void I2CWriteReg(char addr, char byteHigh, char byteLow, char value)
{
// Start Condition
I2CStart();
// EEPROM Addr
I2CWrite((addr<<1)&0xFE);
I2CIdle();
// Addr High Byte
I2CWrite(byteHigh);
I2CIdle();
// Addr Low Byte
I2CWrite(byteLow);
I2CIdle();
// Value
I2CWrite(value);
I2CIdle();
// Stop
I2CStop();
}


char I2CReadReg(char addr, char byteHigh, char byteLow)
{
char temp;
// Start Condition
I2CStart();
// EEPROM Addr
I2CWrite((addr<<1)&0xFE);
I2CIdle();
// Addr High Byte
I2CWrite(byteHigh);
I2CIdle();
// Addr Low Byte
I2CWrite(byteLow);
I2CIdle();
// Restart
I2CRestart();
I2CWrite((addr<<1)|0x01);
I2CIdle(); 
I2CRead();
I2CNack();
I2CStop();
temp = I2C2RCV;
return temp;
}
 

Uart code

 
void uart_init(void)
{

/** 
Set the UART1 module to the options selected in the user interface.
Make sure to set LAT bit corresponding to TxPin as high before UART initialization
*/
// STSEL 1; IREN disabled; PDSEL 8N; UARTEN enabled; RTSMD disabled; USIDL disabled; WAKE disabled; ABAUD disabled; LPBACK disabled; BRGH enabled; URXINV disabled; UEN TX_RX; 
// Data Bits = 8; Parity = None; Stop Bits = 1;
U1MODE = (0x8008 & ~(1<<15)); // disabling UARTEN bit
// UTXISEL0 TX_ONE_CHAR; UTXINV disabled; OERR NO_ERROR_cleared; URXISEL RX_ONE_CHAR; UTXBRK COMPLETED; UTXEN disabled; ADDEN disabled; 
U1STA = 0x00;
// BaudRate = 9600; Frequency = 3685000 Hz; BRG 95; 
U1BRG = 0x5F;

U1MODEbits.UARTEN = 1; // enabling UART ON bit
U1STAbits.UTXEN = 1;
 
/****************************************************************************
* Set the PPS
***************************************************************************/
__builtin_write_OSCCONL(OSCCON & 0xbf); // unlock PPS
 
RPOR0bits.RP20R = 0x0001; //RA4->UART1:U1TX
RPINR18bits.U1RXR = 0x0019; //RA9->UART1:U1RX
 
__builtin_write_OSCCONL(OSCCON | 0x40); // lock PPS
 
//END UART SETUP 
}


 
//send one character to UART1
void uartputc(char temp)
{
while(U1STAbits.UTXBF); //transmit only if TX buffer is empty
U1TXREG = temp;
}
//send a string to uart1
void uartputs(char *buf)
{
while (*buf) // loop while we haven't hit the terminal NULL
uartputc(*buf++); //send this character, then advance the pointer
}
 

problem is i am getting only write data,not getting read data in uart could u tell me where i am going wrong. 
Thanking you.
 
#1

26 Replies Related Threads

    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/11 04:42:24 (permalink)
    0
    I have attached uart output what i have got.
    #2
    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/11 06:01:41 (permalink)
    0
    Gouthami c v
    I have attached uart output what i have got.

    Where?
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #3
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/11 21:18:54 (permalink)
    0
    sorry i am not able to attach,it was showing some error,now i uploaded
     
     
     
     
     
    Thank you.
    post edited by Gouthami c v - 2019/09/11 21:22:49

    Attached Image(s)

    #4
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/12 01:57:49 (permalink)
    0
    I need help please help me i am not getting read data,could someone tell what is the issue.
     
    #5
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/15 21:22:08 (permalink)
    0
    hi  can anyone help me please i have struggling from last one week to resolve this problem. Please help me.
     
     
     
     
     
    #6
    davekw7x
    Entropy++
    • Total Posts : 1827
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Second star on the right, straight on till morning
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/16 08:18:02 (permalink)
    5 (3)
    Gouthami c v
    ...help...



    I have been in read-only mode for the last few days.  Have not been able to do any testing, and I just about never post specific suggestions until and unless I am able to test.  (Even though, in this case, I am resurrecting old code that I know "used to work," I want to make sure it still works after all these years.)

    First of all: The I2C code you posted is simply wrong, wrong, wrong for accessing memory in a 24C04 device.  The routines themselves might (or might not) work for certain devices, but you certainly don't call them correctly in any case.  I'm guessing that you didn't write the routines, and I'm wondering just what, exactly, you expected to happen.
     
    Anyhow...
     
    Have you read the EEPROM data sheet?  I'm looking at the AT24C04D data sheet from Microchip, but all '04 EEPROM devices operate with the same sequence.

    In particular, note that there are 512 memory bytes, so the byte address is a 9-bit number.

    Here's the sequence for writing a single byte to a particular location in the 9-bit address space:
    1. Set the I2C Start condition.  Wait until it has been asserted.
    2. Transmit  a "Write" control byte and wait for the transmission to be complete.  For a 'C04 device This control byte consists of the seven-bit I2C device address, a bit that is the MSB of the 9-bit byte address and a zero bit that indicates it is a "Write" control byte.  After the transaction is complete, check for an ACK condition from the target.  If the '04 did not ACK (i.e. the ACK bit is 1), STOP and see if you can figure out why.  It is senseless to continue if the target did not ACK.
    3. Transmit a byte containing the low 8 bits of the byte address and wait for the transmission to be complete.  Check for a target ACK.  If the target did not ACK, STOP and see if you can figure out what happened.  It is senseless to continue if the target did not ACK.
    4. Transmit a byte containing the 8-bit data bite to be written and wait for the transmission to be complete.  Again, check to see if the target sent an ACK.  If it did not, that (probably) means that it did not write the desired data.
    5. Set the I2C Stop condition wait until it has been asserted.

    Reading a single byte from a particular location in the 9-bit address space consists of the following
    1. Steps 1-3 of the above sequence
    2. Set the I2C Start condition.  (For the PIC in multimaster mode, use Restart.  Restart will always work, whether the system is multimaster or not.  If the system is multimaster, you have to be concerned with Bus Collision, but let's keep things simple for starters.)
    3. Enable the RCEN bit and wait for the reception it to be complete.
    4. Send a NACK to the '04 device and wait for it to be complete.
    5. Set the I2C Stop condition.
    6. Read the value from the I2C RCV register.

    NOTE: After writing to the device, you must wait for the target's internally-timed write cycle to finish before trying anything else with the device. That is, there is a certain time (a few milliseconds) during which the '04 will not respond to any further I2C activity.  Read the section of the data sheet titled "Acknowledge Polling."

    Now a very important part is testing.  If you have a 'scope you can observe each of the transactions.  If you don't have a 'scope, I feel your pain.  Been there done that.  It's harder, but it can be done.  It is very helpful that you have a working UART to assist.

    So here's my first test suggestion, whether you have 'scope or not:
    Don't use any functions just yet.  Write and read registers directly in your code.
    For starters, after initialization just do the following in a continuous loop:
    1. Set the I2C Start condition.
    2. Transmit a Write control byte consisting of the device id bits in the proper place and wait for the transaction to be complete.
    3. Set the I2C Stop condition
    4. Check the ACK bit and print its value
    Here's my main() for testing my AT24C04 connected to the I2C1 pins on my PIC24EP256GP202 breadboard:

    #define DEV_ADDR7 0x50

    void init_system(void);
    uint16_t count;

    int main()
    {
        // Initialize clock, UART, I2C, etc.
        init_system();
        __delay_ms(100); // Give things a little time to settle down.
        printf("\r\nCompiled on %s at %s by XC16 version %u\r\n",
                __DATE__, __TIME__, __XC16_VERSION);

        uint8_t ackbit;

        while (1) { // Main loop
            // Visual aid if you have an LED
            LED1_Toggle();
            // Set Start condition
            I2C1CONbits.SEN = 1;
            while (I2C1CONbits.SEN)
                ;
            // Send "Write" control byte
            I2C1TRN = (DEV_ADDR7 << 1);
            // Wait until end of transmission before testing ACK bit
            while (I2C1STATbits.TRSTAT)
                ;
            ackbit = I2C1STATbits.ACKSTAT;
            // Set Stop condition
            I2C1CONbits.PEN = 1;
            while (I2C1CONbits.PEN)
                ;
            printf("%u: ACK bit from device = %u\r\n", ++count, ackbit);
            // Give some separation between bytes so that you can them
            // clearly on the 'scope
            __delay_ms(1000);
        } // End of Main loop
    } // End of main()



    Output:
    Compiled on Sep 16 2019 at 07:42:32 by XC16 version 1040
    1: ACK bit from device = 0
    2: ACK bit from device = 0
    3: ACK bit from device = 0
    .
    .
    .


    Just for kicks, define DEV_ADDR7 to be something that is not the right ID, say 0x60, and verify that the ACK bit is 1, indicating NACK so that it is actually testing what you think it is.

    Bottom line: Once you have verified that you can get the '04 to respond to your I2C write transaction, change your WriteReg and ReadReg routines to comply with the 24C04 Data Sheet.

    Final suggestion for this time (I promise): Use "0x%02X" format for displaying your characters.  I'm guessing your original code is writing 0xFF to the UART and it doesn't show up on your terminal emulator.  Wring all of the information  you can out of your test code.

    Regards,

    Dave
    post edited by davekw7x - 2019/09/16 14:32:43

    Sometimes I just can't help myself...
    #7
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/17 23:58:04 (permalink)
    0
    Hi,
    thank you for replying davekw, u have explained briefly thank you.
    i have checked the code u have sent that whether it responds to ATC024, it has works fine i got output from uart as your attached output.
    i need to read and write character from A to Z for this i have written code with your instruction i have tested in uart but i am not getting anything, could you please tell me correction i have attached code here.

     
     
     

    void I2CInit(void)
    {
    I2C2BRG = 0x23; // Baud Rate Generator Value: I2CBRG 35;
    I2C2CONbits.I2CEN = 0; // Disable I2C
    I2C2CONbits.DISSLW = 1; // Disable slew rate control
    I2C2CONbits.A10M = 0; // 7-bit slave addr
    I2C2CONbits.SCLREL = 1; // SCL release control
    I2C2CONbits.I2CEN = 1; // Enable I2C
    IFS3bits.MI2C2IF = 0;
    // enable the master interrupt
    IEC3bits.MI2C2IE = 0;
    }

    void i2c_start(void)
    {
    I2C2CONbits.SEN = 1; //Initiate start condition
    while(I2C2CONbits.SEN); //Wait till completion of event
    }
    void i2c_restart(void)
    {
    I2C2CONbits.RSEN = 1; //Initiate start condition
     
     
     
    while(I2C2CONbits.RSEN); //Wait till completion of event
    }
    int i2c_write(unsigned char c)
    {
    I2C2TRN=c;
    while(I2C2STATbits.TRSTAT);
    }
    unsigned char i2c_read(void)
    {
    I2C2CONbits.RCEN = 1; //Enable reception in Master device
    while(!I2C2STATbits.RBF); //Wait till buffer is full
    I2C2CONbits.RCEN = 0; //Enable reception in Master device
    return I2C2STATbits.TBF; //return received data
    }
    void I2CNack(void)
    {
    I2C2CONbits.ACKDT = 1; // Send NACK
    I2C2CONbits.ACKEN = 1; // Initiate Acknowledge and transmit ACKDT
    if(I2C2CONbits.ACKEN);
    }
     
     
     
    void i2c_stop(void)
    {

    I2C2CONbits.PEN = 1; //Initiate Stop condition
    while(I2C2CONbits.PEN); //Wait till completion of event
    }
     
     
     
     
     
     
     
    void EE_byte_write(unsigned char addr,unsigned char data )
    {
    unsigned char addrh, addrl;
    addrh=(addr>>8);
    addrl=(addr&0xff);
    i2c_start(); // start I2C
    i2c_write(0xA0); // Write Control byte
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete
     
     
     
    i2c_write(addrh); // MSB of byte address
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete
     
     
     
    i2c_write(addrl); // LSB of byte address(data word address)
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete

    i2c_write(data); // input character to eeprom
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete
    i2c_stop(); // stops I2C

    //_delay_ms(100); // delay for internal write cycle of EEPROM
    }
     
     
     
    unsigned char EE_byte_read(unsigned char addr)
    {
    unsigned char temp;
    unsigned char addrh, addrl;
    addrh=(addr>>8);
    addrl=(addr&0xff);
    i2c_start(); // start I2C
    i2c_write(0xA0); // Write Control byte
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete
     
     
     
    i2c_write(addrh); // MSB of byte address
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete
     
     
     
    i2c_write(addrl); // LSB of byte address(data word address)
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete
     
     
     
    i2c_restart(); // restart I2C
    i2c_write(0xA1); // access in read mode
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete
     
     
     
    i2c_read();
    I2CNack(); // read with NACK
    i2c_stop(); // stops I2C
    temp = I2C2RCV;
     
     
     
    return temp;
    }
     
     
     

    main.c

     
     
     
    // FICD
    #pragma config ICS = PGD2 // ICD Communication Channel Select bits (Communicate on PGEC2 and PGED2)
    #pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
     
     
     
    // FPOR
    #pragma config ALTI2C1 = OFF // Alternate I2C1 pins (I2C1 mapped to SDA1/SCL1 pins)
    #pragma config ALTI2C2 = OFF // Alternate I2C2 pins (I2C2 mapped to SDA2/SCL2 pins)
    #pragma config WDTWIN = WIN25 // Watchdog Window Select bits (WDT Window is 25% of WDT period)
     
     
     
    // FWDT
    #pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler bits (1:32,768)
    #pragma config WDTPRE = PR128 // Watchdog Timer Prescaler bit (1:128)
    #pragma config PLLKEN = OFF // PLL Lock Enable bit (Clock switch will not wait for the PLL lock signal.)
    #pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
    #pragma config FWDTEN = OFF // Watchdog Timer Enable bit (Watchdog timer enabled/disabled by user software)
     
     
     
    // FOSC
    #pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
    #pragma config OSCIOFNC = OFF // OSC2 Pin Function bit (OSC2 is clock output)
    #pragma config IOL1WAY = ON // Peripheral pin select configuration (Allow only one reconfiguration)
    #pragma config FCKSM = CSDCMD // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are disabled)
     
     
     
    // FOSCSEL
    #pragma config FNOSC = FRC // Oscillator Source Selection (Internal Fast RC (FRC))
    #pragma config IESO = OFF // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
     
     
     
    // FGS
    #pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written)
    #pragma config GCP = OFF // General Segment Code-Protect bit (General Segment Code protect is Disabled)
     
     
     
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.
     
     
     
    #include <xc.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define _XTAL_FREQ 7370000UL
    #define FP 3685000UL
    #define BAUDRATE 9600
    #define BRGVAL ((FP/BAUDRATE)/16)-1
    #include <libpic30.h> //for delay routines#
    #include "at24.h"
    #include "uart.h"
    #define SDA SDA2
    #define SCL SCL2
    #define DEV_ADDR7 0x50
    uint16_t count;
    int main(void)
    {
    //TRISC=0x3FFF;
    char buffer[40]; //array to hold the strin
    unsigned char read_int,write_int;
     
     
     
    char address;
    uart_init();
    I2CInit();
    while (1){



    for(write_int='A';write_int<='Z';write_int++)
    {
    //sprintf(buffer,"\n\rFlash Write: %c ",write_int); //Print the message on UART
    //uartputs(buffer); // output the string we created
    EE_byte_write(address,write_int); // Write the data at

    read_int=EE_byte_read(address); // Read the data from memoryLocation 0x00
    sprintf(buffer,"Flash Read: %c",read_int); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created

    }

    }
    return 1;
    }
     
     
     

    and u have told me about uart to use something else then what i am using but i didn't get that so i used same thing.
     Thanking you.
    post edited by Gouthami c v - 2019/09/18 00:02:02
    #8
    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/18 00:08:44 (permalink)
    5 (1)
    All your handling of the ACK bit is wrong. Have another look at Dave's example.
    You should wait for the I2C transfer to finish, then read the state of the ACK bit ONCE.
    Any loop that just waits for the ACK bit is WRONG.
    The "ACK Polling" that Dave refers to (to check if the EEPROM's internal write has finished) requires you to do multiple complete transactions, checking if you received an ACK after each transaction.
    That is NOT what your code is doing.
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #9
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/18 00:27:45 (permalink)
    0
    thank you for replying, in above reply u have said that i should wait for I2C transfer to finish and then read ack bit, i have used same thing in write loop.
    i have attached here

    int i2c_write(unsigned char c)
    {
    I2C2TRN=c;
    while(I2C2STATbits.TRSTAT);
    }

    after writing adress msb and lsb i am waiting in write loop, is this not correct?
    #10
    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/18 00:34:14 (permalink)
    5 (1)
    This line is wrong every time you do it
    while(I2C2STATbits.ACKSTAT); // Wait for ACK bit to complete
    You just don't seem to get the "read once" concept.



     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #11
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/18 00:45:49 (permalink)
    0
    i have read datasheet but still i am not getting how to handle ack bit could you please send me small example code.
     
     
     
    Thanking you.
     
    #12
    davekw7x
    Entropy++
    • Total Posts : 1827
    • Reward points : 0
    • Joined: 2012/01/16 12:01:07
    • Location: Second star on the right, straight on till morning
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/18 07:46:14 (permalink)
    5 (1)
    Gouthami c v
    ...how to handle ack bit...

    The basics are in the Main loop of the test program that I posted.  I sincerely hoped that the comments would give the information you need.  My hope was that by understanding what it is doing you might see the difference between my code and yours and change yours accordingly to capture the target's ACK/NACK expression.

            // Send "Write" control byte
            I2C1TRN = (DEV_ADDR7 << 1);
            // Wait until end of transmission before testing ACK bit
            while (I2C1STATbits.TRSTAT)
                ;
            ackbit = I2C1STATbits.ACKSTAT;


    Do this everywhere you write to the I2C transmit register to see if the target issued an ACK.

    That is, if ackbit == 0, it the target issued an ACK.  If ackbit != 0 the target did not ACK.

    When you implement your byte read and byte write functions, if at any point the target did not issue the expected ACK, you might as well abort the rest of the transaction.

    My suggestion would be create byte read and byte write functions that return a signed integer. (Integers are 16-bit quanties in XC16.)

    For both functions, if the target did not ACK, have the function issue a Stop condition and return a negative number (-1, for example, but see Footnote).

    So, if either function returns a negative value, the calling program does whatever it needs to do  (Try again?  Report error to the user?  Whatever...).

    If the byte write function gets all of the way through with ACKs everywhere expected, this function returns 1 to indicate that one byte was successfully transmitted, and the calling program can proceed normally.

    Then...

    If the byte read function gets all of the way through with ACK where expected, this function returns the value from the I2C receive register. Note that an unsigned char from the receive register will be promoted to an integer with the upper byte equal to zero, so it will be a non-negative integer.  With a non-negative return value the calling program can know that the return value is the valid target response from the I2C receive register.
     
    Now, in addition to the preferred ACK checking where appropriate, there are a number of out-and-out bugs in your program.  I Have not tested other parts of your program (I2C initialization for example), but some things simply jump out at me that indicate your lack of understanding of my previous points.

    For example: Your EE_byte_write() does NOT comply with the 'C04 requirements that I pointed out previously:
    • Send the control byte with the I2C device address bits and the MSB of the nine-bit byte address in the proper bit positions.
    • Send the lower 8 bits of the nine-bit byte address
    • Send the byte data.
     
    Also, check your EE_byte_read() function for compliance.  Really a mess!


    Regards,

    Dave
     
    Footnote:
    For the byte write function, a somewhat more informative plan might to return -1 if the first write (the device address) failed.  Return -2 if the second write (the byte address) failed, etc.  This might help debugging, and would let you zero in on what part of the transaction you should be observing on a 'scope.



    post edited by davekw7x - 2019/09/18 08:21:55

    Sometimes I just can't help myself...
    #13
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/19 01:59:25 (permalink)
    0
    hi dave's thank you for explaining, i have followed your code and datasheet, first have to send control byte and msb second is to send lsb then have to send data right. in datasheet I have done it,in data sheet device address is 1010, so i have used same for to write MSB and LSB, and i have attached device address mentioned in datasheet.You have told to check ACK bit after every transmission, i followed the same i have checked in uart i am getting output for ackbit as 0 for every transmission.I have attached code here

     
     
     

    #include <xc.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define _XTAL_FREQ 7370000UL
    #define FP 3685000UL
    #define BAUDRATE 9600
    #define BRGVAL ((FP/BAUDRATE)/16)-1
    #include <libpic30.h> //for delay routines#
    #include "AT24C04DEEPROM.h"
    #include "uart.h"
    #define SDA SDA2
    #define SCL SCL2
    #define DEV_ADDR7 0xA0
    #define DATA 0x0A;
    uint16_t count;
    int main(void)
    {
    //TRISC=0x3FFF;
    char buffer[40]; //array to hold the string

    uart_init();
    I2CInit();
     
     
     
     uint8_t ackbit;
     
     
     
     while (1) {
     
     
     
    I2C2CONbits.SEN = 1;
    while (I2C2CONbits.SEN)
    ;
    // Send "Write" control byte
    I2C2TRN = (DEV_ADDR7 << 1);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ackbit = I2C2STATbits.ACKSTAT;
    // output the string we created
    sprintf(buffer,"ACK bit from control byte =%u\r\n", ackbit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    // Send "LSB" BIT
    I2C2TRN = (DEV_ADDR7);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ackbit = I2C2STATbits.ACKSTAT;
    // output the string we created
    sprintf(buffer,"ACK bit from lsb byte = %d\r\n",ackbit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    // Send DATA
    I2C2TRN = DATA;
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ackbit = I2C2STATbits.ACKSTAT;
    // output the string we created
    sprintf(buffer,"ACK bit from data=%u\r\n",ackbit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    // Set Stop condition

    I2C2CONbits.PEN = 1;
    while (I2C2CONbits.PEN)
    ;
     
     
     
    }
    return 1;
    }
     
     
     
      
    I am getting ACK bit after transmission, is my code correct and could u please tell me about read operation.
    Thanking you.
    post edited by Gouthami c v - 2019/09/19 02:12:18

    Attached Image(s)

    #14
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/19 05:16:26 (permalink)
    0
    hey hi,
    OMG i got output now i am able to read and write,thank you dave's and ric's.
    In my code i tried to store character 'H',its worked 
    i am attaching code and uart output, thank you once againSmile: Smile.

    #include <xc.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define _XTAL_FREQ 7370000UL
    #define FP 3685000UL
    #define BAUDRATE 9600
    #define BRGVAL ((FP/BAUDRATE)/16)-1
    #include <libpic30.h> //for delay routines#
    #include "AT24C04DEEPROM.h"
    #include "uart.h"
    #define SDA SDA2
    #define SCL SCL2
    #define DEV_ADDR7 0xA0
    #define DEV_ADDR 0xA1
    #define byte_addr 0x210
    int main(void)
    {
    //TRISC=0x3FFF;
    char buffer[80]; //array to hold the string

    uart_init();
    I2CInit();

    //sprintf(buffer,"BRIGHTNESS CONTROLLER\r\n");
    //uartputs(buffer);// output the string we created

    uint8_t ackbit,ack1bit,ack2bit,ack3bit,ack4bit,ack5bit;

    unsigned char Data='H';

    unsigned char temp;
    uint8_t nackbit;
    while (1) { // Main loop

    //WRITE CONDITION
    // Set Start condition

    I2C2CONbits.SEN = 1;
    while (I2C2CONbits.SEN)
    ;
    // Send "Write" control byte
    I2C2TRN = (DEV_ADDR7);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;

    ackbit = I2C2STATbits.ACKSTAT;

    // Send word adress byte
    I2C2TRN = (byte_addr);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ack1bit = I2C2STATbits.ACKSTAT;

    // Send "data"
    I2C2TRN = (Data);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ack2bit = I2C2STATbits.ACKSTAT;

    // Set Stop condition
    I2C2CONbits.PEN = 1;
    while (I2C2CONbits.PEN)
    ;
    sprintf(buffer,"ACK bit from control byte = %u\r\n",ackbit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    sprintf(buffer,"ACK bit from lsb byte = %u\r\n",ack1bit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    sprintf(buffer,"ACK bit from data = %u\r\n",ack2bit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created

    //READ CONDITION
    I2C2CONbits.SEN = 1;
    while (I2C2CONbits.SEN)
    ;
    // Send "Write" control byte
    I2C2TRN = (DEV_ADDR7);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;

    ack3bit = I2C2STATbits.ACKSTAT;

    // Send word adress byte
    I2C2TRN = (byte_addr);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ack4bit = I2C2STATbits.ACKSTAT;
    //READ CONDITION
    I2C2CONbits.RSEN = 1;
    while (I2C2CONbits.RSEN)
    ;
    I2C2TRN = (DEV_ADDR);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;

    ack5bit = I2C2STATbits.ACKSTAT;

    I2C2CONbits.ACKDT=1; // No Acknowledge for data in Receive mode.
    I2C2CONbits.RCEN=1; // Enables Receive mode on I2C.
    I2C2CONbits.ACKEN=1; // Initiates Acknowledge sequence on SDA and SCL pins.
    while( I2C2CONbits.RCEN ==1); // master receive mode
    while(!I2C2STATbits.RBF);
    temp =I2C2RCV;
    nackbit = I2C2STATbits.ACKSTAT;
    // Set Stop condition
    I2C2CONbits.PEN = 1;
    while (I2C2CONbits.PEN)
    ;
    sprintf(buffer,"ACK bit from controlread byte = %u\r\n",ack3bit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    sprintf(buffer,"ACK bit from lsbread byte = %u\r\n",ack4bit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    sprintf(buffer,"ACK bit from readdata = %u\r\n",ack5bit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    sprintf(buffer,"NACK bit from data = %u\r\n",nackbit); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    sprintf(buffer,"RSLT = %c\r\n",temp); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    }
    return 1;
    }
     
    Thank you.

    Attached Image(s)

    #15
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/20 00:03:54 (permalink)
    0
    Hi everyone,
    After the above code has done, i have tried to read and write data from A to Z and 1 to 100 even i got output. But i have one question that is EEPROM is electrically erasable ROM nothing but "non-volatile" memory right, it means it has to store data when power has gone and as soon as power arrives it has to operate where it has left it should not start from beginning right. But when i have tried to store char from A to Z or 1 to 100,when i will switch off power supply it start displaying from beginning so how to achieve this in our program, could you please tell me how to do this.
    Thanking You. 
    #16
    ric
    Super Member
    • Total Posts : 23893
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/20 00:08:27 (permalink)
    0
    You've made a mistake in how you tested.
    We can't comment if you don't show us the exact code you did this test with.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #17
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/20 00:24:22 (permalink)
    0
    I have did test with uart
    here is my code

    #include <xc.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define _XTAL_FREQ 7370000UL
    #define FP 3685000UL
    #define BAUDRATE 9600
    #define BRGVAL ((FP/BAUDRATE)/16)-1
    #include <libpic30.h> //for delay routines#
    #include "AT24C04DEEPROM.h"
    #include "uart.h"
    #define SDA SDA2
    #define SCL SCL2
    #define DEV_ADDR7 0xA0
    #define DEV_ADDR 0xA1
    #define byte_addr 0x210
    int main(void)
    {
    //TRISC=0x3FFF;
    char buffer[80]; //array to hold the string

    uart_init();
    I2CInit();
    uint8_t ackbit,ack1bit,ack2bit,ack3bit,ack4bit,ack5bit;

    unsigned char Data;

    unsigned char Read_char;
    uint8_t nackbit;
    while (1) { // Main loop

    //WRITE CONDITION
    // Set Start condition
    for(Data='A';Data<='Z';Data++)
    {
    I2C2CONbits.SEN = 1;
    while (I2C2CONbits.SEN)
    ;
    // Send "Write" control byte
    I2C2TRN = (DEV_ADDR7);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;

    ackbit = I2C2STATbits.ACKSTAT;

    // Send word adress byte
    I2C2TRN = (byte_addr);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ack1bit = I2C2STATbits.ACKSTAT;

    // Send "data"
    I2C2TRN = (Data);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ack2bit = I2C2STATbits.ACKSTAT;

    // Set Stop condition
    I2C2CONbits.PEN = 1;
    while (I2C2CONbits.PEN)
    ;
    sprintf(buffer,"\n\rWRITE DATA = %c",Data); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created

    //READ CONDITION
    I2C2CONbits.SEN = 1;
    while (I2C2CONbits.SEN)
    ;
    // Send "Write" control byte
    I2C2TRN = (DEV_ADDR7);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;

    ack3bit = I2C2STATbits.ACKSTAT;

    // Send word adress byte
    I2C2TRN = (byte_addr);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;
    ack4bit = I2C2STATbits.ACKSTAT;
    //READ CONDITION
    I2C2CONbits.RSEN = 1;
    while (I2C2CONbits.RSEN)
    ;
    I2C2TRN = (DEV_ADDR);
    // Wait until end of transmission before testing ACK bit
    while (I2C2STATbits.TRSTAT)
    ;

    ack5bit = I2C2STATbits.ACKSTAT;

    I2C2CONbits.ACKDT=1; // No Acknowledge for data in Receive mode.
    I2C2CONbits.RCEN=1; // Enables Receive mode on I2C.
    I2C2CONbits.ACKEN=1; // Initiates Acknowledge sequence on SDA and SCL pins.
    while( I2C2CONbits.RCEN ==1); // master receive mode
    while(!I2C2STATbits.RBF);
    Read_char =I2C2RCV;
    nackbit = I2C2STATbits.ACKSTAT;
    // Set Stop condition
    I2C2CONbits.PEN = 1;
    while (I2C2CONbits.PEN)
    ;
    sprintf(buffer," READ DATA = %c",Read_char); //transmit the data read from Eeprom
    uartputs(buffer);// output the string we created
    }

    }
    return 1;
    }

    Thanking you.
    #18
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/20 00:32:27 (permalink)
    0
    i have attached uart output here
    post edited by Gouthami c v - 2019/09/20 00:33:33

    Attached Image(s)

    #19
    Gouthami c v
    Starting Member
    • Total Posts : 79
    • Reward points : 0
    • Joined: 2019/07/11 01:55:44
    • Location: 0
    • Status: offline
    Re: External EEPROM(ATC024) interface with PIC24EP256GP206 2019/09/20 00:39:12 (permalink)
    0
    here is my waveform

    Attached Image(s)

    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5