⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c.txt

📁 基于AVR系列单片机实现i2c通信
💻 TXT
📖 第 1 页 / 共 2 页
字号:
00303     // disable TWI interrupt
00304     cbi(TWCR, TWIE);
00305 
00306     // send start condition
00307     i2cSendStart();
00308     i2cWaitForComplete();
00309 
00310     // if there's data to be sent, do it
00311     if(sendlength)
00312     {
00313         // send device address with write
00314         i2cSendByte( deviceAddr & 0xFE );
00315         i2cWaitForComplete();
00316         
00317         // send data
00318         while(sendlength)
00319         {
00320             i2cSendByte( *senddata++ );
00321             i2cWaitForComplete();
00322             sendlength--;
00323         }
00324     }
00325 
00326     // if there's data to be received, do it
00327     if(receivelength)
00328     {
00329         // send repeated start condition
00330         i2cSendStart();
00331         i2cWaitForComplete();
00332 
00333         // send device address with read
00334         i2cSendByte( deviceAddr | 0x01 );
00335         i2cWaitForComplete();
00336 
00337         // accept receive data and ack it
00338         while(receivelength > 1)
00339         {
00340             i2cReceiveByte(TRUE);
00341             i2cWaitForComplete();
00342             *receivedata++ = i2cGetReceivedByte();
00343             // decrement length
00344             receivelength--;
00345         }
00346 
00347         // accept receive data and nack it (last-byte signal)
00348         i2cReceiveByte(TRUE);
00349         i2cWaitForComplete();
00350         *receivedata++ = i2cGetReceivedByte();
00351     }
00352     
00353     // transmit stop condition
00354     // leave with TWEA on for slave receiving
00355     i2cSendStop();
00356     while( !(inb(TWCR) & BV(TWSTO)) );
00357 
00358     // enable TWI interrupt
00359     sbi(TWCR, TWIE);
00360 }
00361 */
00362 
00363 //! I2C (TWI) interrupt service routine
00364 SIGNAL(SIG_2WIRE_SERIAL)
00365 {
00366     // read status bits
00367     u08 status = inb(TWSR) & TWSR_STATUS_MASK;
00368 
00369     switch(status)
00370     {
00371     // Master General
00372     case TW_START:                      // 0x08: Sent start condition
00373     case TW_REP_START:                  // 0x10: Sent repeated start condition
00374         #ifdef I2C_DEBUG
00375         rprintfInit(uart1AddToTxBuffer);
00376         rprintf("I2C: M->START\r\n");
00377         rprintfInit(uart1SendByte);
00378         #endif
00379         // send device address
00380         i2cSendByte(I2cDeviceAddrRW);
00381         break;
00382     
00383     // Master Transmitter & Receiver status codes
00384     case TW_MT_SLA_ACK:                 // 0x18: Slave address acknowledged
00385     case TW_MT_DATA_ACK:                // 0x28: Data acknowledged
00386         #ifdef I2C_DEBUG
00387         rprintfInit(uart1AddToTxBuffer);
00388         rprintf("I2C: MT->SLA_ACK or DATA_ACK\r\n");
00389         rprintfInit(uart1SendByte);
00390         #endif
00391         if(I2cSendDataIndex < I2cSendDataLength)
00392         {
00393             // send data
00394             i2cSendByte( I2cSendData[I2cSendDataIndex++] );
00395         }
00396         else
00397         {
00398             // transmit stop condition, enable SLA ACK
00399             i2cSendStop();
00400             // set state
00401             I2cState = I2C_IDLE;
00402         }
00403         break;
00404     case TW_MR_DATA_NACK:               // 0x58: Data received, NACK reply issued
00405         #ifdef I2C_DEBUG
00406         rprintfInit(uart1AddToTxBuffer);
00407         rprintf("I2C: MR->DATA_NACK\r\n");
00408         rprintfInit(uart1SendByte);
00409         #endif
00410         // store final received data byte
00411         I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00412         // continue to transmit STOP condition
00413     case TW_MR_SLA_NACK:                // 0x48: Slave address not acknowledged
00414     case TW_MT_SLA_NACK:                // 0x20: Slave address not acknowledged
00415     case TW_MT_DATA_NACK:               // 0x30: Data not acknowledged
00416         #ifdef I2C_DEBUG
00417         rprintfInit(uart1AddToTxBuffer);
00418         rprintf("I2C: MTR->SLA_NACK or MT->DATA_NACK\r\n");
00419         rprintfInit(uart1SendByte);
00420         #endif
00421         // transmit stop condition, enable SLA ACK
00422         i2cSendStop();
00423         // set state
00424         I2cState = I2C_IDLE;
00425         break;
00426     case TW_MT_ARB_LOST:                // 0x38: Bus arbitration lost
00427     //case TW_MR_ARB_LOST:              // 0x38: Bus arbitration lost
00428         #ifdef I2C_DEBUG
00429         rprintfInit(uart1AddToTxBuffer);
00430         rprintf("I2C: MT->ARB_LOST\r\n");
00431         rprintfInit(uart1SendByte);
00432         #endif
00433         // release bus
00434         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00435         // set state
00436         I2cState = I2C_IDLE;
00437         // release bus and transmit start when bus is free
00438         //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTA));
00439         break;
00440     case TW_MR_DATA_ACK:                // 0x50: Data acknowledged
00441         #ifdef I2C_DEBUG
00442         rprintfInit(uart1AddToTxBuffer);
00443         rprintf("I2C: MR->DATA_ACK\r\n");
00444         rprintfInit(uart1SendByte);
00445         #endif
00446         // store received data byte
00447         I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00448         // fall-through to see if more bytes will be received
00449     case TW_MR_SLA_ACK:                 // 0x40: Slave address acknowledged
00450         #ifdef I2C_DEBUG
00451         rprintfInit(uart1AddToTxBuffer);
00452         rprintf("I2C: MR->SLA_ACK\r\n");
00453         rprintfInit(uart1SendByte);
00454         #endif
00455         if(I2cReceiveDataIndex < (I2cReceiveDataLength-1))
00456             // data byte will be received, reply with ACK (more bytes in transfer)
00457             i2cReceiveByte(TRUE);
00458         else
00459             // data byte will be received, reply with NACK (final byte in transfer)
00460             i2cReceiveByte(FALSE);
00461         break;
00462 
00463     // Slave Receiver status codes
00464     case TW_SR_SLA_ACK:                 // 0x60: own SLA+W has been received, ACK has been returned
00465     case TW_SR_ARB_LOST_SLA_ACK:        // 0x68: own SLA+W has been received, ACK has been returned
00466     case TW_SR_GCALL_ACK:               // 0x70:     GCA+W has been received, ACK has been returned
00467     case TW_SR_ARB_LOST_GCALL_ACK:      // 0x78:     GCA+W has been received, ACK has been returned
00468         #ifdef I2C_DEBUG
00469         rprintfInit(uart1AddToTxBuffer);
00470         rprintf("I2C: SR->SLA_ACK\r\n");
00471         rprintfInit(uart1SendByte);
00472         #endif
00473         // we are being addressed as slave for writing (data will be received from master)
00474         // set state
00475         I2cState = I2C_SLAVE_RX;
00476         // prepare buffer
00477         I2cReceiveDataIndex = 0;
00478         // receive data byte and return ACK
00479         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00480         break;
00481     case TW_SR_DATA_ACK:                // 0x80: data byte has been received, ACK has been returned
00482     case TW_SR_GCALL_DATA_ACK:          // 0x90: data byte has been received, ACK has been returned
00483         #ifdef I2C_DEBUG
00484         rprintfInit(uart1AddToTxBuffer);
00485         rprintf("I2C: SR->DATA_ACK\r\n");
00486         rprintfInit(uart1SendByte);
00487         #endif
00488         // get previously received data byte
00489         I2cReceiveData[I2cReceiveDataIndex++] = inb(TWDR);
00490         // check receive buffer status
00491         if(I2cReceiveDataIndex < I2C_RECEIVE_DATA_BUFFER_SIZE)
00492         {
00493             // receive data byte and return ACK
00494             i2cReceiveByte(TRUE);
00495             //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00496         }
00497         else
00498         {
00499             // receive data byte and return NACK
00500             i2cReceiveByte(FALSE);
00501             //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00502         }
00503         break;
00504     case TW_SR_DATA_NACK:               // 0x88: data byte has been received, NACK has been returned
00505     case TW_SR_GCALL_DATA_NACK:         // 0x98: data byte has been received, NACK has been returned
00506         #ifdef I2C_DEBUG
00507         rprintfInit(uart1AddToTxBuffer);
00508         rprintf("I2C: SR->DATA_NACK\r\n");
00509         rprintfInit(uart1SendByte);
00510         #endif
00511         // receive data byte and return NACK
00512         i2cReceiveByte(FALSE);
00513         //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00514         break;
00515     case TW_SR_STOP:                    // 0xA0: STOP or REPEATED START has been received while addressed as slave
00516         #ifdef I2C_DEBUG
00517         rprintfInit(uart1AddToTxBuffer);
00518         rprintf("I2C: SR->SR_STOP\r\n");
00519         rprintfInit(uart1SendByte);
00520         #endif
00521         // switch to SR mode with SLA ACK
00522         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00523         // i2c receive is complete, call i2cSlaveReceive
00524         if(i2cSlaveReceive) i2cSlaveReceive(I2cReceiveDataIndex, I2cReceiveData);
00525         // set state
00526         I2cState = I2C_IDLE;
00527         break;
00528 
00529     // Slave Transmitter
00530     case TW_ST_SLA_ACK:                 // 0xA8: own SLA+R has been received, ACK has been returned
00531     case TW_ST_ARB_LOST_SLA_ACK:        // 0xB0:     GCA+R has been received, ACK has been returned
00532         #ifdef I2C_DEBUG
00533         rprintfInit(uart1AddToTxBuffer);
00534         rprintf("I2C: ST->SLA_ACK\r\n");
00535         rprintfInit(uart1SendByte);
00536         #endif
00537         // we are being addressed as slave for reading (data must be transmitted back to master)
00538         // set state
00539         I2cState = I2C_SLAVE_TX;
00540         // request data from application
00541         if(i2cSlaveTransmit) I2cSendDataLength = i2cSlaveTransmit(I2C_SEND_DATA_BUFFER_SIZE, I2cSendData);
00542         // reset data index
00543         I2cSendDataIndex = 0;
00544         // fall-through to transmit first data byte
00545     case TW_ST_DATA_ACK:                // 0xB8: data byte has been transmitted, ACK has been received
00546         #ifdef I2C_DEBUG
00547         rprintfInit(uart1AddToTxBuffer);
00548         rprintf("I2C: ST->DATA_ACK\r\n");
00549         rprintfInit(uart1SendByte);
00550         #endif
00551         // transmit data byte
00552         outb(TWDR, I2cSendData[I2cSendDataIndex++]);
00553         if(I2cSendDataIndex < I2cSendDataLength)
00554             // expect ACK to data byte
00555             outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00556         else
00557             // expect NACK to data byte
00558             outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT));
00559         break;
00560     case TW_ST_DATA_NACK:               // 0xC0: data byte has been transmitted, NACK has been received
00561     case TW_ST_LAST_DATA:               // 0xC8:
00562         #ifdef I2C_DEBUG
00563         rprintfInit(uart1AddToTxBuffer);
00564         rprintf("I2C: ST->DATA_NACK or LAST_DATA\r\n");
00565         rprintfInit(uart1SendByte);
00566         #endif
00567         // all done
00568         // switch to open slave
00569         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWEA));
00570         // set state
00571         I2cState = I2C_IDLE;
00572         break;
00573 
00574     // Misc
00575     case TW_NO_INFO:                    // 0xF8: No relevant state information
00576         // do nothing
00577         #ifdef I2C_DEBUG
00578         rprintfInit(uart1AddToTxBuffer);
00579         rprintf("I2C: NO_INFO\r\n");
00580         rprintfInit(uart1SendByte);
00581         #endif
00582         break;
00583     case TW_BUS_ERROR:                  // 0x00: Bus error due to illegal start or stop condition
00584         #ifdef I2C_DEBUG
00585         rprintfInit(uart1AddToTxBuffer);
00586         rprintf("I2C: BUS_ERROR\r\n");
00587         rprintfInit(uart1SendByte);
00588         #endif
00589         // reset internal hardware and release bus
00590         outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)|BV(TWINT)|BV(TWSTO)|BV(TWEA));
00591         // set state
00592         I2cState = I2C_IDLE;
00593         break;
00594     }
00595 }
00596 
00597 eI2cStateType i2cGetState(void)
00598 {
00599     return I2cState;
00600 }


--------------------------------------------------------------------------------

Generated on Sun Oct 29 03:41:06 2006 for Procyon AVRlib by   1.4.2 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -