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?
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.
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); } } }
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.
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.
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).
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.
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.
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?
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.
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.
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
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.
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.:-)
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.:-)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.