DSP28335I2C接口应用

实用文档

} // end of write section

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

// Read data from EEPROM section //该过程包括两次发送START位,第一次发送地址 ///////////////////////////////////

// Check outgoing message status. Bypass read section if status is // not inactive.

if (I2cMsgOut1.MsgStatus == I2C_MSGSTAT_INACTIVE) {

// Check incoming message status.

if(I2cMsgIn1.MsgStatus == I2C_MSGSTAT_SEND_NOSTOP) { Read_load_num1++;

// EEPROM address setup portion

while(I2CA_ReadData(&I2cMsgIn1) != I2C_SUCCESS) {

// Maybe setup an attempt counter to break an infinite while //这里可以设置一个计数器用于终止可能存在的无限循环。 // loop. The EEPROM will send back a NACK while it is performing//当EEPROM忙于处理写数据操作时,将返回一个NACK。 // a write operation. Even though the write communique is //对DSP来说,此刻写操作已经完成。但是,EEPROM仍需要 // complete at this point, the EEPROM could still be busy //一定时间完成数据的烧写1.8ms左右。在EEPROM完成烧写之前,都会

// programming the data. Therefore, multiple attempts are //返回NACK,告诉DSP它还在忙。因此,DSP需要多次尝试,直到

// necessary. //EEPROM空闲了,并返回ACK确认为止。 }

// Update current message pointer and message status CurrentMsgPtr = &I2cMsgIn1;

I2cMsgIn1.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP_BUSY;

//第一次发送START成功,即地址数据已发送成功,给发无停止位数据忙状态,作为第二次发送START位标志 }

// Once message has progressed past setting up the internal address//一旦成功写入EEPROM地址,便可以再次发送START起始位

// of the EEPROM, send a restart to read the data bytes from the //然后从EEPROM存储器中读取数据。 // EEPROM. Complete the communique with a stop bit. MsgStatus is //DSP采可用一个停止位来结束数据接收。 // updated in the interrupt service routine. //msg状态在中断程序中被更新了。 else if(I2cMsgIn1.MsgStatus == I2C_MSGSTAT_RESTART) //该状态是在中断服务程序中态被赋予 { Read_load_num2++; // Read data portion

while(I2CA_ReadData(&I2cMsgIn1) != I2C_SUCCESS) {

// Maybe setup an attempt counter to break an infinite while // loop. }

文案大全

实用文档

// Update current message pointer and message status CurrentMsgPtr = &I2cMsgIn1;

I2cMsgIn1.MsgStatus = I2C_MSGSTAT_READ_BUSY;

//第二次发送START,且数据接收成功,给下一个状态-读忙,作为中断中读取接收缓存中数据的标志 }

} // end of read section

} // end of for(;;) } // end of main

void I2CA_Init(void) {

// Initialize I2C

I2caRegs.I2CSAR = 0x0050;

#if (CPU_FRQ_100MHZ) I2caRegs.I2CPSC.all = 9; #endif

#if (CPU_FRQ_60MHZ) I2caRegs.I2CPSC.all = 6; #endif

I2caRegs.I2CCLKL = 95; I2caRegs.I2CCLKH = 95;

// NOTE: must be non zero // NOTE: must be non zero // Enable SCD & ARDY interrupts

// Prescaler - need 7-12 Mhz on module clk

// Prescaler - need 7-12 Mhz on module clk

// Slave address - EEPROM control code

I2caRegs.I2CIER.all = 0x24;

I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset

// Stop I2C when suspended

//0b0000 0000 0010 0000,NACKMOD=0,FREE=0中断产生时IIC停止运行,STT=0不产生开始位,

//STP=0不产生停止位,MST=0从模式,TRX=0接收模式,XA=0 七位地址模式,RM=0不重复,DLB=0无回来 //IRS=1使能I2C模块,STB=0模块未处在开始字节模式,FDF=0自由数据格式被禁止 //注意:TRX决定AT24C1024设备地址中的R/W,这里R/W=1读数据 I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,

return; }

Uint16 I2CA_WriteData(struct I2CMSG *msg) {

Uint16 i;

// Wait until the STP bit is cleared from any previous master communication.

文案大全

实用文档

// Clearing of this bit by the module is delayed until after the SCD bit is // set. If this bit is not checked prior to initiating a new message, the // I2C could get confused. if (I2caRegs.I2CMDR.bit.STP == 1) {

return I2C_STP_NOT_READY_ERROR; }

// Setup slave address

I2caRegs.I2CSAR = msg->SlaveAddress;

// Check if bus busy

if (I2caRegs.I2CSTR.bit.BB == 1) {

return I2C_BUS_BUSY_ERROR; }

////////判断总线空闲后进行数据发送//////// // Setup number of bytes to send // MsgBuffer + Address

I2caRegs.I2CCNT = msg->NumOfBytes+2; //递减

// Setup data to send

I2caRegs.I2CDXR = msg->MemoryHighAddr; I2caRegs.I2CDXR = msg->MemoryLowAddr; // for (i=0; iNumOfBytes-2; i++) for (i=0; iNumOfBytes; i++) {

I2caRegs.I2CDXR = *(msg->MsgBuffer+i); }

// Send start as master transmitter

I2caRegs.I2CMDR.all = 0x6E20; // 按以下参数配置IIC并使能IIC

//【0b0110 1110 0010 0000,NACKMOD=0,FREE=1中断产生时IIC能继续运行,STT=1产生开始位】

//【STP=1产生停止位,MST=1主模式,TRX=1发送,XA=0 七位地址模式,RM=0不重复,DLB=0无回路,IRS=1使能I2C模块,STB=0,FDF=0】 //开始发送数据,I2CCNT 递减模式统计数据到达0时产生中断,且产生停止位 //注意:TRX决定AT24C1024设备地址中的R/W,这里R/W=0写数据模式 return I2C_SUCCESS; }

Uint16 I2CA_ReadData(struct I2CMSG *msg)

{ //要完成一次读数据任务:要产生两个START位,产生第1个START位之后发送设备地址和数据地址; //产生第2个START位之后写入设备地址,并开始接收存储器提供的数据。

文案大全

实用文档

// Wait until the STP bit is cleared from any previous master communication. // Clearing of this bit by the module is delayed until after the SCD bit is // set. If this bit is not checked prior to initiating a new message, the // I2C could get confused. if (I2caRegs.I2CMDR.bit.STP == 1) {

return I2C_STP_NOT_READY_ERROR; }

I2caRegs.I2CSAR = msg->SlaveAddress;

if(msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP) //产生第一个START位之后发送设备地址和数据地址//// {

// Check if bus busy

if (I2caRegs.I2CSTR.bit.BB == 1) {

return I2C_BUS_BUSY_ERROR; }

I2caRegs.I2CCNT = 2; // 设置发送数据字节数-递减模式-等0时可以允许产生stop位(若使能STP) I2caRegs.I2CDXR = msg->MemoryHighAddr;//发送要读取数据的开始地址 I2caRegs.I2CDXR = (msg->MemoryLowAddr); I2caRegs.I2CMDR.all = 0x2620;

// 按以下参数配置IIC并使能IIC

//【STT =1发送起始位,STP=0不产生停止位,MST=1主模式,TRX=1发送,IRS=1使能I2C模块】

} // 开始发送数据I2CCNT 递减模式统计数据到达0时产生中断,但是没有产生停止位 //注意:TRX决定AT24C1024设备地址中的R/W,这里R/W=0写数据

else if(msg->MsgStatus == I2C_MSGSTAT_RESTART)//产生第2个START位之后发送设备地址,然后开始接收存储器提供的数据// {

I2caRegs.I2CCNT = msg->NumOfBytes; // 设置数据接收字节数量 I2caRegs.I2CMDR.all = 0x2C20;

// 按以下参数配置IIC并使能IIC

// 【STT =1发送起始位,STP=1产生停止位,MST=1主模式,TRX=0接收,IRS=1使能I2C模块】 } //开始接收数据,I2CCNT递减模式统计数据到达0时产生中断,有产生停止位 //注意-TRX决定AT24C1024设备地址中的R/W,这里R/W=1读数据

return I2C_SUCCESS; //到此说明发送地址/读取数据成功 }

interrupt void i2c_int1a_isr(void) // I2C-A {

Uint16 IntSource, i;

all_ISRC_number++;//统计所有中断次数 // Read interrupt source

IntSource = I2caRegs.I2CISRC.all;

文案大全

实用文档

// Interrupt source = stop condition detected if(IntSource == I2C_SCD_ISRC) {

SCD_ISRC_number++;

// If completed message was writing data, reset msg to inactive state if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_WRITE_BUSY) {

CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE;//发送完成,便换为未启动状态;说明可以进行下一次写数据 } else {

// If a message receives a NACK during the address setup portion of the // EEPROM read, the code further below included in the register access ready // interrupt source code will generate a stop condition. After the stop // condition is received (here), set the message status to try again. // User may want to limit the number of retries before generating an error. if(CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY)//发送无停止位地址忙 {

CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;//更新为发送停止位状态,可允许下一发送地址 }

// If completed message was reading EEPROM data, reset msg to inactive state // and read data from FIFO.

else if (CurrentMsgPtr->MsgStatus == I2C_MSGSTAT_READ_BUSY) //读数据忙状态,说明可对接收缓存器I2CDRR进行接收数据读取了

{

CurrentMsgPtr->MsgStatus = I2C_MSGSTAT_INACTIVE; //设为未启状态动,再读数据,这样允许下一次写数据到EEPROM for(i=0; i < I2C_NUMBYTES; i++) {

CurrentMsgPtr->MsgBuffer[i] = I2caRegs.I2CDRR; }

// Check recieved data //读完接收到的数据,接下来进行判断数据是否准确 for(i=0; i < I2C_NUMBYTES; i++) {

if(I2cMsgIn1.MsgBuffer[i] == I2cMsgOut1.MsgBuffer[i]) {

PassCount++; } else {

FailCount++; } }

文案大全

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4