Forum: Mikrocontroller und Digitale Elektronik PCF8591 an ATTiny2313 - I2C-Bus


von M. B. (freiberger77)


Lesenswert?

Hallo zusammen,
ich habe schon das Forum und Google durchsucht, ich finde leider nix.

Ich habe einen A/D-Wandler PCF8591 an einen ATTiny2313 angeschlossen.
Ich bekomme aber die Werte nicht ausgelesen.

Der Bus scheint vorhanden zu sein, da schon mal "> I2C - OK <" auf dem 
Display erscheint. Allerdings erscheint die Meldung auch, wenn ich die 
Adresse #define PCF8591   0b10010000 auf #define PCF8591   0b10010011 
ändere.
Wenn ich die Masse des PCF8591 entferne, kommt "> I2C - Error <".

Aber ich bekomme immer nur die 4 Analogwerte "238,238,238,236" 
angezeigt.
Habe auch schon den IC getauscht.
Diese Werte werden allerdings auch bei "> I2C - Error <" angezeigt.

Bin echt ratlos. Das Probleme mit dem PCF8591 habe ich schon oft im 
Forum gefunden, aber leider keine Lösung....

PS: Am 1. Eingang ist ein Poit (0-5V), die anderen sind unbelegt...
    SDA & SCL sind mit PullUp-Widerständen 4,7k angeschlossen

1
#define PCF8591   0b10010000    // Grundadresse aus Datenblatt 
2
3
void main()
4
{
5
  unsigned char ret;
6
  char Buffer[10];
7
8
  lcd_ini();
9
  lcd_gotopos (1, 1);
10
  lcd_writetext ("Analog-INPUT");
11
12
  i2c_init();                                // init I2C interface
13
14
  ret= i2c_start(PCF8591+I2C_WRITE);    // set device address and write mode     
15
  if (ret) {
16
    i2c_stop;
17
    lcd_gotopos (4, 1);
18
      lcd_writetext ("> I2C - Error <");
19
  }else{
20
    lcd_gotopos (4, 1);
21
       lcd_writetext 
22
23
    i2c_write(0b01000100);       // Kontrollbyte:    Bit 7 = immer 1
24
                                 // Analog Out enable=false   Bit 6
25
                                 // 4 Kanäle, 0..5V        Bit 4&5
26
                                 // Autoincrement Flag an    Bit 3
27
                                 // Kanal Null selektiert    Bit 2
28
                                 // Null auf Start- D/A-Wandler Bit 0&1
29
    i2c_write(0b00000000);   // wenn OUT an, dann 0=0Volt, 255=5Volt
30
    i2c_stop;  
31
  }                        
32
33
  while(1) 
34
   {           
35
       // Daten lesen
36
    i2c_start;                     
37
    i2c_write(PCF8591+I2C_READ);          //Leseadresse senden
38
    ret= i2c_readAck; // Analog 0
39
              lcd_writetext (itoa( ret, Buffer, 10 ));
40
       lcd_writetext (",");
41
                 ret =i2c_readAck; // Analog 1
42
       lcd_writetext (itoa( ret, Buffer, 10 ));
43
       lcd_writetext (",");
44
    ret =i2c_readAck; // Analog 2
45
       lcd_writetext (itoa( ret, Buffer, 10 ));
46
       lcd_writetext (",");
47
    ret =i2c_readNak; // Analog 3
48
       lcd_writetext (itoa( ret, Buffer, 10 ));
49
       i2c_stop;  
50
   
51
  _delay_ms(500);
52
  lcd_gotopos (2, 1);
53
  lcd_writetext ("                ");
54
  _delay_ms(200);
55
   return 0;                 // 
56
}

von Jörg G. (joergderxte)


Lesenswert?

Wo hast du die Adress-pins des pcf angeschlossen? (Ich kann im 
Datenblatt - das hast du doch auch gelesen? - nichts finden, was dafür 
spricht die nicht anzuschließen).
Dieser Kommentar ist unnötig verwirrend:
1
    i2c_write(0b01000100);
2
// Kontrollbyte:    Bit 7 = immer 1 -> Besser: bit7 ist ungenutzt
3
// Analog Out enable=false   Bit 6  -> Du schaltest es aber an
4
// 4 Kanäle, 0..5V        Bit 4&5
5
// Autoincrement Flag an    Bit 3   -> Das ist aber bit 2, Bit 3 ist auch ungenutzt
6
// Kanal Null selektiert    Bit 2
7
// Null auf Start- D/A-Wandler Bit 0&1 -> Tippfehler?
Ich würde sowas bevorzugen:
1
#define PCF8591_ANA_OUT (1<<6)
2
3
#define PCF8591_SINGLE 0
4
#define PCF8591_3DIFF (1<<4)
5
#define PCF8591_1DIFF_2SINGLE (2<<4)
6
#define PCF8591_2DIFF (3<<4)
7
8
#define PCF8591_AUTOINCR (1<<2)
9
10
#define PCF8591_ADCHANNEL(_n) ((_n) & 3)
11
12
//...
13
    i2c_write( PCF8591_ANA_OUT
14
             | PCF8591_SINGLE
15
             | PCF8591_AUTOINCR
16
             | PCF8591_ADCHANNEL(0) );
17
// ...

Außerdem misst der PCF während dem Auslesen (Im Datenblatt unter 'A/D 
Conversion'ist sogar ein Bild davon). Um deine 4 Kanäle zu lesen, musst 
du demnach 5 Bytes lesen (oder besser: ein Dummybyte nach der 
Initialisierung).
hth, Jörg

von M. B. (freiberger77)


Lesenswert?

Die 3 Adress-Pins liegen auf Masse, somit sollte die Adresse 0b10010000 
eigentlich stimmen.

von M. B. (freiberger77)


Lesenswert?

So, habe einen Fehler gefunden...
bem Auslesen hatte ich
1
ret= i2c_readAck;
, es muß aber
1
ret= i2c_readAck();
 geschrieben werden, sonst zeigt es wirre Zahlen.

Allerdings steht jetzt 4 x 255 da, obwohl am AIN0 nur ca. 3V anliegen.

Habe zum Test mal ein EEprom dazugeschalten. Aber der ausgelesene Wert 
ist auch 255 statt 09...
1
// EEPROM 24C16
2
//==============
3
  ret= i2c_start(EEPROM24C16+I2C_WRITE);    // set device address and write mode     
4
  if (ret) {
5
    // Fehler
6
    i2c_stop;
7
    lcd_gotopos (4, 1);
8
      lcd_writetext ("> I2C - Error <");
9
  }else{
10
    lcd_gotopos (4, 1);
11
       lcd_writetext ("> I2C - OK <"); 
12
    
13
// Daten schreiben
14
    i2c_write(0x00);   // Start-Adresse       
15
    i2c_write(0x09);   // Daten 
16
    i2c_stop;  
17
18
// Datel lesen
19
    i2c_start_wait(EEPROM24C16+I2C_WRITE);
20
    i2c_write(0x00);   // Start-Adresse   
21
22
    i2c_rep_start(EEPROM24C16+I2C_READ);
23
    ret =i2c_readNak();  // Daten
24
    i2c_stop; 
25
26
    lcd_gotopos (3, 1);
27
       lcd_writetext (itoa( ret, Buffer, 10 ));
28
  }

von holger (Gast)


Lesenswert?

>Habe zum Test mal ein EEprom dazugeschalten. Aber der ausgelesene Wert
>ist auch 255 statt 09...

Ein EEPROM benötigt Zeit für die Programmierung.
So 10-20ms warten nach i2cstop ist eine Lösung.
Oder Acknowledge Polling anwenden.

von M. B. (freiberger77)


Lesenswert?

OK, ich habe jetzt nach jedem i2C_stop 50ms Wartezeit.
Aber immer noch 255.
Wie kann ich testen, ob der Bus funktioniert ???

Sind die Ports am Prozessor egal ???
Ich habe SCL an PB1 und SDA an PB0, ist auch so in der i2cmaster.s 
eingetragen.
Der Prozessor läuft mit intern 4 MHZ

von holger (Gast)


Lesenswert?

>Wie kann ich testen, ob der Bus funktioniert ???

Osci oder Logikanalyzer.

von M. B. (freiberger77)


Lesenswert?

ja, wenn man sowas hätte   ;-)

von M. B. (freiberger77)


Lesenswert?

OK, FEHLER gefunden...
habe im BUS alle Adressen durchlaufen lassen, die richtigen Adressen 
wurden gefunden...

Der Fehler war klein aber fein...

Hatte überall i2c_stop;   statt i2c_stop();
Was so ein paar Klammern ausmachen...

Danke trotzdem

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.