Sunteți pe pagina 1din 6

I2CCommunicationInformationPackets

Amasterinitiatingawritetransactionofnbytes 0=write nbytesofdatatransferred

Slave Address R/W


Frommastertoslave Fromslavetomaster A /A S P

A
= = = =

DATA

A ... DATA

A/A

Acknowledge (SDA = Low) Not Acknowledge (SDA = Hi) Start Condition Stop Condition

Amasterinitiatingareadtransactionofnbytes: 1 =read nbytesofdatatransferred

Slave Address R/W

DATA

A ... DATA

/A

I2CCommunicationbetweenTwoPICMicrocontrollers

PICasI2CMaster

PICasI2CSlave

PICI2CSlave Peripheral SCL SDA Gnd SCL SDA Gnd

Slavewritedata i2c_write()byslave Slavereaddata i2c_read()bySlave state=i2c_isr_state()

SSPInterrupt

// I2C Example: Pseudo-code within Master PIC for 2-byte read and 2-byte // write transactions. #define ACK 1 #define NO_ACK 0 union IO { struct { unsigned int8 lsb; unsigned int8 msb; } abyte; unsigned int16 aword; }; union IO R, W; void main() { // Main program in Master : // Master receive-code immediately follows. // Master reads 2-bytes transmitted by the Slave and saves as variable, W. // The Slave.c code is on the next page. i2c_start(); i2c_write(0xA1); // // // W.abyte.lsb=i2c_read(ACK); // // W.abyte.msb=i2c_read(NO_ACK); // // i2c_stop(); // : Start I2C transaction Least significant bit (1) specifies read from the Slave with address 0xA0/0xA1 Read first/next byte from slave with ACK asserted by the Master Read LAST byte from slave with NO_ACK by the Master End I2C transaction

// Master transmit-code immediately follows. // The Master transmits 2-bytes (that comprise the variable, R) to the Slave. ?? The Slave.c code, is on the next page. R=16-bit signed value; i2c_start(); i2c_write(0xA0); i2c_write(R.abyte.lsb); i2c_write(R.abyte.msb); i2c_stop(); : } // // // // // // Start I2C transaction Least significant bit (0)specifies write to the Slave with address 0xA0/0xA1 Write first/next byte to Slave Write last byte to Slave End I2C transaction

// // // // // // // //

Pseudo Code within the Slave PIC. The SSP interrupt routine implements the operation of the I2C Slave. The interrupt routine reads or write 2-bytes with each transaction that is initiated by the Master. Whenever a read transaction is initiated (by the Master) the Slave will write the two bytes that comprise the 16-bit variable, X. Whenever a write transaction is initiated (by the Master) the Slave will read the two bytes that comprise the 16-bit variable (sent by the Master) and stores as variable Rslave.

union IO { struct { unsigned int8 lsb; unsigned int8 msb; } abyte; unsigned int16 aword;}; union Rslave, X; // Globals unsigned int8 SendBuffer(2), ReceiveBuffer(2); void main() { // Main program in Slave : X=16-bit value; } #INT_SSP // I2C Interrupt handler within the slave. void i2c_interrupt() { BYTE state, incoming; state = i2c_isr_state(); // Note: state increments with each subsequent byte received or sent. // state == 0: address match detected by slave. // state 0x01 to 0x7F: Slave should read the first/next byte transmitted by // the Master. // state == 0x80 to 0xFF: Slave should write the first/next byte of a read // transaction initiated by the Master. if(state >= 0x80) { if(state > 0x82) {I2C_Errror=1; break;} // Error because the Master was programmed to read/receive 2-bytes only. else { if(state == 0x80) { // Starting a new 2-byte transaction. SendBuffer[0]=X.abyte.lsb; // Load SendBuffer[] within the SendBuffer[1]=X.abyte.msb; // interrupt handler as an atomic } // operation. i2c_write(SendBuffer[state-0x80]; } else { incoming = i2c_read(); if(state > 2) { I2C_Errror=2; break;} // Error because the Master was programmed to send/transmit 2-bytes only. else { ReceiveBuffer[state-1]=incoming; if(state == 2) { // Update Rslave within Rslave.abyte.lsb=ReceiveBuffer[0]; // interrupt handler as Rslave.abyte.msb=ReceiveBuffer[1]; // an atomic operation. } } }

I2CusingaPICasMasterandaPICasSlaveWriteTransactionbyMaster

SCLdrivenby Master R/W =0 SDAdrivenby Master 1 0 1 0 0 0 0 0 z 0 0 0 0 0 0 0 0 z 0 1 1 0 0 0 0 0 z

SDAdrivenby Slave

z ACK*

z ACK*

z ACK*

0/1

SSPinterrupt inSlave i2c_isr_state() state=0x00 state=0x01 state=0x02

i2c_start(); w=i2c_write(0x0A0); x=i2c_write(0x00); y=i2c_write(0x61); i2c_stop(); MASTERCODE ACK*heldlowbyslavewhileslaveservicesinterrupt. zdenotespininhiimpedance.

I2CusingaPICasMasterandaPICasSlaveReadTransactionbyMaster

SCLdrivenby Master R/W =1 SDAdrivenby Master 1 0 1 1 0 0 0 1 z z z z z z z z z ACK 0 z z z z z z z z NO_ACK 1

SDAdrivenby Slave

z ACK*

SSPinterrupt inSlave i2c_isr_state() state=0x80 state=0x81 state=0x82

i2c_start(); w=i2c_write(0x0A0); x=i2c_read(ACK); y=i2c_read(NO_ACK); i2c_stop(); MASTERCODE ACK*heldlowbyslavewhileslaveservicesinterrupt. ACKheldlowbymasterfollowingfirst/nextread. NO_ACKbymasterfollowinglastread.zdenotespininhiimpedancestate.

S-ar putea să vă placă și