Forum: Mikrocontroller und Digitale Elektronik SMBUS mit Atmega RRc2040


von Franz S. (franz_0815)


Lesenswert?

Hallo
Gestern habe ich eine PCF8583 mit dem AT90CANxx verbunden und 
angesteuert.
mit hilfe von der
/*********************************************************************** 
**
* Title:    I2C master library using hardware TWI interface
* Author:   Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury

library hat sehr schnell funktioniert.

nun versuche ich eine Akku Pack RRc2040 mit dem SMBus auszulesen.

Dieser hat 2 Datenbyte pro register.
leider klappt das so noch nicht.

habe auch uart0 und uart1 eingestellt.

 uint16_t i2c_read_byte_16(uint8_t adr,uint8_t reg)
  {
     uint8_t ret1,ret2;
     i2c_start_wait(adr);     // set device address and write mode
     i2c_write(reg);          // write address = reg
     i2c_rep_start(adr+1);    // set device address and read mode
     ret1 = i2c_readAck();    // read one byte from EEPROM
     ret2 = i2c_readNak();    // read one byte from EEPROM
     i2c_stop();
     return(ret1*0xff+ret2);
  }

das system bleibt in der routine
i2c_start_wait(adr);

hängen.

Mit dem Ozsi sehen die Signale gut aus.
Adressierung habe ich auch schon durchgetestet.

Irgendwas mit dem TWI BUS ??

von franz_0815 (Gast)


Lesenswert?

Moin alle die sich mit I2C /TWI Atmega auskennen

Wie oben beschrieben versuche ich ein Akku Pak auszulesen.

PCF8583 klappt super.

Bei dem Akku Pack wird das TWCR Register nicht richtig gesetzt.

void i2c_start_wait(unsigned char address)
{
    uint8_t   twst;


    while ( 1 )
    {
      // send START condition
!!!>>>      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
      // wait until transmission completed
  do
  {
!!!>>>  USART0_Transmit(TWCR);

//    PORTF^=(1<<PF7);
  }
      while(!(TWCR & (1<<TWINT)));

      // check value of TWI Status Register. Mask prescaler bits.
      twst = TW_STATUS & 0xF8;
      if ( (twst != TW_START) && (twst != TW_REP_START)) continue;

      // send device address
      TWDR = address;
      TWCR = (1<<TWINT) | (1<<TWEN);

      // wail until transmission completed
      while(!(TWCR & (1<<TWINT)));

      // check value of TWI Status Register. Mask prescaler bits.
      twst = TW_STATUS & 0xF8;
      if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
      {
          /* device busy, send stop condition to terminate write 
operation */
          TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

          // wait until stop condition is executed and bus released
          while(TWCR & (1<<TWSTO));

          continue;
      }
      //if( twst != TW_MT_SLA_ACK) return 1;
      break;
     }
//   SETPIN(LED_F7);


}/* i2c_start_wait */

---------------
Hier bleibt das programm hängen.
  do
  {
!!!>>>  USART0_Transmit(TWCR);

//    PORTF^=(1<<PF7);
  }

Rückgabe über uart ist 0x24

Oh man oh man.

Muss noch eine interuppt routine erstellt werden ?

Früher bei den 8051 musste doch auch bei jedem Slave in den CLK und 
Daten Leitung ein 330R Widerstand eingebaut werden.
Ist das nicht mehr erforderlich. ?

Jemmand ein Idee ?

Gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.