Hallo zusammen Folgende Ausgangssituation: MCU: ATtiny25, ca. 8Mhz mit internen Oscillator Winavr:20090313 AVR-Studio: 4.18, SP2, Simulator2 Ich möchte den A/D-Wandler benutzen und das Ende der Wandlung abfragen. Hier die relevanten Codeschnipsel: #include <avr/io.h> .... init: ADMUX = 0b00100000; //left adjust, channel0 select ADCSRA = 0b00000110; //125KHZ sample rate at 8MHz .... ADCSRA |= _BV(ADEN); //enable ADC, bit7 of ADCSRA .... ADCSRA |= _BV(ADSC); //start conversion, bit6 of ADCSRA loop_until_bit_is_clear(ADCSRA,ADSC); //das geht nicht alternativ hab ich versucht: do { tmp = ADCSRA; //tmp ist als lokale uint8_t variable zuvor definiert tmp &= 0x40; } while(tmp); //geht auch nicht Folgendes Verhalten: Im Simulator kann man beobachten, dass das ADSC bit gesetzt wird und nach ein paar loops wieder auf 0 geht. Die SW bleibt aber im makro loop_until_.. hängen. Im Datenblatt und im AVR-Simulator sind für Register ADCSRA 2 Adressen angegeben: 0x6 und 0x26. Im generierten Assemblercode wird 0x26 verwendet, wogegen man im memory I/O Fenster des AVR-Simulators auf Adresse 0x6 die Veränderung des ADSC bit verfolgen kann. Auf Adresse 0x26 passiert nichts. Wo steckt da der Wurm? Es gibt im AVR-Studio noch einen weiteren Punkt der seltsam ist: In der Konfigurationseinstellung gebe ich 8MHz Takt an, der Simulator sagt aber nur 1MHz, im generierten makefile steht aber auch 8Mhz drin. Hat das etwa mit der Auswahl der Taktquelle zu tun? Hat da einer von euch eine Idee die mir hilft? Schon mal danke im Voraus. Christian
Christian P. schrieb: > Wo steckt da der Wurm? Im Simulator? Schau dir mal an, was im realen Silizium passiert. Der Unterschied zwischen beiden Adressierungsarten ist eine grundsätzliche Eigenheit der klassischen (nicht-Xmega) AVRs, darüber solltest du dich mal im Datenblatt kundig machen, bevor du da irgendwas mutmaßt. Offenbar hast du auch die Optimierung ausgeschaltet. > im generierten makefile steht aber auch 8Mhz drin. Das Makefile konfiguriert rein gar nichts, das teilt nur einigen Routinen bzw. Makros (und zwar denen in <util/delay.h> und <util/setbaud.h>) mit, von welcher CPU-Frequenz sie bei ihren Rechnungen ausgehen sollen. Dass diese CPU-Frequenz eingestellt ist, darum musst du dich separat kümmern (per Fuses bzw. CLKPR).
Hallo Jörg Danke für die rasche Antwort. Habe noch kein reales Si. Von unterschiedlichen Zugriffen auf I/O-Adressen des AVR habe ich schon gehört, aber aus dem Datenblatt bin ich da auch nicht wirklich schlauer geworden. Der wahre Überblick fehlt mir da noch. In bin davon ausgegangen, daß der Winavr-Compiler das richtig macht und man den Simulator für so einfache Routinen nutzen kann, ehe man die HW am Tisch hat. Die Optimierung habe ich tatsächlich abgeschaltet. Wollte das erst während des Projektverlaufes optimieren. Gibt es keinen Weg das ohne Si zu testen? Gruß Christian
Christian P. schrieb: > Gibt es keinen Weg das ohne Si zu testen? Du kannst im Simulator immer noch händisch auf jedes Bit in jedem Register draufklicken und es so von 0 auf 1 bzw. umgekehrt stellen. Dann ein paar mal F10, bis das Programm an die Stelle kommt, an der das Bit abgefragt wird, und schon sollte die Schose wieder laufen. Einzig wenn es darum geht, dass irgendein Timer eine PWM generiert und daher ein Pin eigentlich bei bestimmten Zählerständen toggeln sollte, so hat der Simulator so manchesmal seine liebe Not damit.
> alternativ hab ich versucht: Was ist falscg daran, die ADC Routine aus dem AVR-GCC-Tutorial als Ausgangspunkt zu nehmen?
Hallo Karl Heinz Das Bit setzen & löschen im Sim. geht ja alles, einzig die Warteschleife will nicht. Weder der vorgegebene macro, noch die umständliche, selbstgestrickte do..while. Das Muster im Tutorial kannte ich nicht, probier ich mal. Übrigens bei eingeschalteter Optimierung (Os anstatt ursprünglich O0) steht im Disassembler dann die Adresse 0x6 anstatt 0x26. Funktionieren tut das aber trotzdem nicht. Danke, bis bald Christian
Christian P. schrieb: > Übrigens bei eingeschalteter Optimierung (Os anstatt ursprünglich O0) > steht im Disassembler dann die Adresse 0x6 anstatt 0x26. Da macht der COmpiler den Zugriff anders. Kümmere dich nicht darum. Im Debugger mit einer optimierten Variante durchzusteppen ist .... mutig
Da bin ich noch mal Also auch das Beispiel aus dem Tutor mag der Sim. nicht. Mit & ohne Optimierung bleibt da die SW in der Schleife while (ADCSRA & (1<<ADSC) ); hängen. Da kann ich mit dem ADSC bit machen was ich will. Da scheint Atmel im Sim. noch einen bug zu haben. Jörg hat auch schon sowas angedeutet. Der "Übermut" resuldiert daher, dass ich nur den code für die Funktion herauskopiert habe, um damit mal zu experimentieren. Wenn ich noch mutiger wäre, würde ich das ganze in assembler schreiben. Bei der relativ überschaubaren Aufgabe könnte man das fast wagen. Aber es drängt die Zeit und es mangelt an Erfahrung. Noch mal danke für die Unterstützung. Christian
Hast du den "Simulator V2" benutzt? Den müsste es doch für einen ATtiny25 geben, oder? (Sorry, ich habe kein AVR Studio hier. No Gates, no Windows.) Der sollte zumindest den Digitalteil ordentlich simulieren. Ansonsten die errata notes zum AVR Studio genau lesen, ich glaube mich zu erinnern, dass die bekannten Probleme in der Simulation in der Regel auch dokumentiert worden sind. Christian P. schrieb: > Wenn ich noch mutiger wäre, würde ich das ganze in assembler schreiben. Das bringt dir auch nichts, wenn es nur der Simulator falsch simuliert. Du kannst dem bisschen C-Code, das hinter "loop_until_..." steht schon zutrauen, dass der Compiler das korrekt compiliert. Da bringt auch ein ebenfalls korrekt geschriebener Assemblercode keine Änderung (wenn du ihn erstmal bis zu diesem Punkt hast).
Hallo Jörg, ja ich hab's mit Sim.V2 probiert, steht auch in meinem 1. thread. Auch die Studioversion ist die aktuellste. Der ATtiny25 ist mit dabei. Winavr gibt es in einer neueren Version. Bei dem trivialen code kann es eigentlich daran nicht liegen. Die Mühe, vielmehr die Zeit die Atmel error lists durchzulesen habe ich mir noch nicht genommen. Vielleicht wird das ja heute meine Bettlektüre;-). Also das mit dem Assembler überleg ich mir auch noch. Wahrscheinlich krieg ich da kalte Füsse. Gruß C.
Christian P. schrieb: > ja ich hab's mit Sim.V2 probiert, steht auch in meinem 1. thread. Sorry, hatte ich überlesen. Dann sollte es allerdings auch funktionieren. Poste mal vollständigen, compilierbaren Code.
Hallo Jörg Anbei der auf die ADC-Anwendung reduzierte code. Ich hab mit allen Optimierungsstufen alle 3 Varianten probiert. Im SimV2 wird bit ADSC->0, aber er bleibt in der Abfrageschleife hängen. Gruß C.
Kann man den ADC (oder andere HW-Komponenten) initialisieren, wenn sie nicht aktiviert sind? Auf AVR hatte ich da mal irgendwo ein Problem, daß ich nach nem Sleep was konfirgurierte bevor ich das Modul aktivierte. UART oder Timer, vielleicht ist es beim ADV ja auch sowas?
Hallo Johan Der ADC wird mit dem Setzen des ADEN bits im ADCSRA Register aktiviert und mit dem Setzen von ADSC im selben Register gestartet. Läßt sich im Simulator nachvollziehen. Das Problem ist der deadlock bei der Abfrage von ADSC. Gruß C.
Korrektur des sourcecodes. Ich hatte im vorangehenden posting die variable tmp nicht definiert. Ohne der funktioniert Version2 der Abfrageschleife nicht. C.
Also: Der generierte Code sieht richtig aus. Ich denke das ist ein Fehler im Simulator. Auf der GUI sieht man zwar, das das Bit gelöscht wird, dem Code wird es aber ständig als gesetzt präsentiert.
1 | //3. Version (aus dem tutorial)
|
2 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung |
3 | uint8_t val = ADCSRA; |
4 | while (val & (1<<ADSC)) |
5 | val = ADCSRA; // auf Abschluss der Konvertierung warten |
6 | }
|
val hat immer einen Wert von 196 == 0xC6 == ADSC ist gesetzt, unabhängig davon ob man händisch den Haken aus dem ADCSRA Register rausmacht oder nicht.
Servus Karl Heinz Ich hab jetzt noch mal mehrfach die Initialisierungsreihenfolge verändert, aber das Ergebnis bleibt unbefriedigend. Mal sehen wie ich das den Atmelkameraden mitteilen kann. Bleibt nur noch der Test an der realen HW. Trotzdem euch allen herzlichen Dank für die Mühe und noch einen schönen Fußballabend. Gruß Christian
Bei mir im Sim. ändert sich der Wert im ADCSRA schon von C6 auf 86, aber aus der Schleife kommt er trotzdem nicht raus.
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.