Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Poszukuje procedur do obsługi AVR w trybie slave(raczej TWI)

17 Wrz 2007 16:12 1292 2
  • Poziom 38  
    Witam, jeżeli ktoś posiada dostęp do wyżej wymienionych procedur, prosiłbym o podzielenie się:)

    Albo pokierowanie na konkretny adres - szukajka i google nic konkretnego dla mnie nie znajdują:(
    Procedurki najchętniej ASM, ale C też przerobię na własne potrzeby.

    Pozdrawiam Łukasz.
  • Pomocny post
    Poziom 19  
    Proszę:

    Code:
    /******************************************************************************
    
    ******************************************************************************/
    static void I2C_Slave_Initialise(u8_t I2C_ownAddress)
    {
       TWAR = I2C_ownAddress;         // set own I2C slave address

       TWAMR = MASK_ADDRESS; //<<I2C_ADR_BITS;

       // I2C Interface enabled
       TWCR = (1<<TWEN)|
       // enable I2C Interupt and clear the flag
       (1<<TWIE)|(1<<TWINT)|
       // prepare to ACK next time the Slave is addressed
       (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
       //
       (0<<TWWC);

    }


    /******************************************************************************/
    static u8_t Process_I2C(void)
    {
       u8_t I2C_WriteCompleted = 0;

       if(TWCR & (1<<TWINT)) {
       switch (TWSR & 0xF8)
       {

          // own SLA+R has been received; ACK has been returned
          case I2C_STX_ADR_ACK:
             I2C_BufferIndex = 0;
             SlaveAddress = TWDR & 0xFE;
             if(SlaveAddress == EEPROM_I2C_SLAVE_ADDRESS) {
                TWDR = EEPROM_read();
             } else if(SlaveAddress == CONTROL_I2C_SLAVE_ADDRESS) {
                TWDR = REGS_Read();
             }

             // I2C Interface enabled
             TWCR = (1<<TWEN)|
             // Enable I2C Interupt and clear the flag to send byte
             (1<<TWIE)|(1<<TWINT)|
             //
             (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
             //
             (0<<TWWC);

             break;

          // Data byte in TWDR has been transmitted; ACK has been received
          case I2C_STX_DATA_ACK:
             if(SlaveAddress == EEPROM_I2C_SLAVE_ADDRESS) {
                TWDR = EEPROM_read();
             } else if(SlaveAddress == CONTROL_I2C_SLAVE_ADDRESS) {
                TWDR = REGS_Read();
             }
             // I2C Interface enabled
             TWCR = (1<<TWEN)|
             // Enable I2C Interupt and clear the flag to send byte
             (1<<TWIE)|(1<<TWINT)|
             //
             (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
             //
             (0<<TWWC);
             break;

          // Data byte in TWDR has been transmitted; NACK has been received.
          case I2C_STX_DATA_NACK:

             // Put I2C Transceiver in passive mode.
             // Enable I2C-interface and release I2C pins
             TWCR = (1<<TWEN)|
             // disable Interupt
             (1<<TWIE)|(1<<TWINT)|
             // do not acknowledge on any new requests
             (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
             //
             (0<<TWWC);
             break;

       //=============================================================================

          // General call address has been received; ACK has been returned
          case I2C_SRX_GEN_ACK:

          // Own SLA+W has been received ACK has been returned
          case I2C_SRX_ADR_ACK:
             SlaveAddress = TWDR;

             // Set buffer pointer to first data location
             I2C_BufferIndex = 0;

             // Reset the I2C Interupt to wait for a new event.
             // I2C Interface enabled
             TWCR = (1<<TWEN)|
             // enable I2C Interupt and clear the flag to send byte
             (1<<TWIE)|(1<<TWINT)|
             // expect ACK on this transmission
             (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
             //
             (0<<TWWC);
             break;

          case I2C_SRX_ADR_DATA_ACK:

          case I2C_SRX_GEN_DATA_ACK:
             {
                u8_t tmp = TWDR;
                // Reset the I2C Interupt to wait for a new event.
                // I2C Interface enabled
                TWCR = (1<<TWEN)|
                // enable I2C Interupt and clear the interrupt flag
                (1<<TWIE)|(1<<TWINT)|
                // send ACK after next reception
                (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
                //
                (0<<TWWC);

                if(SlaveAddress == EEPROM_I2C_SLAVE_ADDRESS) {
                   I2C_Buffer[I2C_BufferIndex++] = tmp;
                } else if(SlaveAddress == CONTROL_I2C_SLAVE_ADDRESS) {
                   if(I2C_BufferIndex == 0) {
                      REGS_SetCurrentAddress(tmp);
                   } else {
                      REGS_WriteRegister(tmp);
                   }
                   I2C_BufferIndex++;
                }
             }
             break;

          // A STOP condition or repeated START condition has been
          // received while still addressed as Slave
          case I2C_SRX_STOP_RESTART:
             // I2C Interface enabled
             TWCR = (1<<TWEN)|
             // enable I2C Interupt and clear the flag to send byte
             (1<<TWIE)|(1<<TWINT)|
             // send ACK after next reception
             (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
             //
             (0<<TWWC);
             if(I2C_BufferIndex && (SlaveAddress == EEPROM_I2C_SLAVE_ADDRESS)){
                I2C_WriteCompleted = 1;
             }
             break;

          case I2C_SRX_ADR_DATA_NACK:

          case I2C_SRX_GEN_DATA_NACK:

          // Last data byte in TWDR has been transmitted (TWEA = 0);
          // ACK has been received
          case I2C_STX_DATA_ACK_LAST_BYTE:

          case I2C_BUS_ERROR:

          default:
             // Store TWSR and automatically sets clears noErrors bit.
             // Reset I2C Interface
             TWCR = (1<<TWEN)|
             // enable I2C Interupt and clear the flag to send byte
             (1<<TWIE)|(1<<TWINT)|
             // send ACK after next reception
             (1<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|
             //
             (0<<TWWC);
             break;
          }
       }
       return I2C_WriteCompleted;
    }


    W kodzie pozostałości od zapisu/odczytu z EEPROM należy usunąć ;) -zostało z mojego projektu.
  • Poziom 38  
    Dzięki wielkie:) Jakby ktoś miał w asm to chętnie też zobaczę:)