简介一下I2C协议的规则:
一. 技术性能:
工作速率有100K和400K两种;
支持多机通讯;
支持多主控模块,但同一时刻只允许有一个主控;
由数据线SDA和时钟SCL构成的串行总线;
每个电路和模块都有唯一的地址;
每个器件可以使用电源
二. 基本工作原理:
以启动信号START来掌管总线,以停止信号STOP来释放总线;
每次通讯以START开始,以STOP结束;
启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R/W位为0表示由主控向被控器件写数据,R/W为1表示由主控向被控器件读数据;
当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号;
每个数据字节在传送时都是高位(MSB)在前;
写通讯过程:
1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
2. 发送一个地址字节(包括7位地址码和一位R/W);
3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
4. 主控收到ACK后开始发送第一个数据字节;
5. 被控器收到数据字节后发送一个ACK表示继续传送数据,发送NACK表示传送数据结束;
6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;
读通讯过程:
1. 主控在检测到总线空闲的状况下,首先发送一个START信号掌管总线;
2. 发送一个地址字节(包括7位地址码和一位R/W);
3. 当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ACK);
4. 主控收到ACK后释放数据总线,开始接收第一个数据字节;
5. 主控收到数据后发送ACK表示继续传送数据,发送NACK表示传送数据结束;
6. 主控发送完全部数据后,发送一个停止位STOP,结束整个通讯并且释放总线;
DSP中IIC模块框图:
1. 总线空闲状态
SDA和SCL两条信号线都处于高电平,即总线上所有的器件都释放总线,两条信号线各自的上拉电阻把电平拉高;
2. 启动信号START
时钟信号SCL保持高电平,数据信号SDA的电平被拉低(即负跳变)。启动信号必须是跳变信号,而且在建立该信号前必修保证总线处于空闲状态;
3. 停止信号STOP
时钟信号SCL保持高电平,数据线被释放,使得SDA返回高电平(即正跳变),停止信号也必须是跳变信号。
4. 数据传送
SCL线呈现高电平期间,SDA线上的电平必须保持稳定,低电平表示0(此时的线电压为低电压),高电平表示1(此时的电压由元器件的VDD决定)。只有在SCL线为低电平期间,SDA上的电平允许变化。
5. 应答信号ACK
I2C总线的数据都是以字节(8位)的方式传送的,发送器件每发送一个字节之后,在时钟的第9个脉冲期间释放数据总线,由接收器发送一个ACK(把数据总线的电平拉低)来表示数据成功接收。
6. 无应答信号NACK
在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个NACK,NACK有两种用途:
a. 一般表示接收器未成功接收数据字节;
b. 当接收器是主控器时,它收到最后一个字节后,应发送一个NACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。
地址模式:为了跟好的跟外部器件接口,DSP上面设计了三种地址模式
7bit地址格式:i2c的第一个字节的高7bit为器件的地址。后面的数据bit长度可以自己设定。
10bit地址格式:i2c的第一个字节的低2bit为器件的地址的高2bit,第二字节的8bit作为器件地址的低8bit。后面的数据bit长度可以自己设定。
free地址格式:i2c的第一个字节的nbit为器件的地址。后面的数据bit长度可以自己设定。
通信模式:为了跟好的跟外部器件接口,DSP上面设计了两种通信模式
NOREAPTE:就是我们上面所说的一般通信模式,一个start信号发出一个器件地址,当这个器件收到地址之后发出应答之后,就占有i2c总线,然后进行数据通信和数据的交换,只有主机发出停止信号之后才释放总线。
REAPTE:就是我们上面所说的一般通信模式,一个start信号发出一个器件地址,当这个器件收到地址之后发出应答之后就占有i2c总线,然后进行数据通信和数据的交换,之后主机可以发出start信号之后继续选址其他,然后进行数据通信,然后进行数据通信。这个个人觉得主机就像一个广播一样写一个数据就把会把写到全部器件中。
实例,我们这儿使用是I2C读写eeprom
/********************************************************************************\
\\* The routine illustrates the using method of TMS320C6713 IIC. In this example,*\
\\*Writting and reading operation on EEPROM AT24C256 are related. *\
\\********************************************************************************/
#include #include #include #include #include #include #include “DEC6713.h” #include “IIC.h” /********************************************************************************/ /* Set I2C registers. */ I2C_Config MyI2CCfgT = { I2C_FMKS(I2COAR,A,OF(0×00)), //Not used if master. I2C_FMKS(I2CIMR,ICXRDY,MSK) | I2C_FMKS(I2CIMR,ICRRDY,MSK) | I2C_FMKS(I2CIMR,ARDY,MSK) | I2C_FMKS(I2CIMR,NACK,MSK) | I2C_FMKS(I2CIMR,AL,MSK), // Master clock frequency is 200kHz(SYSCLK2 is 150MHz). I2C_FMKS(I2CCLKL,ICCL,OF(14)), I2C_FMKS(I2CCLKH,ICCH,OF(14)), I2C_FMKS(I2CCNT,ICDC,OF(6)), I2C_FMKS(I2CSAR,A,OF(80)), I2C_FMKS(I2CMDR,FREE,RFREE) | I2C_FMKS(I2CMDR,STT,START) | I2C_FMKS(I2CMDR,STP,STOP) | I2C_FMKS(I2CMDR,MST,MASTER) | I2C_FMKS(I2CMDR,TRX,XMT) | I2C_FMKS(I2CMDR,XA,7BIT) | I2C_FMKS(I2CMDR,RM,NONE) | I2C_FMKS(I2CMDR,DLB,NONE) | I2C_FMKS(I2CMDR,IRS,NRST) | I2C_FMKS(I2CMDR,STB,NONE), //? I2C_FMKS(I2CPSC,IPSC,OF(15-1)) // 10MHz }; I2C_Config MyI2CCfgR = { I2C_FMKS(I2COAR,A,OF(0×00)), I2C_FMKS(I2CIMR,ICXRDY,MSK) | I2C_FMKS(I2CIMR,ICRRDY,MSK) | I2C_FMKS(I2CIMR,ARDY,MSK) | I2C_FMKS(I2CIMR,NACK,MSK) | I2C_FMKS(I2CIMR,AL,MSK), // Master clock frequency is 200kHz(SYSCLK2 is 150MHz). I2C_FMKS(I2CCLKL,ICCL,OF(14)), I2C_FMKS(I2CCLKH,ICCH,OF(14)), I2C_FMKS(I2CCNT,ICDC,OF(4)), I2C_FMKS(I2CSAR,A,OF(80)), I2C_FMKS(I2CMDR,FREE,RFREE) | I2C_FMKS(I2CMDR,STT,START) | I2C_FMKS(I2CMDR,STP,STOP) | I2C_FMKS(I2CMDR,MST,MASTER) | I2C_FMKS(I2CMDR,TRX,RCV) | I2C_FMKS(I2CMDR,XA,7BIT) | I2C_FMKS(I2CMDR,RM,NONE) | I2C_FMKS(I2CMDR,DLB,NONE) | I2C_FMKS(I2CMDR,IRS,NRST) | I2C_FMKS(I2CMDR,STB,NONE), //? I2C_FMKS(I2CPSC,IPSC,OF(15-1)) // 10MHz }; /********************************************************************************/ I2C_Handle hI2C; Uint8 DataByte[4] = {0×21,0×02,0×05,0×20}; Uint8 DataByteE[4] = {0xFF,0xFF,0xFF,0xFF}; Uint8 ReceiveData[4] = {0,0,0,0}; Uint8 Length = 4; extern far void vectors(); main() { Uint8 i; /* Initialize CLS, must when using csl. */ CSL_init(); /* Initialize DEC6713 board. */ DEC6713_init(); IRQ_setVecs(vectors); IRQ_nmiEnable(); IRQ_globalEnable(); //start added on 2005.2.21 /* Open I2C0. */ hI2C = I2C_open(I2C_DEV0,I2C_OPEN_RESET); waitForBusFree(hI2C); I2C_config(hI2C,&MyI2CCfgT); /* Write word address to AT24C256. */ I2C_writeByte(hI2C,0×00); I2C_start(hI2C); while(!I2C_xrdy(hI2C)); I2C_writeByte(hI2C,0×00); /* Writting data to AT24C256. */ for(i=0;i while(!I2C_xrdy(hI2C)); I2C_writeByte(hI2C,DataByteE[i]); } I2C_sendStop(hI2C); waitForBusFree(hI2C); printf(“\\nWritting data is over.”); MyI2CCfgT.i2ccnt = 2; I2C_config(hI2C,&MyI2CCfgT); /* Perform dummy write operation. */ I2C_writeByte(hI2C,0×00); I2C_start(hI2C); while(!I2C_xrdy(hI2C)); I2C_writeByte(hI2C,0×00); I2C_sendStop(hI2C); waitForBusFree(hI2C); DEC6713_wait(200); /* Reading data from AT24C256. */ I2C_config(hI2C,&MyI2CCfgR); DEC6713_wait(200); I2C_start(hI2C); for(i=0;i while(!I2C_rrdy(hI2C)); ReceiveData[i] =I2C_readByte(hI2C); } I2C_sendStop(hI2C); printf(“\\nReading data is over.”); /* Comparing data. */ for(i=0;i if(ReceiveData[i] != DataByteE[i]) { printf(“\\nErasing is failure.”); exit(0); } } printf(“\\nErasing is success.”); I2C_FSETH(hI2C,I2CSTR,BB,1); I2C_reset(hI2C); I2C_close(hI2C); DEC6713_wait(0xf000); //end added on 2005.2.21 /* Open I2C0. */ hI2C = I2C_open(I2C_DEV0,I2C_OPEN_RESET); waitForBusFree(hI2C); MyI2CCfgT.i2ccnt = 6; //added on 2005.02.21 I2C_config(hI2C,&MyI2CCfgT); /* Write word address to AT24C256. */ I2C_writeByte(hI2C,0×00); I2C_start(hI2C); while(!I2C_xrdy(hI2C)); I2C_writeByte(hI2C,0×00); /* Writting data to AT24C256. */ for(i=0;i while(!I2C_xrdy(hI2C)); I2C_writeByte(hI2C,DataByte[i]); } I2C_sendStop(hI2C); waitForBusFree(hI2C); printf(“\\nWritting data is over.”); MyI2CCfgT.i2ccnt = 2; I2C_config(hI2C,&MyI2CCfgT); /* Perform dummy write operation. */ I2C_writeByte(hI2C,0×00); I2C_start(hI2C); while(!I2C_xrdy(hI2C)); I2C_writeByte(hI2C,0×00); I2C_sendStop(hI2C); waitForBusFree(hI2C); DEC6713_wait(200); /* Reading data from AT24C256. */ I2C_config(hI2C,&MyI2CCfgR); DEC6713_wait(200); I2C_start(hI2C); for(i=0;i while(!I2C_rrdy(hI2C)); ReceiveData[i] =I2C_readByte(hI2C); } I2C_sendStop(hI2C); printf(“\\nReading data is over.”); /* Comparing data. */ for(i=0;i if(ReceiveData[i] != DataByte[i]) { printf(“\\nOperation is failure.”); exit(0); } } printf(“\\nOperation is success.”); } /********************************************************************************/ //This function waits until the I2C bus busy bit is reset waitForBusFree(I2C_Handle hI2C) { //Waiting for Bit12 of ICSTR ie. BB (Bus Busy) to clear while(I2C_bb(hI2C)); } //This function waits untill the I2C bus busy bit gets set waitForBusBusy(I2C_Handle hI2C) { //Waiting for Bit12 of ICSTR ie. BB (Bus Busy) to set while(!I2C_bb(hI2C)); } /********************************************************************************/ /********************************************************************************\ \\* End of DEC6713_EEPROM.C *\ \\********************************************************************************/下载本文