void I2cISR (void) { INT8U addFlag; addFlag = 0; switch (I2STAT) { case 0x00: //Bus Error has occured I2CON = GENERATE_STOP; break; case 0x08: //(rep) Start condition transmitted case 0x10: //Slave slvadd+R/W are transmitted I2DAT = pMsg[cbyMsg]->slvadd; I2CON = RELEASE_BUS_ACK; break; case 0x18: //SLA+W transmitted,ACK received DATA or STOP will be transmitted //已经发送完了SLA+W,接下来开始发送第一个地址字节 addFlag = 1; I2DAT = pMsg[cbyMsg]->buf[cbyBuf]; I2CON = RELEASE_BUS_ACK; break; case 0x28: //DATA transmitted,ACK received DATA or STOP will be transmitted //已经发送了I2DAT的一个字节,接下来再次发送I2DAT里的数据字节 if (addFlag == 1){ I2DAT = pMsg[cbyMsg]->buf[cbyBuf + 1]; I2CON = RELEASE_BUS_ACK; } else {
if (cbyBuf < pMsg[cbyMsg]->nrBytes) { //一个信息里的字节还没有发送完,接着发送 I2DAT = pMsg[cbyMsg]->buf[cbyBuf++]; I2CON = RELEASE_BUS_ACK; } else { //发送下一个信息 cbyMsg++; if (cbyMsg < nrMessage) { cbyBuf = 0; //next message I2CON = RELEASE_BUS_STA; //generate (rep)START } else { I2CON = GENERATE_STOP; drvStatus = I2C_OK; } //end if } //end if } //end if break; case 0x20: //发送完SLA+W,但未收到ACK,发送停止信号 case 0x48: //SLA+W/R transmitted NOT ACK received drvStatus = I2C_NACK_ON_ADDRESS; //driver finished I2CON = GENERATE_STOP; break; case 0x30: //DATA transmitted,NOT ACK received drvStatus = I2C_NACK_ON_DATA; I2CON = GENERATE_STOP; break; case 0x38: //Arbitration lost in SLA+W or DATA I2CON = RELEASE_BUS_STA; //release bus,set STA break; case 0x40: //SLA+R transmitted,ACK received if (pMsg[cbyMsg]->nrBytes == 1) I2CON = RELEASE_BUS_NOACK; //NOT ACK on next byte else I2CON = RELEASE_BUS_ACK; //ACK on next byte break; case 0x50: //DATA received,ACK has been returned pMsg[cbyMsg]->buf[cbyBuf++] = I2DAT; //read next data if (cbyBuf + 1 ==pMsg[cbyMsg]->nrBytes) //next byte the lase? I2CON = RELEASE_BUS_NOACK; //NO ACK on next byte else I2CON = RELEASE_BUS_ACK; //return ACK break; case 0x58: //DATA received, NOT ACK has been returned pMsg[cbyMsg]->buf[cbyBuf] = I2DAT; //read last data cbyMsg++; if (cbyMsg < nrMessage) { cbyBuf = 0; //next message I2CON = RELEASE_BUS_STA; //generate (rep)START } else { I2CON = GENERATE_STOP; drvStatus = I2C_OK; } break; default:; } }