Guten Tag.
Ich habe eine mir nicht erklärbare Anomalie bei einem ATmega328P, der
mit einem 16MHz Oszillator getaktet wird, feststellt. Es geht dabei um
die Durchführung einer ADC-Conversion und das Umschalten eines Ausgangs
hinsichtlich seines digitalen Levels.
Ich habe dabei zwei unterschiedliche Codevarianten implementiert, die
eigentlich das Umschalten des PD1 Pins auf die selbe Art durchführen
sollten. Anbei habe ich dann die Spannungsverläufe des PD1 Pins
angehängt.
Man kann erkennen, dass beim ersten Fall der Pin jeweils nur eine
Taktdauer auf dem gesetzten Pegel ist. Im zweiten Fall ist aber der Pin
für die erste Portanweisung für zwei Taktperioden auf dem Low-Level.
Weiß möglicherweise jemand, wie das zustande kommt? Ich habe mir
überlegt, dass es irgendwas mit dem Springen zur ISR zu tun haben
könnte. Das sollte ja aber eigentlich schon bis zur dieser Codeposition
erfolgt sein, weshalb ich nicht wirklich weiß, was die Ursache ist.
Ich würde mich freuen, wenn jemand etwas dazu sagen könnte.
MfG LeDay
Code Fall 1:
Am Besten erstmal den disassemblierten Code ansehen und posten. Nicht
dass der Compiler irgendwas zwischen die beiden ersten
PORTD-Schreibzugriffe in der ISR packt.
> irgendwas zwischen die beiden ersten> PORTD-Schreibzugriffe in der ISR packt
Zum Beispiel ein ldi. Vielleicht auch mal die Compiler-Optimierungen
umschalten.
Wow, danke euch.
Also helfen würde dann wahrscheinlich, vor dem ersten Low-Befehl, den
Port wiederholt auf High zu setzen, damit das Register vorgeladen wird.
Ich muss mal überprüfen, ob das noch einen Performancegewinn im
Vergleich zur Polling-Variante darstellt.
Oder einfach ASM lernen :).
LeDay schrieb:> Oder einfach ASM lernen :).
Das ist hier die einzig richtige Antwort, denn nur so kann man solche
Taktgenauen Sachen bauen. Der C-Compiler kann einem immer irgendwas
umsortieren. Oder noch besser das Signal-Timing per Timer/PWM o.ä. in
Hardware erzeugen.
LeDay schrieb:> Also helfen würde dann wahrscheinlich, vor dem ersten Low-Befehl, den> Port wiederholt auf High zu setzen, damit das Register vorgeladen wird.
So etwas kann vielleicht helfen, aber wenn du irgendwo irgendwas anderes
änderst, klappt's dann vielleicht nicht mehr.
Ja, das hat tatsächlich geholfen. Meine Intention ist nicht die ganze
Zeit zu togglen, aber generell kann ja dann eine entsprechende
Verzögerung implementiert werden bis es zur nächsten gewünschten
Änderung kommt, und dann mit dem Toggle-Befehl der Pin umgeschaltet
werden.
Danke für den Tipp!