I2C(Inter -Integrated Circuit)总线是一种由Philips公司开发的两线式串行总线,用于连接微控制器及其外围设备。I2C总线产生于在80年代,最初为音频和视频设 备开发。由于其简单性,如今方泛用于微控制器与各种功能模块的连接,可以说是学单片机的人,入门之后,必定要涉及到的。
I2C 总线实际上已经成为一个国际标准在超过100 种不同的IC 上实现,而且得到超过50 家公司的许可,正因为其简单和应用广泛,因此其功能也越来不满足人们的要求,其速度也从原来的100Kbit/S,增加了快速模式,其速度达 400Kbit/S,再后来也增加了高速模式,其速度更达3.4Mbit/S。
二.功能和特点
I2C 总线是一种用于IC器件之间连接的双向二线制总线,所谓总线它上面可以挂多少器件,并且通个两根线连接,占用空间非常的小,总线的长度可高达25英尺,并 且能够以10Kbps的最大传输速率支持4个组件。它的另一优点是多主控,只要能够进行接收和发送的设备都可以成为主控制器,当然多个主控不能同一时间 工作。
I2C总线有两根信号线,一根为SDA(数据线),一根为SCL(时钟线)。任何时候时钟信号都是由主控器件产生。
I2C总线在传送数据的过程中,主要有三种控制信号:起始信号,结不信号,应答信号
起始信号:当SCL为高电平时,SDA由高电平转为低电平时,开始传送数据
结束信号:当SCL为高电平时,SDA由低电平转为高电平时,结束数据传送
应答信号:接收数据的器件在接收到8bit数据后,向发送数据的器件发出低电平信号,表示已收到数据。这个信号可以是主控器件发出,也可以是从动器件发出。总之由接收数据的器件发出。
这些信号中,起始信号是必需的,结束信号和应答信号,都可以不要。
#include "MSP430x14x.h" //P2.0 SCL //P2.1 SDA #define SDA_1 P2OUT |= BIT3 //SDA = 1 #define SDA_0 P2OUT &=~ BIT3 //SDA = 0 #define SCL_1 P2OUT |= BIT2 //SCL = 1 #define SCL_0 P2OUT &=~ BIT2 //SCL = 0 #define DIR_IN P2DIR &=~ BIT3; SDA_1 //I/O口为输入 #define DIR_OUT P2DIR |= BIT3 //I/0口为输出 #define SDA_IN ((P2IN >> 3) & 0x01) //Read SDA unsigned int a[50]; static void Delay(unsigned int n) { unsigned int i; for (i=0; i } void Init(void) { SCL_1; Delay(5); SDA_1; Delay(5); } void Start(void) { SDA_1; Delay(5); SCL_1; Delay(5); SDA_0; Delay(5); SCL_0; Delay(5); } void Stop(void) { SDA_0; Delay(5); SCL_1; Delay(5); SDA_1; Delay(5); } void WriteByte(unsigned char WriteData) { unsigned char i; for (i=0; i<8; i++) { SCL_0; Delay(5); if (((WriteData >> 7) & 0x01) == 0x01) { SDA_1; } else { SDA_0; } Delay(5); SCL_1; WriteData = WriteData << 1; Delay(5); } SCL_0; SDA_1; Delay(5); Delay(5); } unsigned char ReadByte(void) { unsigned char i; unsigned char TempBit = 0; unsigned char TempData = 0; SCL_0; Delay(5); SDA_1; for (i=0; i<8; i++) { Delay(5); SCL_1; Delay(5); DIR_IN; if (SDA_IN == 0x01 /*sda==1*/) { TempBit = 1; } else { TempBit = 0; } DIR_OUT; TempData = (TempData << 1) | TempBit; SCL_0; } Delay(5); return(TempData); } void ReceiveAck(void) { unsigned char i = 0; SCL_1; Delay(5); DIR_IN; while ((SDA_IN == 0x01 /*sda==1*/) && (i < 255)/*调试方便,可以不要*/) { i++; } DIR_OUT; SCL_0; Delay(5); } void Acknowledge(void) { SCL_0; Delay(5); DIR_OUT; SDA_0; SCL_1; Delay(5); SCL_0; } unsigned int ReadWord(unsigned char unit/*address*/) { unsigned char HighData = 0; unsigned char LowData = 0; unsigned int TempData = 0; Start(); WriteByte(0xa0); ReceiveAck(); WriteByte(unit); ReceiveAck(); Start(); WriteByte(0xa1); ReceiveAck(); LowData = ReadByte(); Acknowledge(); HighData = ReadByte(); Stop(); TempData = (HighData << 8) + LowData; Delay(1000); return(TempData); } void ReadWords(unsigned char unit/*address*/) { unsigned char i; unsigned char HighData = 0; unsigned char LowData = 0; unsigned int TempData = 0; Start(); WriteByte(0xa0); ReceiveAck(); WriteByte(unit); ReceiveAck(); Start(); WriteByte(0xa1); ReceiveAck(); for (i=0; i<49; i++) { LowData = ReadByte(); Acknowledge(); HighData = ReadByte(); Acknowledge(); a= (HighData << 8) + LowData; } LowData = ReadByte(); Acknowledge(); HighData = ReadByte(); Stop(); a[49] = (HighData << 8) + LowData; Delay(1000); } void WriteWord(unsigned char unit/*address*/, unsigned int WriteData) { unsigned char LowData = 0; unsigned char HighData = 0; LowData = (unsigned char)WriteData; HighData = (unsigned char)(WriteData >> 8); Start(); WriteByte(0xa0); ReceiveAck(); WriteByte(unit); ReceiveAck(); WriteByte(LowData); ReceiveAck(); WriteByte(HighData); ReceiveAck(); Stop(); Delay(2000); } void Read24C64(unsigned int ADDR,unsigned char *s,unsigned char no) { // uchar ddata=0; unsigned char ADDR_L,ADDR_H,i; ADDR_L=ADDR%256; ADDR_H=ADDR/256; IIC_START (); IIC_TX_DATA (0xA0); delay(50); IIC_TX_DATA (ADDR_H); delay(50); IIC_TX_DATA (ADDR_L); delay(50); IIC_START (); IIC_TX_DATA (0xA1); delay(50); for(i=0;i<no;i++) { s= IIC_RX_DATA(); if(i!=no-1) { IIC_ACK (); } } delay(50); IIC_STOP (); } void Write24C64(unsigned int ADDR,unsigned char *ddata,unsigned char no) { unsigned char ADDR_H,ADDR_L,i; ADDR_L=ADDR%256; ADDR_H=ADDR/256; SDA_OUT; IIC_START (); IIC_TX_DATA (0xA0); // E2PROM 片选 IIC_TX_DATA (ADDR_H); // 大于256BIT的EEPROM需加地址高位 IIC_TX_DATA (ADDR_L); for(i=0;i<no;i++) { IIC_TX_DATA(ddata); delay(50); } IIC_STOP (); delay (0x3FFF); // 等待写时序 } main() { unsigned char temp[32]; unsigned char temp1[32]={9,5,3,4,5,6,7,8,23,10,11,12,13,14,15,16,17,18, 19,20,21,22,23,24,25,26,27,28,29,30,11,33}; Write24C64(0x0030,temp1,8); delay(0x5000); Read24C64(0x0030,temp,8); delay(1000); }
用户403664 2012-11-20 15:08
wxg1988 2012-11-20 12:24