(Inter-Integrated Circuit) I2C (Inter-Integrated Circuit)
I2C (Inter-Integrated Circuit) I²C reference design จะกำหนดให้มี Address 7-bit (มีที่สงวนใว้ 16 addresses) ทำให้สามารถมี Device ได้ถึง 112 nodes ที่สื่อสารกันได้ใน Bus เดียวกัน โดยทั่วไปแล้ว I²C bus speeds จะเป็น 100 kbit/s standard mode หรือ 10 kbit/s low-speed mode ปัจจุบันข้อกำหนดของ I²C จะมี node ได้มากขึ้น และทำงานที่ ความเร็วมากขึ้น (400 kbit/s Fast mode, 1 Mbit/s Fast mode plus or Fm+, and 3.4 Mbit/s High Speed mode) จะใช้กันมากใน embedded systems
Reference design ระบบจะเชื่อมต่อด้วยสายสัญญาณ สองเล้น clock (SCL) และ data (SDA) โดย Node ที่อยู่บน BUS นี้ จะแบ่งตามหน้าที่ได้สองแบบคือ Master node — node ที่จ่ายสัญญาณ clock และ addresses ของ slaves Slave node — node ที่รับสัญญาณ clock line และ address. ในระบบของ I2C จะสามารถทำ multi-master ได้ (มี master node ได้มากกว่าหนึ่ง) และ ในระหว่างการสื่อสาร master และ slave node อาจสลับหน้าที่กันได้อีกด้วย ซึ่งจะสรุปเป็นลักษณะการทำงานของแต่ละ Node ได้ 4 รูปแบบ แต่อย่างไรก็ดี โดยมากแล้วอุปกรณ์ใน BUS จะทำงานในหน้าที่เดียว (master or slave) master transmit — master node is sending data to a slave master receive — master node is receiving data from a slave slave transmit — slave node is sending data to the master slave receive — slave node is receiving data from the master
Physical layer At the physical layer, both SCL & SDA lines are of open-drain design, thus, pull-up resistors are needed. Pulling the line to ground is considered a logical zero while letting the line float is a logical one. When idle, both lines are high. To start a transaction, SDA is pulled low while SCL remains high. Releasing SDA to float high again would be a stop marker, which would be pointless immediately after a start, so the next step is to pull SCL low. When one node is transmitting a logical one (i.e., letting the line float to Vdd) and another transmits a logical zero then the first node can sense this because the line is not in a logical one state — it is not pulled up to Vdd. When used on SCL, this is called "clock stretching" and gives slaves a flow control mechanism. When used on SDA, this is called arbitration and ensures there is only one transmitter at a time.
I2C Signal START bit (S) when SDA is pulled low while SCL stays high. Then, SDA sets the transferred bit while SCL is low (blue) and the data is sampled (received) when SCL rises (green). When the transfer is complete, a STOP bit (P) is sent by releasing the data line to allow it to be pulled up while SCL is constantly high.
รูปแบบของสัญญาณข้อมูลใน I2C จะประกอบด้วย Start Condition Address R/W ACK DATA Stop Condition
เมื่อ Master ต้องการส่งข้อมูลให้ Slave จะมีลำดับสัญญาณคือ MASTER set Start Condition MASTER transmit target slave addresses (7-bit address << 1) รวมกับ บิต 0 ที่เป็น 0 เพื่อบอกว่าต้องการส่งข้อมูล Target SLAVE จะตอบรับ ด้วยสัญญาณ ACK MASTER transmit 1 Data Byte Target SLAVE จะตอบรับ ด้วยสัญญาณ ACK หรือ NACK MASTER set Stop Condition
เมื่อ Master ต้องการรับข้อมูลจาก Slave จะมีลำดับสัญญาณคือ MASTER set Start Condition MASTER transmit target slave addresses (7-bit address << 1) รวมกับ บิต 0 ที่เป็น 1 เพื่อบอกว่าต้องการรับข้อมูล Target SLAVE จะตอบรับ ด้วยสัญญาณ ACK MASTER receive 1 Data Byte (Target SLAVE Send data) MASTER จะตอบรับ ด้วยสัญญาณ ACK หรือ NACK (เมื่อต้องการสิ้นสุด) MASTER set Stop Condition
I2C Applications I²C จะเหมาะในการสื่อสารกับอุปกรณ์ร่วมอื่นๆ เมื่อต้องการความเรียบง่ายของวงจร ต้นทุนที่ต่ำกว่า มีความสำคัญมากกว่าความเร็วในการทำงาน การใช้งานของ I²C bus เช่น: Reading configuration data from SPD EEPROMs on SDRAM, DDR SDRAM, DDR2 SDRAM memory sticks (DIMM) and other stacked PC boards Supporting systems management for PCI cards, through an SMBus 2.0 connection. Accessing NVRAM chips that keep user settings. Accessing low speed DACs and ADCs. Changing contrast, hue, and color balance settings in monitors (Display Data Channel). Changing sound volume in intelligent speakers. Controlling OLED/LCD displays, like in a cellphone. Reading hardware monitors and diagnostic sensors, like a CPU thermostat and fan speed. Reading real-time clocks. Turning on and turning off the power supply of system components.
ตัวอย่างการใช้งานในเครื่องโทรศัพท์แบบไร้สาย โดย IC ที่มีหน้าที่การทำงานต่างๆ จะเชื่อมต่อกันด้วย I2C Bus Microcontroller จะควบคุมการทำงานส่วนต่างๆ ได้ การออกแบบวงจร และ PCB จะประหยัดพื้นที่
เปรียบเทียบการใช้งาน
Master Synchronous Serial Port PIC MSSP Module Master Synchronous Serial Port
I2C Mode The MSSP module in I2C mode fully implements all master and slave functions (including general call support) and provides interrupts on Start and Stop bits in hardware to determine a free bus (multi-master function). The MSSP module implements the standard mode specifications, as well as 7-bit and 10-bit addressing. Two pins are used for data transfer: Serial clock (SCLx) – RC3/SCK1/SCL1 or RD6/SCK2/SCL2 Serial data (SDAx) – RC4/SDI1/SDA1 or RD5/SDI2/SDA2 The user must configure these pins as inputs by setting the associated TRIS bits.
SLAVE Mode Block Diagram when used in SLAVE Mode
MASTER Mode Block Diagram when used in MASTER Mode
Registers The MSSP module has six registers for I2C operation. These are: MSSP Control Register 1 (SSPxCON1) MSSP Control Register 2 (SSPxCON2) MSSP Status Register (SSPxSTAT) Serial Receive/Transmit Buffer Register (SSPxBUF) MSSP Shift Register (SSPxSR) – Not directly accessible MSSP Address Register (SSPxADD) SSPxCON1, SSPxCON2 and SSPxSTAT are the control and status registers in I2C mode operation. The SSPxCON1 and SSPxCON2 registers are readable and writable. SSP1ADD, SSP2ADD are used as The Address of the device when operate in slave mode BAUD rate generator counter when operate in master mode
SSPxSR is the shift register used for shifting data in or out SSPxSR is the shift register used for shifting data in or out. SSPxBUF is the buffer register to which data bytes are written to or read from. SSPxADD register holds the slave device address when the MSSP is configured in I2C Slave mode. When the MSSP is configured in Master mode, the lower seven bits of SSPxADD act as the Baud Rate Generator reload value. In receive operations, SSPxSR and SSPxBUF together create a double-buffered receiver. When SSPxSR receives a complete byte, it is transferred to SSPxBUF and the SSPxIF interrupt is set. During transmission, the SSPxBUF is not double-buffered. A write to SSPxBUF will write to both SSPxBUF and SSPxSR.
BAUD RATE In I2C Master mode, the Baud Rate Generator (BRG) reload value is placed in the lower 7 bits of the SSPxADD register When a write occurs to SSPxBUF, the Baud Rate Generator will automatically begin counting. The BRG counts down to ‘0’ and stops until another reload has taken place. The BRG count is decremented twice per instruction cycle (TCY) on the Q2 and Q4 clocks. In I2C Master mode, the BRG is reloaded automatically. Once the given operation is complete (i.e., transmission of the last data bit is followed by ACK), the internal clock will automatically stop counting and the SCLx pin will remain in its last state.
I2C Programming
Peripheral Function libraries มีฟังก์ชันสำหรับการใช้งาน MSSE เป็น I2C ให้แล้ว โดย #include <plib.h>
Example I2C Application MCP23017 I2C IO Expander
MCP23017 I2C I/O Expander Features 16-bit remote bidirectional I/O port I/O pins default to input High-speed I2C™ interface (MCP23017) 100 kHz 400 kHz 1.7MHz High-speed SPI interface (MCP23S17) 10 MHz (max.) Three hardware address pins to allow up to eight devices on the bus Configurable interrupt output pins Configurable as active-high, active-low or open-drain INTA and INTB can be configured to operate independently or together Configurable interrupt source Interrupt-on-change from configured register defaults or pin changes Polarity Inversion register to configure the polarity of the input port data External Reset input
Function Block Diagram
Registers The MCP23X17 contains 22 individual registers (11 register pairs) that can be addressed through the Serial Interface block
I2C INTERFACE I2C Write Operation The I2C write operation includes the control byte and register address sequence. This sequence is followed by eight bits of data from the master and an Acknowledge (ACK) from the MCP23017. The operation is ended with a Stop (P) or Restart (SR) condition being generated by the master.
I2C Read Operation I2C Read operations include the control byte sequence. This sequence is followed by another control byte (including the Start condition and ACK) with the R/W bit set (R/W = 1). The MCP23017 then transmits the data contained in the addressed register. The sequence is ended with the master generating a Stop or Restart condition.
Example 2 I2C Connection
Example program MCP23017 ตัวบน มี Address คือ 0 กำหนดให้มีการทำงานดังนี้ Reset MCP23017 ทั้งสองตัว ทำการกำหนด GPIOA ของ MCP23017 ตัวล่างให้เป็น Output while ( 1) อ่านค่าจาก GPIOA ของ MCP23017 ตัวบน ส่งค่าที่อ่านได้ ไปยัง GPIOA ของ MCP23017 ตัวล่าง
Example Program //Reset MCP กำหนดให้ RE0 เป็น Output แล้วให้ค่าเป็น 0 เพื่อ Reset หน่วงเวลา แล้วให้ค่าเป็น 1
CloseI2C1() สำหรับปิดการทำงานของ I2C ถ้ามันเปิดอยู่ก่อนหน้า void CloseI2C1( void ) { SSP1CON1 &= 0xDF; // disable synchronous serial port } OpenI2C1( MASTER,SLEW_OFF) สำหรับเปิดการทำงานให้เป็น Master mode IdleI2C1() สำหรับการตรวจสอบว่า BUS ว่างอยู่หรือไม่ StartI2C1() สำหรับการ สร้าง Start condition
กำหนดค่าเริ่มต้นของ Register void OpenI2C1( unsigned char sync_mode, unsigned char slew ) { SSP1STAT &= 0x3F; // power on state SSP1CON1 = 0x00; // power on state SSP1CON2 = 0x00; // power on state SSP1CON1 |= sync_mode; // select serial mode SSP1STAT |= slew; // slew rate on/off I2C1_SCL = 1; // Set SCL1 (PORTC,3) pin to input I2C1_SDA = 1; // Set SDA1 (PORTC,4) pin to input SSP1CON1 |= SSPENB; // enable synchronous serial port } กำหนดค่าเริ่มต้นของ Register ตั้งให้เป็นการทำงานที่ต้องการ #define SSPENB 0b00100000 #define MASTER 0b00001000 #define SLEW_OFF 0b10000000
void IdleI2C1( void ) { while ( ( SSP1CON2 & 0x1F ) | ( SSP1STATbits void IdleI2C1( void ) { while ( ( SSP1CON2 & 0x1F ) | ( SSP1STATbits.R_W ) ) continue; } void StartI2C1( void ) { SSP1CON2bits.SEN = 1; // initiate bus start condition void StopI2C1( void ) { SSP1CON2bits.PEN = 1; // initiate bus stop condition void RestartI2C1( void ) { SSP1CON2bits.RSEN = 1; // initiate bus restart condition void AckI2C1( void ) { SSP1CON2bits.ACKDT = 0; // set acknowledge bit state ACK SSP1CON2bits.ACKEN = 1; // initiate acknowledge sequence void NotAckI2C1( void ) { SSP1CON2bits.ACKDT = 1; // set acknowledge bit not ACK
signed char WriteI2C1( unsigned char data_out ) { SSP1BUF = data_out; // write single byte to SSP1BUF if ( SSP1CON1bits.WCOL ) // test if write collision occurred return ( -1 ); // if WCOL bit is set return negative # // for master mode while( SSP1STATbits.BF ); // wait until write cycle is complete IdleI2C1(); // ensure module is idle if ( SSP1CON2bits.ACKSTAT ) // test for ACK condition received return ( -2 ); //Return NACK else return ( 0 ); //Return ACK } unsigned char ReadI2C1( void ) { SSP1CON2bits.RCEN = 1; // enable master for 1 byte reception while ( !SSP1STATbits.BF ); // wait until byte received return ( SSP1BUF ); // return with read byte