I2C Kein ACK :-(

OP #4013228
Lesenswert?

Habe eine Atmega32 16Mhz  TC74 Sensor mit I2C verbunden ( Pull up sind 
dran)

1 Schritt Frequenz einstellen

TWSR = 0;
TWBR = ((F_CPU/SCL_CLOCK)-16)/2;   // 72

2 Schritt Startbedingung

       TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
       while(!(TWCR & (1<<TWINT))); // Prüfen

3 Schritt Adresse ( 7 Bit) + Low (1 Bit)  Für das Schreiben

I2C_sende(0x90); // Hier kommt immer  Kein ACK

 void I2C_sende(int daten)
 {
   TWDR = daten;
    TWCR = (1<<TWINT)  | (1<<TWEN);
    while  (!(TWCR & (1<<TWINT))); // Warte bis gesendet
    if((TWSR & 0xF8) != TW_MT_DATA_ACK)
    {
      USART_putstring("Kein ACK");
    }
    else
    {
      USART_putstring("ACK");
    }

 }

Was mache ich Falsch ?
Habe es schon mit Adresse 0x00 Probiert auch kein Ack
OP #4013283
Lesenswert?

Mein Code leider geht es immer noch nicht.
Hast du ein anderen Tipp?

#define F_CPU 16000000UL
#define BAUD 9600                                   // define baud
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1)
 #define SCL_CLOCK  100000 //100 kHz

#include <avr/io.h>
#include <util/delay.h>
#include <util/twi.h>
#include<stdbool.h>
#include "USART.h"
#include <avr/io.h>
void I2C_sende(int daten)
{
  TWDR = daten;
  TWCR = (1<<TWINT)  | (1<<TWEN);
  while  (!(TWCR & (1<<TWINT))); // Warte bis gesendet
  if((TWSR & 0xF8) != TW_MT_DATA_ACK)
  {
    USART_putstring("Kein ACK!!!");
  }
  else
  {
    USART_putstring("ACK");
  }

}
 void I2C_start(int adresse)
 {
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
   while(!(TWCR & (1<<TWINT)));
   int twst = TW_STATUS & 0xF8;
   if ( (twst != TW_START) && (twst != TW_REP_START))
   {
     USART_putstring("Fehler beim Start ");
   }
   else
   {
     USART_putstring("Kein Fehler beim Start ");
   }


   I2C_sende(adresse);


 }

 void I2C_init(void)
 {
   DDRC &= !((1<<DD0)|(1<<DD1));
   PORTC = (1<<DD0)|(1<<DD1);
   TWSR = 0;                         /* no prescaler */
   TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable 
operation */


 }
int main(void)
{
  USART_init();
    I2C_init();

  TWSR = 0;
  TWBR = ((F_CPU/SCL_CLOCK)-16)/2;   // 72
  I2C_start(0x9B);


    while(1)
    {
        //TODO:: Please write your application code
    }
}
Angehängte Dateien:
#4013675
Lesenswert?

Joe M. schrieb:
> TW_STATUS passt mir ja, dass klappt alles.

Deine Aussage war bisher doch, du würdest auf die Adresse kein ACK 
kriegen. Dein Code dafür sieht bisher so aus:
1
  if((TWSR & 0xF8) != TW_MT_DATA_ACK)
2
  {
3
    USART_putstring("Kein ACK!!!");
4
  }
Dieser Code ist jedoch nur für Datenbytes im Master-Transmit geeignet, 
nicht aber für das Adressbyte in egal welchem Modus, da die Statemachine 
des TWI auch bei einer erfolgreichen Adressierung des Slave 
keinesfalls TW_MT_DATA_ACK liefert.

Eben darauf wollte ich dich mit dem Hinweis stossen, dass es wesentlich 
sinnvoller wäre, statt
  USART_putstring("Kein ACK!!!");
sowas wie
  USART_puthex("TWI Status=", TWST);
auszugeben. Damit du siehst, was tatsächlich passiert.

> Bekomme einfach kein ACK

Basierend auf Oszi/LA-Anzeige, oder basierend auf dem obigen Code? Dein 
Code ist für diese Aussage nicht geeignet. Der zeigt nur, dass du nicht 
jenen Status kriegst, den du erwartest hast.
OP #4014063
Lesenswert?

Habe es  Danke sehr vielen dank :-D Jetzt klappt das ACK.
ok
Jetzt das 2 Problem.
Der Sensor sendet keine Daten

         i2c_init();
   i2c_start(0x9A); // Start Cond+ Sendet Adresse + SchreibBit
   i2c_write(0x00);   // Code für das lesen der Temp.
   i2c_start(0x9A+1);  //Start Cond+ Adresse + LeseBit
   int a = i2c_readNak(); // Hier kommt leider nur 0 raus :-(
   i2c_stop();

Was im I2C Angezeigt wird:
s     (Start Cod.)
9A A (Sendet 9A bekommt ACK)
00 A (Sendet 00 bekommt ACK)
Sr    (Start Cod.)
9B A   (Sendet 9B bekommt ACK)
00 N   (Beim lesen überträgt er nur 0er Bits)
p    ( Stop bed.)
Gast #4464013
Lesenswert?

Hallo,

ich versuche gerade die RTC RV-3029-C2 in Betrieb zu nehmen, leider ohne
Erfolg. Ich nutze Altmelstudio 7 mit Codevision-Plugin. Zum lesen und
schreiben über I2C/TWI nutze ich die twi_master_trans(). Andere I2C
Busteilnehmer konnte ich damit erfolgreich auslesen und schreiben. Zu
Testzwecken ist die RTC nun alleine am BUS. In Anhang findet Ihr ein
Oszi Bild. Dort ist zu sehen das die RTC kein ACK sendet. Pullups sind
jeweils 2,7k. Wo könnte der Fehler liegen? Achso, die twi_master_trans()
Funktion gibt auch zurück das ein ACK fehlt. SCL Rate ist 400k bps. 100k
bps geht aber auch nicht.

Danke schon im Vorraus :-)

Elektrischer Anschluss:
PIN1: 3,29V (gemessen)
PIN2: Offen
PIN3: Offen
PIN4: SCL (siehe Oszibild - CH Gelb)
PIN5: SDA (siehe Oszibild - CH Blau)
PIN6: 0V (gemessen)
PIN7: Offen
PIN8: 0V (gemessen, über 10k Pulldown an GND angeschlossen)
PIN9: Offen
PIN10: Offen

Quellcodeausschnitt:

#define I2C_ADRESSE  0xAC

//Nachrichten IDs
typedef enum {
  //Controll Page
  RTC_CONTROL1 = 0x00        ,      //
  RTC_CONTROL_INT            ,
  RTC_CONTROL_INT_FLAG       ,
  RTC_CONTROL_STATUS         ,
  RTC_CONTROL_RESET          ,
  // Clock Page
  RTC_SECONDS = 0x08         ,
  RTC_MINUTES                ,
  RTC_HOURS                  ,
  RTC_DAYS                   ,
  RTC_WEEKDAYS               ,
  RTC_MONTHS                 ,
  RTC_YEARS                  ,
  // ALARM PAGE
  RTC_SECOND_ALARM = 0x10    ,
  RTC_MINUTE_ALARM           ,
  RTC_HOUR_ALARM             ,
  RTC_DAY_ALARM              ,
  RTC_WEEKDAY_ALARM          ,
  RTC_MONTH_ALARM            ,
  RTC_YEAR_ALARM             ,
  // TIMER PAGE
  RTC_TIMER_LOW = 0x18       ,
  RTC_TIMER_HIGH             ,
  // TEMPERTUR PAGE
  RTC_TEMPERATURE = 0x20     ,
  // EEPROM USER PAGE
  RTC_EEPROM_USER1 = 0x28    ,
  RTC_EEPROM_USER2           ,
  // EEPROM CONTROL PAGE
  RTC_EEPROM_CONTROL = 0x30  ,
  RTC_EEPROM_XTAL_OFFSET     ,
  RTC_EEPROM_XTAL_COEF       ,
  RTC_EEPROM_XTAL_T0         ,
  // EEPROM CONTROL PAGE
  RTC_USER_RAM =     0x38    ,
  // Size
  RTC_SIZE     =     0x3F    ,
}tRTC_REG_ID;

void twie_init(void)
{
  // General TWIE initialization
  // External Driver Interface: OFff
  // SDA Hold: Off
  twi_init(&TWIE,false,TWI_SDAHOLD_OFF_gc);
  // Note: The directions of the SDA_IN (PORTE Pin 0), SCL_IN (PORTE Pin
1),
  // SDA_OUT (PORTE Pin 2) and SCL_OUT (PORTE Pin 3) signals are
configured
  // in the ports_init function

  // TWIE Master initialization
  // Master interrupt: Low Level
  // Peripheral Clock frequency: 32000000 Hz
  // SCL Rate: 400000 bps
  // Real SCL Rate: 400000 bps, Error: 0,0 %
  twi_master_init(&twie_master,&TWIE,TWI_MASTER_INTLVL_LO_gc,
  TWI_BAUD_REG(32000000,400000));

  // TWIE Slave is disabled
  TWIE.SLAVE.CTRLA=0;
}

void RTC_SetRegister(tRTC_REG_ID StartReg, uint8_t *Data, uint8_t Anz)
{
  uint8_t TX_Buffer[16];

  TX_Buffer[0] = StartReg;
  if(Anz < 16)
  {
    memcpy(&TX_Buffer[1], Data, Anz);
    twi_master_trans(&twie_master, I2C_ADRESSE, TX_Buffer, Anz + 1, 0,
0);
  }
}

void RTC_GetRegister(tRTC_REG_ID StartReg, uint8_t *Data, uint8_t Anz)
{
  uint8_t TX_Buffer[32];
  TX_Buffer[0] = StartReg;
  twi_master_trans(&twie_master, I2C_ADRESSE, TX_Buffer, 1, Data, Anz);
}
Angehängte Dateien:
#4464085
Lesenswert?

ehrlich?

ich würde die Fleury LIB installieren.
http://homepage.hispeed.ch/peterfleury/avr-software.html

Als letztes Zeichen muss ja NACK kommen und nicht ACK.
Ich würde nicht immer auf 16 Zeichen Antwort warten, ich weiss doch wie 
viel Zeichen ich erwarte und für das letzte muss es NACK sein.

Dann gibt es noch I2C Stretching auch das wäre zu prüfen, da neheme ich 
immer die Arduino LIB und versuche den Slave solange anzusprechen bis er 
wieder antwortet, kann ja auch mit einem Timeout kombiniert werden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren