- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 3 von 3

Thema: Problem beim Auslesen von ADC mit I2C

  1. #1

    Problem beim Auslesen von ADC mit I2C

    Anzeige

    Praxistest und DIY Projekte
    Hallo zusammen,

    ich will einen I2C-12bit ADC ADS7828 auslesen und habe gerade ein Problem bei dem ich nicht weiterkomme. Da ich mich in Bascom mit dem Buch von Walter eingearbeitet habe, hab ich seine Unterprogramme fuer I2C uebernommen, aber die machen wahrscheinlich nicht viel anderes, als die Standard-Bascom I2C Befehle. Bisher jedenfalls konnte ich problemlos EEPROMs und auch den CMPS03 damit ansteuern.

    Nun zum Problem:

    Ich steuere den ADC wie im Datenblatt beschrieben an und bekomme auch richtige Statuscodes zurueck. Nur beim Auslesen des 12bit-ADC-Werts funktioniert was nicht.
    Nach dem wiederholten Startbefehl, sende ich die Slaveadresse im Lesemodus und danach sollte ich High- und Lowbyte des AD-Wertes empfangen koennen. Nach dem Highbyte muesste ein ACK und nach dem Lowbyte, also dem letzten Byte ein NACK kommen. Nur leider bekomme ich schon nach dem ersten Byte (dem Highbyte) einen Statuscode H58, also Datenbyte empfangen NACK zurueck.

    Was mach ich da falsch?

    Ich hoffe, ich hab mein Problem einigermassen verstaendlich beschrieben und hoffe, dass mir jemand auf die Spruenge helfen kann.

    Danke im voraus!

    Viele Gruesse,
    Stefan

    Code:
    '************************************************************** 
    'ads7828_test.bas : Testprogramm fuer den I2C-ADC ADS7828 
    '************************************************************** 
     
    $regfile = "m8def.dat" 
    $crystal = 3686400 
    $baud = 9600 
     
    Declare Function Twistart() As Byte 
    Declare Function Twisend(byval Databyte As Byte) As Byte 
    Declare Function Twireceive(byref Databyte As Byte) As Byte 
    Declare Sub Twistop() 
     
    Dim I As Byte                                      'temporaere Variable fuer Statuscodes 
    Dim Highdatabyte As Byte 
    Dim Lowdatabyte As Byte 
    Dim Result As Word 
     
    Twsr = &B00000000  'Bits1+0=00: TWI-Vorteilung 1 
    Twbr = 0   'Twi-Prescale 
     
    Do 
      'Ch0 auslesen: 
     
      If Twistart() <> &H08 Then Goto Raus                 'START-Signal generieren 
      If Twisend(&B10010000) <> &H18 Then Goto Raus             'Slave-Adresse im Sendemodus senden                                  
      If Twisend(&B10001100) <> &H28 Then Goto Raus             'Commandbyte senden, Byte7=1 SinglEndInp                                                
                                                               'Byte6+5+4=Ch0,Byte3+2=RefOn+ADCon 
     
      If Twistart() <> &H10 Then Goto Raus                      'erneutes START-Signal 
      If Twisend(&B10010001) <> &H40 Then Goto Raus             'SlvAdr(R) senden 
     
      I = Twireceive(highdatabyte) 
      Printbin I; 
      If I <> &H50 Then Goto Raus                               'Highbyte empfangen ->ACK 
     
      I = Twireceive(lowdatabyte) 
      Printbin I; 
      If I <> &H58 Then Goto Raus                               'Lowbyte empfangen ->NO ACK 
     
      Raus: 
      Twistop 
     
      'Print "*"; 
      'Print Highdatabyte; 
      'Print "+"; 
      'Print Lowdatabyte; 
      Shift Highdatabyte , Left , 4 
      Result = Highdatabyte + Lowdatabyte 
      'Print Result 
      Waitms 500 
    Loop 
     
     
    '================================================================================ 
    ========= 
    Function Twistart() As Byte 
      Twcr = &B10100100                                         'START-Signal erzeugen 
      Do : Loop Until Twcr.twint = 1                            'Warten bis fertig 
      Twistart = Twsr And &B11111000                            'Status-Code zurückgeben 
    End Function 
    '------------------------------------------------------------------------------------------ 
    Function Twisend(byval Databyte As Byte) As Byte 
      Twdr = Databyte                                           'Byte ins Datenregister 
      Twcr = &B10000100                                         'TWI-Operation starten 
      Do : Loop Until Twcr.twint = 1                            'Warten bis fertig 
      Twisend = Twsr And &B11111000                             'Status-Code zurückgeben 
    End Function 
    '------------------------------------------------------------------------------------------ 
    Function Twireceive(byref Databyte As Byte) As Byte 
      Twcr = &B10000100                                         'TWI-Operation starten 
      Do : Loop Until Twcr.twint = 1                            'Warten bis fertig 
      Databyte = Twdr 
      Twireceive = Twsr And &B11111000                          'Status-Code zurückgeben 
    End Function 
    '------------------------------------------------------------------------------------------ 
    Sub Twistop() 
      Twcr = &B10010100                                         'STOP-Signal erzeugen 
    End Sub 
    '-------------------------------------------------------------------------------

  2. #2
    Also irgendwie ist da Ganze sehr komisch... Ich habs jetzt mal mit den "herkoemmlichen" Bascom-I2C-Befehlen versucht und da funktionierts! Also nach folgendem Strickmuster:

    i2cstart
    i2cwbyte adres_write
    i2cwbyte command_byte
    i2cstart
    i2cwbyte adres_read
    i2crbyte highbyte, ack
    i2crbyte lowbyte, nack
    i2cstop

    so gehts. Ich wuerd aber zu gerne wissen, warum ich das mit den anderen Subroutinen nicht auch hinbekomme. Ich mach doch im Endeffekt dasselbe!

    Hat da denn keiner ne Idee???

    Wie gesagt, mit den Subroutinen kann ich prima EEPROMs beschreiben und lesen, nur bei diesem ADC komm ich nicht weiter!

    Ciao,
    Stefan

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    ich sehe nur das TWBR auf 0 gesetzt wird, der Prescaler ist auch auf 1 also läuft der Bus mit maximaler Geschwindigkeit.
    Wenn ich richtig gerechnet habe ca. 230kHz.
    Da im Atmel-Datenblatt steht, das es bei einem Wert in TWBR kleiner 10 zu Problemen mit der Startsequenz kommen kann, solltest Du mal probieren hier den richtigen berechneten Wert bei TWBR einzusetzen, bzw. nicht kleiner als 10.

    Edit:
    mit 10 hat der Bus knapp über 100kHz, also eigentlich immer noch ein wenig zu schnell, aber besser als vorher.
    siehe -> TWI

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress