RadioLocman.com Electronics ru
Advanced Search +
  
Go Back   RadioLocman Forum > Electronics and ... > Microcontrollers (MCU)

Microcontrollers (MCU) Application and programming of MCUs, Evaluation Kits and Demonstration Boards, Programmers.

Reply
 
Thread Tools Search this Thread
Old 08-01-2015, 11:12 AM   #1
symbol
Senior Member
 
Join Date: Oct 2013
Posts: 131
symbol is on a distinguished road
Default PIC32 and I2C EEPROM interface problems

I am writing code for a PIC32MX250F128B to interface with the Microchip 24LC02B EEPROM with I2C interface. I have followed the datasheet of the EEPROM, the PIC32 and section 24 of the PIC32 family reference manual very closely and attempted to write code to interface with the EEPROM. I do not get any "hang" on any of the tests for the bits that need to be cleared/set after eg. an ACK is received - the code executes completely. However, when I check the value of the data variable right at the end of the readEeprom function, I just get a Null-character (after writing an 'H' in the EEPROM memory address specified, in byte write mode (page write code is commented out with #if)). This indicates that either the write did not occur properly, or the read did not occur properly.

I do not have access to an oscilloscope or logic analyzer to check what exactly happens on the SDA and SCL lines.

The PIC32 oscillator is set to 8 MHz and I intended to use a 100 kHz baud rate for communication with the EEPROM. So therefore, using the equation I2CBRG = (PBCLK/(2*FSCK))-2, as found in section 24 of the PIC32 family reference documents, I use 0x26 for theI2CBRG value.

Perhaps someone could spot if something is wrong in my code? I have tried to find the problem over a day now, but have not succeeded.

Here is my code:
Code:
* Interface test for I2C EEPROM with PIC32
*/

#include <plib.h>
#include <p32xxxx.h>


/* Pin outline:
* SCL1 - pin 17 - (EEPROM pin 6)
* SDA1 - pin 18 - (EEPROM pin 5)
* WP - pin 16 (RB7) (EEPROM pin 7) - Currently connected to GND
*/


//configuration bits
// DEVCFG3
//#pragma config PMDL1WAY = OFF           // Peripheral Module Disable Configuration (Allow multiple reconfigurations)
//#pragma config IOL1WAY = OFF            // Peripheral Pin Select Configuration (Allow multiple reconfigurations)
//#pragma config FUSBIDIO = OFF            // USB USID Selection (Controlled by the USB Module)
//#pragma config FVBUSONIO = OFF           // USB VBUS ON Selection (Controlled by USB Module)
// DEVCFG2
#pragma config FPLLIDIV = DIV_1        // PLL Input Divider (12x Divider)
#pragma config FPLLMUL = MUL_24        // PLL Multiplier (24x Multiplier)
//#pragma config UPLLIDIV = DIV_1        // USB PLL Input Divider (12x Divider)
//#pragma config UPLLEN = OFF             // USB PLL Enable (Disabled and Bypassed)
#pragma config FPLLODIV = DIV_1       // System PLL Output Clock Divider (PLL Divide by 256)
// DEVCFG1
#pragma config FNOSC = FRC              // Oscillator Selection Bits (Fast RC Osc (FRC))
#pragma config FSOSCEN = OFF             // Secondary Oscillator Disnable (Disabled)
#pragma config IESO = ON                // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = OFF            // Primary Oscillator Configuration (Primary osc disabled)
#pragma config OSCIOFNC = OFF           // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_1           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/1)
#pragma config FCKSM = CSECMD           // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576        // Watchdog Timer Postscaler (1:1048576)
//#pragma config WINDIS = OFF             // Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
//#pragma config FWDTWINSZ = WISZ_25      // Watchdog Timer Window Size (Window Size is 25%)
// DEVCFG0
//#pragma config JTAGEN = OFF             // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx2        // ICE/ICD Comm Channel Select (Communicate on PGEC2/PGED2)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)
//////////////////////////////////////////

#define EEPROM_WP PORTBbits.RB7
#define CLOCK   8000000
#define HIGH 1 //logic values declaration
#define LOW 0 //logic values declaration

char data[10];
void init(void);
void readEeprom(void);
void writeEeprom(void);

int main (void)
{
    init();
    writeEeprom();
    readEeprom();
} /*main*/

void init(void)
{
    SYSTEMConfigPerformance(CLOCK);
    TRISBbits.TRISB7 = 0x01;
    /*I2C peripheral overrides states of respective interface pins - no need
     to set state of SCLx and SDAx pins here*/  

    /*Initialize I2C Peripheral*/   
    I2C1CONbits.DISSLW = HIGH; /*disable slew rate for 100 kHz*/
    I2C1BRG = 0x26; /*Set Baud Rate Generator*/
    I2C1CONbits.ON = HIGH;

    int i = 0;
    for (i = 0; i < 10; i++)
    {
        data[i] = '0';
    } /*for*/
} /*init*/

void writeEeprom(void)
{
    /*Assert start condition*/
    I2C1CONbits.SEN = HIGH; /*This bit is automatically cleared by MCU*/

    /*Test if START condition is completed - test interrupt I2C1MIF in IFS1*/
    while (I2C1CONbits.SEN == HIGH); /*wait until start condition finishes*/

    /*Send device address and write indication - address = "1010xxx0"*/
    I2C1TRN = 0b10100000;

    /*Wait for transmit buffer empty - indicates that write is completed*/
    while (I2C1STATbits.TBF == HIGH);

    /*Wait for ACK signal from device - bit will clear when ACK is received*/
    while (I2C1STATbits.ACKSTAT == HIGH);

    /*Send address for read - first HIGH byte, then LOW byte*/
    /*Begin with the very first address page*/
    I2C1TRN = 0x00;
    while (I2C1STATbits.ACKSTAT == HIGH); /*wait for ACK from device*/
    I2C1TRN = 0x00;
    while (I2C1STATbits.ACKSTAT == HIGH);

#if 0 /*Page write*/
    int i;
    /*24LC02 can only write up to 8 bytes at a time*/
    for (i = 0; i < 7; i++)
    {
        I2C1TRN = i;
        /*Wait for transmit buffer empty - indicates that write is completed*/
        while (I2C1STATbits.TBF == HIGH);
        /*Generate ACK event*/       
        I2C1CONbits.ACKEN;
    } /*for*/   
    /*Send stop event*/
    I2C1CONbits.PEN;
#endif

#if 1 /*Byte write*/   
    I2C1TRN = 'H';
    /*Wait for transmit buffer empty - indicates that write is completed*/
    while (I2C1STATbits.TBF == HIGH);
    /*Generate ACK event*/       
    I2C1CONbits.ACKEN;
    /*Send stop event*/
    I2C1CONbits.PEN;
#endif
} /*writeEeprom*/

void readEeprom(void)
{

    /*Assert start condition*/
    I2C1CONbits.SEN = HIGH; /*This bit is automatically cleared by MCU*/

    /*Test if START condition is completed - test interrupt I2C1MIF in IFS1*/
    while (I2C1CONbits.SEN == HIGH); /*wait until start condition finishes*/

    /*Send device address and write indication - address = "1010xxx0"*/
    I2C1TRN = 0b10100000;

    /*Wait for transmit buffer empty - indicates that write is completed*/
    while (I2C1STATbits.TBF == HIGH);

    /*Wait for ACK signal from device - bit will clear when ACK is received*/
    while (I2C1STATbits.ACKSTAT == HIGH);

    /*Send address for read - first HIGH byte, then LOW byte*/
    I2C1TRN = 0x00; /*Upper 8 bits of address*/
    while (I2C1STATbits.ACKSTAT == HIGH); /*wait for ACK from device*/
    I2C1TRN = 0x00; /*Lower 8 bits of address*/
    while (I2C1STATbits.ACKSTAT == HIGH);

    /*Send Repeated start event again*/
    I2C1CONbits.RSEN = HIGH;

    /*Test if START condition is completed - test interrupt I2C1MIF in IFS1*/
    while (I2C1CONbits.SEN == HIGH); /*wait until start condition finishes*/

    /*Send device address and read indication*/
    I2C1TRN = 0b10100001;

    while (I2C1STATbits.ACKSTAT == HIGH);
    int i = 0;
#if 0 /*Sequential read*/   
    for (i = 0; i < 10; i++)
    {
        /*Enable receive mode - RCEN cleared after 8th bit is received*/
        I2C1CONbits.RCEN = HIGH;
        while (I2C1STATbits.RBF == LOW); /*Wait for receive buffer full*/   
        data[i] = I2C1RCV; /*Store receive buffer value in dataByte*/
        while (I2C1STATbits.RBF == HIGH); /*Wait for receive buffer to clear*/
        /*Generate ACK event - do not send ACK for last sequential read*/
        if (i < 9)
        {
            I2C1CONbits.ACKEN;
        } /*if*/
    } /*for*/   
    /*Send stop event*/
    I2C1CONbits.PEN;
#endif

#if 1 /*Single read*/
    /*Enable receive mode - RCEN cleared after 8th bit is received*/
    I2C1CONbits.RCEN = HIGH;
    //while (I2C1STATbits.RBF == LOW); /*Wait for receive buffer full*/   
    data[i] = I2C1RCV; /*Store receive buffer value in dataByte*/
    while (I2C1STATbits.RBF == HIGH); /*Wait for receive buffer to clear*/
    /*Send stop event - no ACK event must be sent*/
    I2C1CONbits.PEN;
#endif
} /*readEeprom()*/
symbol is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
EEPROM data corruption Atmega32a rapid Microcontrollers (MCU) 3 03-27-2015 09:16 PM
Discussion: PIC and EEPROM Programmer Radiolocman Robot Microcontrollers (MCU) 2 12-12-2012 09:42 AM

All times are GMT. The time now is 08:23 PM.




Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Slices ↓
Radiolocman facebook Radiolocman twitter Radiolocman google plus