Difference between revisions of "PIC32MX: I2C External RAM"
TylerJohnson (talk | contribs) |
TylerJohnson (talk | contribs) m (→Code) |
||
Line 25: | Line 25: | ||
---- |
---- |
||
// INCLUDES |
// INCLUDES |
||
#include <HardwareProfile.h> |
#include <HardwareProfile.h> |
||
#include <HardwareProfile_NU32.h> |
#include <HardwareProfile_NU32.h> |
||
#include <plib.h> |
#include <plib.h> |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
#define SYSCLK (80000000) |
|||
⚫ | |||
#define PBCLK (SYSCLK/2) // set PBCLK to 800 KHz |
|||
#define |
#define Fsck 50000 |
||
#define |
#define BRG_VAL ((PBCLK/2/Fsck)-2) |
||
#define |
#define Nop() asm( "nop" ) |
||
#define BRG_VAL ((PBCLK/2/Fsck)-2) |
|||
⚫ | |||
#define Nop() asm( "nop" ) |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
{ |
|||
⚫ | |||
⚫ | |||
} |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
} |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
{ |
{ |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
OpenI2C1( I2C_EN, BRG_VAL ); |
OpenI2C1( I2C_EN, BRG_VAL ); |
||
SlaveAddress = 0x50; (0b01010000) |
SlaveAddress = 0x50; (0b01010000) |
||
i2cData[0] = ((SlaveAddress << 1) | 0 ); //slave address and write command |
i2cData[0] = ((SlaveAddress << 1) | 0 ); //slave address and write command |
||
i2cData[1] = 0x05; //word address |
i2cData[1] = 0x05; //word address |
||
i2cData[2] = 0xAA; //data bits 10101010 |
i2cData[2] = 0xAA; //data bits 10101010 |
||
DataSz = 3; |
DataSz = 3; |
||
Line 89: | Line 88: | ||
MasterWriteI2C1 (i2cData[0]); //sends first string of data to PCF8570P |
MasterWriteI2C1 (i2cData[0]); //sends first string of data to PCF8570P |
||
IdleI2C1(); |
IdleI2C1(); |
||
if( I2C1STATbits.ACKSTAT ) //looks for acknowledge low bit to be returned |
if( I2C1STATbits.ACKSTAT ) //looks for acknowledge low bit to be returned |
||
break; |
break; |
||
MasterWriteI2C1 (i2cData[1]); |
MasterWriteI2C1 (i2cData[1]); |
||
IdleI2C1(); |
IdleI2C1(); |
||
if( I2C1STATbits.ACKSTAT ) |
if( I2C1STATbits.ACKSTAT ) |
||
break; |
break; |
||
MasterWriteI2C1 (i2cData[2]); |
MasterWriteI2C1 (i2cData[2]); |
||
IdleI2C1(); |
IdleI2C1(); |
||
if( I2C1STATbits.ACKSTAT ) |
if( I2C1STATbits.ACKSTAT ) |
||
break; |
break; |
||
StopI2C1(); //sends the stop condition to the PCF8570P clock and data lines |
StopI2C1(); //sends the stop condition to the PCF8570P clock and data lines |
||
IdleI2C1(); |
IdleI2C1(); |
||
/////////////////////////////////////////////////////////// |
/////////////////////////////////////////////////////////// |
||
//Reading Data from the PCF8570P |
//Reading Data from the PCF8570P |
||
//First sends write command to write which word the PIC wants to read from |
//First sends write command to write which word the PIC wants to read from |
||
i2cData[0] = (SlaveAddress << 1) | 0; |
i2cData[0] = (SlaveAddress << 1) | 0; |
||
i2cData[1] = 0x05; |
i2cData[1] = 0x05; |
||
DataSz = 2; |
DataSz = 2; |
||
StartI2C1(); //Send the Start Bit |
StartI2C1(); //Send the Start Bit |
||
Line 120: | Line 119: | ||
MasterWriteI2C1 (i2cData[0]); |
MasterWriteI2C1 (i2cData[0]); |
||
IdleI2C1(); |
IdleI2C1(); |
||
if( I2C1STATbits.ACKSTAT ) |
if( I2C1STATbits.ACKSTAT ) |
||
break; |
break; |
||
MasterWriteI2C1 (i2cData[1]); |
MasterWriteI2C1 (i2cData[1]); |
||
IdleI2C1(); |
IdleI2C1(); |
||
if( I2C1STATbits.ACKSTAT ) |
if( I2C1STATbits.ACKSTAT ) |
||
break; |
break; |
||
RestartI2C1(); //restarts the PCF8570P |
RestartI2C1(); //restarts the PCF8570P |
||
IdleI2C1(); |
IdleI2C1(); |
||
MasterWriteI2C1( (SlaveAddress << 1) | 1 ); //transmit slave address and read command |
MasterWriteI2C1( (SlaveAddress << 1) | 1 ); //transmit slave address and read command |
||
IdleI2C1(); |
IdleI2C1(); |
||
MasterWriteI2C1(i2cData[1]); |
MasterWriteI2C1(i2cData[1]); |
||
IdleI2C1(); |
IdleI2C1(); |
||
unsigned char i2cbyte; |
unsigned char i2cbyte; |
||
i2cbyte = MasterReadI2C1(); //PIC reads data from PCF8570P |
i2cbyte = MasterReadI2C1(); //PIC reads data from PCF8570P |
||
StopI2C1(); |
StopI2C1(); |
||
IdleI2C1(); |
IdleI2C1(); |
||
} |
} |
||
} |
} |
Revision as of 03:00, 16 February 2010
Original Assignment
Do not erase this section!
Use I2C communication to send data from the PIC32 to a PCF8570P SRAM chip.
Overview
This page discusses work toward sending data to a PCF8570P SRAM chip. Basic I2C communication information, chip data, circuit diagram, and a partially functioning code are given. Prior to the code is a brief explanation of where the code is failing and why no data is being transmitted between the PIC 32 and the PCF8570P.
Circuit
Given below is the circuit diagram for communication between the PIC32 board used in class and the PCF8570P SRAM chip [1].
The PCF8570P chip has a built-in 4 bit hardware address and 3-bit user-defined hardware address allowing multiple chips to be on the same I2C data line. The diagram below shows the following 7-bit hardware address (bits shown in bold are given by the manufacturer: 1010010
Code
The following code generates the proper clock and data pulses from the PIC32, however, the PCF8570P chip continuously failed to return an "Acknowledge" bit suggesting that the chip was not processing the data being sent to it by the PIC.
DO NOT USE THE FOLLOWING CODE AS WRITTEN - IT DOES NOT WORK - MODIFY BEFORE USING
// INCLUDES
#include <HardwareProfile.h> #include <HardwareProfile_NU32.h> #include <plib.h> // Configuration Bit settings // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV) // PBCLK = 50 KHz // Primary Osc w/PLL (XT+,HS+,EC+PLL) // WDT OFF // Other options are don't care // #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_2
// DEFINES
#define SYSCLK (80000000) #define PBCLK (SYSCLK/2) // set PBCLK to 800 KHz
#define Fsck 50000 #define BRG_VAL ((PBCLK/2/Fsck)-2)
#define Nop() asm( "nop" )
/////////////////////////////////////////////
void i2c_wait(unsigned int cnt) { while(--cnt) { Nop(); Nop(); } }
/////////////////////////////////////////////
int main(void)
{ while(1) { unsigned char SlaveAddress; char i2cData[0]; int DataSz; //Enable channel
OpenI2C1( I2C_EN, BRG_VAL );
SlaveAddress = 0x50; (0b01010000)
i2cData[0] = ((SlaveAddress << 1) | 0 ); //slave address and write command i2cData[1] = 0x05; //word address i2cData[2] = 0xAA; //data bits 10101010 DataSz = 3;
StartI2C1(); //Send the Start condition to the clock and data lines
IdleI2C1(); //Wait to complete
MasterWriteI2C1 (i2cData[0]); //sends first string of data to PCF8570P IdleI2C1();
if( I2C1STATbits.ACKSTAT ) //looks for acknowledge low bit to be returned break;
MasterWriteI2C1 (i2cData[1]); IdleI2C1();
if( I2C1STATbits.ACKSTAT ) break;
MasterWriteI2C1 (i2cData[2]); IdleI2C1();
if( I2C1STATbits.ACKSTAT ) break;
StopI2C1(); //sends the stop condition to the PCF8570P clock and data lines IdleI2C1();
///////////////////////////////////////////////////////////
//Reading Data from the PCF8570P //First sends write command to write which word the PIC wants to read from
i2cData[0] = (SlaveAddress << 1) | 0; i2cData[1] = 0x05; DataSz = 2;
StartI2C1(); //Send the Start Bit IdleI2C1(); //Wait to complete
MasterWriteI2C1 (i2cData[0]); IdleI2C1();
if( I2C1STATbits.ACKSTAT ) break;
MasterWriteI2C1 (i2cData[1]); IdleI2C1();
if( I2C1STATbits.ACKSTAT ) break;
RestartI2C1(); //restarts the PCF8570P IdleI2C1();
MasterWriteI2C1( (SlaveAddress << 1) | 1 ); //transmit slave address and read command
IdleI2C1();
MasterWriteI2C1(i2cData[1]);
IdleI2C1();
unsigned char i2cbyte;
i2cbyte = MasterReadI2C1(); //PIC reads data from PCF8570P
StopI2C1(); IdleI2C1();
} }