视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
DSP(TMS320C6713)入门之旅五、I2C的理解和使用
2025-09-30 22:49:50 责编:小OO
文档
一般DSP上面都集成了I2C模块,这样在连接外部器件时可以很方便的控制外部的器件。I2C基本上都是用于外部控制的,因为是是串行总线。在我们的实验板上I2C总线连接到了两个从设备上面,一个是我们的eeprom,另一个是我们的音频芯片AIC23。通过I2C协议我们写入和读取eeprom数据,控制AIC23的声音一些属性!

简介一下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 *\

\\********************************************************************************/下载本文

显示全文
专题