Forum: Mikrocontroller und Digitale Elektronik PCF8591 als DAC mit 15 kHz überfordert?


von Chris (Gast)


Lesenswert?

Ich habe meinen ATMega 328 an einen PCF8591 angeschlossen, der als DAC 
arbeiten soll. Die ADC Funktion benötige ich momentan nicht.

Mein Programm habe ich nach der Anleitung unter 
http://www.mikrocontroller.net/articles/AVR_TWI geschrieben.

Prescaler habe ich auf 1 gesetzt und mein µC läuft mit 8 MHz. TWBR 
Register habe ich auf 255 gesetzt. Damit komme ich auf eine SCL-Frequenz 
von ca. 15kHz mit der entsprechenden Formel im Datenblatt.

Zum Test lasse ich in einer Endloschleife Werte von 0-255 ausgeben und 
würde also eine Rampe erwarten. Der Output sieht zwar entfernt nach 
Rampe aus, aber es werden viele Werte übersprungen. Wenn ich den CPU 
Takt auf 1MHz setze, sieht die Rampe deutlich besser aus, aber immer 
noch werden Werte übersprungen.

Hat irgendjemand eine Idee, woran es liegen könnte?

von Pfitsche (Gast)


Lesenswert?

Ich sehe das in Deinem Schaltpan die Abblockkondensatoren fehlen.
Ausserdem ist die Last an dem Ausgang des DAC viel zu hoch.

...und in Deinem Sourcecode vermisse ich das volatile von der im 
interrupt genutzten Variable !

So kann das ja nix werden.

von Chris (Gast)


Lesenswert?

Falls der Post grade heißen sollte "schick doch Schaltplan und Code mit 
du Pappnase", will ich dem mal nachkommen.:-)

Abblockkondensatoren habe ich drin. Die Last am DAC Ausgang ist der 
OSzilloskopeingang. Pullup Widerstände am I2C Bus sind momentan 1k. Ich 
hatte auch schon 10k und 100k ausprobiert, aber das hat nichts 
verändert. Zum Schaltplan...es sind nur auf dem Breadboard die I2C Pins 
des µC mit dem DAC verbunden. Gespeist wird das Ganze von einem 
Labornetzteil.

void ERROR(int pin)
{
  PORTD = pin;
}

void SendValue(int value)
{
  TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);  //TWSTA = TWI START 
Condition Bit

  while  (!(TWCR & (1<<TWINT)));        //Warten bis TWINT wieder im 
TWCR gesetzt ist, dann kanns weiter gehen

  if ((TWSR & 0xF8) != TW_START)
    ERROR(_BV(PORTD7)); 
//Fehlerbehandlung

  TWDR = 0x90;  //Slave Adresse senden 1 0 0 1 0 0 0 0

  TWCR = (1<<TWINT) | (1<<TWEN); //Senden des Paketes

  while (!(TWCR & (1<<TWINT))); //Warten bis TWINT wieder im TWCR 
gesetzt ist, dann kanns weiter gehen

  if ((TWSR & 0xF8) != TW_MT_SLA_ACK) //Fehlerbehandlung
    ERROR(_BV(PORTD6));

  TWDR = 0x40;  //Control Byte 0 1 0 0 0 0 0 0 0x40 Analog out 
anschalten, Rest egal
  TWCR = (1<<TWINT) | (1<<TWEN); //Senden des Paketes

  while (!(TWCR & (1<<TWINT))); //Warten bis TWINT wieder im TWCR 
gesetzt ist, dann kanns weiter gehen

  if ((TWSR & 0xF8) != TW_MT_DATA_ACK) //Fehlerbehandlung
    ERROR(_BV(PORTD5));

  TWDR = value;  //Daten Byte setzen
  TWCR = (1<<TWINT) | (1<<TWEN); //Senden des Paketes

  while (!(TWCR & (1<<TWINT))); //Warten bis TWINT wieder im TWCR 
gesetzt ist, dann kanns weiter gehen

  if ((TWSR & 0xF8) != TW_MT_DATA_ACK) //Fehlerbehandlung
    ERROR(PORTD4);

  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // Senden des Stop

  if ((TWSR & 0xF8) != TW_MT_DATA_ACK) //Fehlerbehandlung
    ERROR(_BV(PORTD3));
}

int main(void)
{
  DDRD = 0xff;
  PORTD = 0;
  TWBR = 0xff;

    while(1)
    {
    for(int i = 0; i <255;++i)
    {
      SendValue(i);
    }
    }
}

von Peter D. (peda)


Lesenswert?

Mach doch einfach mal nen Überschlag:
I2C max 100kHz, für 8 Bit Daten brauche ich 20 Zyklen (Start, Adresse, 
ACK, Daten, ACK, Stop), also kann ich maximal 100k / 20 = 5kSamples 
erreichen im best Case.

von Chris (Gast)


Lesenswert?

Das ist nicht das Problem. Ich habe die I2C Frequenz auf 15kHz und 
trotzdem sehe ich anstatt 255 Treppenstufen nur 9 Stufen imt dem oben 
geposteten Code. Bei 120kHz sinds dann nur noch 2-3 Treppenstufen.

Im Endeffekt bräuchte ich eine I2C Frequenz von ca. 220kHz, weil ich ca. 
8k Daten pro Sekunde schicken muss. Meine Frage ist eben, wieso schon 
bei so niedriger Frequenz der DAC anscheinend nicht mehr mitkommt.

von Sebastian H. (technik_freak)


Lesenswert?

Kurze Frage:

Nachdem Du den Stop-Befehl gesendet hast, erfolgt m.W. eine Abfrage, ob 
diese Bedingung erfüllt wurde, die hier wohl fehlt.

Ich kenne diese Vorgehensweise bei PIC-Controllern(Sprut.de), wo 
entweder durch Interrupt oder Polling abgefragt wurde, ob der Controller 
dies auch schon durchgeführt hatte, um die nächsten Aktionen auf dem Bus 
durchführen zu können.

Beim Start machst Du dieses, aber beim Stop ist es nicht drinnen (oder 
Ich übersehe es).

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

I2C is da auch iwie das maximal dämliche für ;)
Weil langsam und Protokolloverhead.
Nimm nen 74HC595, den kannste mit maximalen SPI Takt des AVRs bespaßen.

von Chris (Gast)


Lesenswert?

Sebastian H. schrieb:
> Kurze Frage:
>
> Nachdem Du den Stop-Befehl gesendet hast, erfolgt m.W. eine Abfrage, ob
> diese Bedingung erfüllt wurde, die hier wohl fehlt.
>
> Ich kenne diese Vorgehensweise bei PIC-Controllern(Sprut.de), wo
> entweder durch Interrupt oder Polling abgefragt wurde, ob der Controller
> dies auch schon durchgeführt hatte, um die nächsten Aktionen auf dem Bus
> durchführen zu können.
>
> Beim Start machst Du dieses, aber beim Stop ist es nicht drinnen (oder
> Ich übersehe es).

Ja irgendsowas vermute ich auch. Der o.g. Artikel von 
Mikorcontroller.net sagt dazu allerdings etwas anderes:

"Nachdem bis hierhin alles funktioniert hat (angenommen), muss nun nur 
noch ein STOP gesendet werden. Dies erfolgt analog zu den obigen 
Ausführungen durch Schreiben eines speziellen Wertes in TWCR. Nach dem 
Löschen von TWINT wird dieses gesendet. Allerdings wird danach TWINT 
nicht automatisch wieder gesetzt, wie es zuvor immer der Fall war."

Ich habe auch schonmal ein delay von ein paar ms nach dem Stop 
eingebaut, aber das hat auch nichts verbessert, aber ich werde das 
nachher nochmal versuchen.

von Chris (Gast)


Lesenswert?

Martin Wende schrieb:
> I2C is da auch iwie das maximal dämliche für ;)
> Weil langsam und Protokolloverhead.
> Nimm nen 74HC595, den kannste mit maximalen SPI Takt des AVRs bespaßen.

Hmmm...ich muss das Datenblatt nochmal genauer anschauen, aber inwiefern 
kann ich den 74HC595 denn als DAC verwenden?

von Sebastian H. (technik_freak)


Lesenswert?

Versuche einmal, das Stop-Bit und den Interrupt abzufragen.

Folgendes steht im Datenblatt dazu( und wird hier auch erklärt 
Beitrag "Re: "I2C-Stopp" wird nicht ausgeführt (HW-TWI, AVR)"):

1)Writing the TWSTO bit to one in Master mode will generate a STOP 
condition on the 2-wire
Serial Bus.When the STOP condition is executed on the bus, the TWSTO bit 
is cleared automatically.

2)TWINT: TWI Interrupt Flag
This bit is set by hardware when the TWI has finished its current job 
and expects application
software response.


Wenn Du jetzt Stop sendest erhälst Du TWINT = 1, wenn Stop erfolgreich 
durchgeführt wurde. So lange würde Ich warten, denn es kann ja sein, 
dass dein Slave trotz delay etwas länger gebraucht hatte, der Master 
dieses jedoch dafür "Taub" war.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

R2R DAC duckundwech

Um ehrlich zu sein hab ich die Nummer verwechselt, also deinen IC fürn 
Portaxpander gehalten mit dem du schon R2R DAC machst.
Im Datenblatt steht tatsächlich nix zur maximalen Samplingrate fürn DAC.
Nur fürn ADC und die is bei 11kHz und "Max sampling rate given by 
I2C-bus speed".
Tolle Aussage...

Guck dir mal den MCP4706A0T an.
Der kann 400kHz und 3,4MHz I2C und kanns chnell genug samplen.

Oder den MCP4902, der wird dann per SPI angesteuert.

von Spess53 (Gast)


Lesenswert?

Hi

>Im Datenblatt steht tatsächlich nix zur maximalen Samplingrate fürn DAC.

Selbstverständlich. Im Aktuellen Datenblatt von NXP, S.18:

DAC conversion  frequency  - - 11.1 kHz

Allerdings würde ich die Übertragung wie im Datenblatt machen:

Adressierung-Controlbyte-Datenbyte-Datenbyte-.....

MfG spess

von Klaus R. (klara)


Lesenswert?

Hallo,
ich meine, ich hätte vor gut 10 Jahren mit dem PCF8591 7 KHz geschafft. 
Viel mehr ist wohl nicht drin. Es ist ja auch ein Oldtimer.
Gruss Klaus.

von Chris (Gast)


Lesenswert?

Spess53 schrieb:

>
> DAC conversion  frequency  - - 11.1 kHz
>
> Allerdings würde ich die Übertragung wie im Datenblatt machen:
>
> Adressierung-Controlbyte-Datenbyte-Datenbyte-.....
>

Mist, ich habe das Datenblatt jetzt gefühlte 100 mal durchgesehen, aber 
das trotzdem überlesen. Würde ja für mich grade noch so reichen, weil 
das Signal am Ausgang nur 8kHz haben muss.

Ich tippe momentan eher darauf, dass mein Exemplar defekt ist. Ich habe 
grade mal den Prescaler auf 4 gesetzt, das TWBR auf 255 und nach jedem 
Durchlauf 0,1 Sekunde delay eingebaut. Und trotzdem waren keine 255 
Stufen vorhanden. Manchmal gings auch wieder bergab, dann waren wieder 
Sprünge drin. Sehr seltsam das Ganze.

Die ganzen ACK Signale kommen ja vom DAC. Insofern würde ich erwarten, 
dass er dann auch was tut für sein Geld.:-)

von Chris (Gast)


Lesenswert?

Martin Wende schrieb:
> R2R DAC duckundwech
>
> Um ehrlich zu sein hab ich die Nummer verwechselt, also deinen IC fürn
> Portaxpander gehalten mit dem du schon R2R DAC machst.
> Im Datenblatt steht tatsächlich nix zur maximalen Samplingrate fürn DAC.
> Nur fürn ADC und die is bei 11kHz und "Max sampling rate given by
> I2C-bus speed".
> Tolle Aussage...
>
> Guck dir mal den MCP4706A0T an.
> Der kann 400kHz und 3,4MHz I2C und kanns chnell genug samplen.
>
> Oder den MCP4902, der wird dann per SPI angesteuert.

Den MCP4706A0T hatte ich auch schon im Visier, aber SOT/MSOT versuche 
ich zu vermeiden.

Den MCP4902 habe ich auch zu Hause, den werde ich morgen mal 
ausprobieren. Ich habe den PCF8591 bevorzugt, weil die SPI Pins ja auch 
vom ISP verwendet werden. Das Boardlayout wäre angenehmer geworden, wenn 
ich SPI Pins nicht für den DAC gebraucht hätte, aber daran solls nicht 
scheitern.:-)

von Pfitsche (Gast)


Lesenswert?

...soll heissen man braucht mehr informationen !

von Chris (Gast)


Lesenswert?

Soooo...jetzt hab ich endlich herausgefunden wo das Problem lag. Ich 
hatte PIN Ext offen gelassen. Ich hatte das Datenblatt so interpretiert, 
dass Ext nur für den A/D Betrieb relevant ist. Wenn ich ihn auf Masse 
lege funktioniert alles wunderbar. Vielleicht hilft der Thread jemandem 
diesen Fehler nicht zu begehen.

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.