Ich tauche gerade in das Thema Assembler und 328P ein.
Ich lasse den Timer2 ohne prescaler als freerunning im Mode0 laufen.
Das passt auch, alle 16us ändert sich der Ausgang von PB3 (OC2A).
Next step ist, zwei rechecksignale über PD7 innerhalb des Timer2OverFlow Interrupts auszugeben. Daran cheitere ichanscheinend (oder die Test HW ist zu schwach). Ich bekomme einmal ein Recht oder manchmal die gewünschten zwei Rechtecke auf D7, allerdings nicht konstant immer.
Debugger ist vorhanden. Ich kann das ganze ja nocheinmal im Emulator durchlaufen lassen, nur scheint mir die Realität in diesem Fall von dem Debugger abzuweichen. GPIO/Timer und die entsprechenden realen "verhaltensweisen" lassen sich nicht einfach emulieren.
Egal, ich spiele das noch einmal durch und liefere dann die "Erkentnisse" ;-)
Die Interrupts immer erst freigeben, wenn die Quelle konfiguriert ist, sonst kann es zu Fehlzündungen kommen. In der ISR solltest du als erstes immer das SFR retten und am Ende zurückschreiben. Jetzt noch nicht so wichtig, aber führt in Zukunft zu unerwünschten Seiteneffekten.
.EQU takt = 16000000 ; Systemtakt 16 MHz intern => 1 CPU clk = 62,5ns
Sicher? 16Mhz gibts eigentlich nur mit externem Quarz oder Oszillator. Intern sind max. 8Mhz drin.
out DDRD,dummy ; 1 cycl, set portd
sbi portd,7 ; 2 cycl, enable pullup D7
Nö. Wenn PD7 ein Ausgang ist, setzt das Statement PD7 auf high. Pullup schaltest du nur ein, wenn PD7 ein Eingang wäre.
Die Interrupts immer erst freigeben, wenn die Quelle konfiguriert ist,
sonst kann es zu Fehlzündungen kommen. In der ISR solltest du als erstes
immer das SFR retten und am Ende zurückschreiben. Jetzt noch nicht so
wichtig, aber führt in Zukunft zu unerwünschten Seiteneffekten.
Ja, Danke.
.EQU takt = 16000000 ; Systemtakt 16 MHz intern => 1 CPU clk = 62,5ns
Sicher? 16Mhz gibts eigentlich nur mit externem Quarz oder Oszillator.
Intern sind max. 8Mhz drin.
Mhm, soweit ich das Datenblatt korrekt gelesen habe, wird der 16mHz Quarz direkt 1:1 übernommen. Das Bedeutet 1/16mHz = 62,5ns.
Bitte um korrektur, falls ich Falsch liege :-O
out DDRD,dummy ; 1 cycl, set portd
sbi portd,7 ; 2 cycl, enable pullup D7
Nö. Wenn PD7 ein Ausgang ist, setzt das Statement PD7 auf high. Pullup
schaltest du nur ein, wenn PD7 ein Eingang wäre.
Aber um einen gesetzten Eingang wieder einzulesen, brauche ich doch den Pullup, oder? Sonnst hätte ich doch einen OpenCollector System?
Bitte um Korrektur.
Tippfehler? COM2A z.B. setzt du mit (1 << COM2A) und COM2B mit (1 <<
COM2B).
Nullen schieben bringt übrigens keine Wirkung. Hier genauso:
ldi dummy,(0<<WGM22)|(CS2) ; 1 cycl
sts TCCR2B,dummy ; 2 cycl, SFR B1
Ich dachte das die "Null" x-mal verschieben wird. Somit kann ich einzelne bits im Byte Ein/Ausschalten. Doch nicht ?!? :-O
Auf jedenfall herzlichen Dank für die Hinweise.
Werden gerne aufgenommen :-)
Aber um einen gesetzten Eingang wieder einzulesen, brauche ich doch den
Pullup, oder?
Mag sein, je nach Schaltung, die wir nicht kennen. In diesem Programm konfigurierst du den Pin aber als Ausgang. Deine Überlegungen zu Eingängen passen nicht dazu.
Mein "Testsystem" ist hier ein Arduino Uno mit modifiziertem "RESET-EN".
[Darum auch die 16mHz]
Achtet auf die Abtastfrequenz des LogicAnalyzer.
[Ist die Frequenz zu gering, können Signale ggf. nicht erfasst werden.
Eingestellt waren bei mir 2 oder 4 MS/s. Mit 25 MS/s bekomme endlich meine beiden Rechtecke :-)]
Die errechneten Zeiten für jeweils High/Low stimmen (in etwa),
aber irgendwo muss der Preisunterschied zwischen Original und Clone SALEAE berechtigt sein ;-)
Auf jedenfall Herlichen Dank für die vielen Hinweise und das schubsen in die richtige Richtung.
Man(n) zweifelt ja sofort am eigenem Unvermögen ;-)
@Arduino F
Wie würde so eine "Toggle Maske" aussehen?
@Matthias S
Danke, so ein HowTo hatte ich schon immer gesucht und es gibt wieder etwas Lesestoff ;-)
@Peter D
Merci für den Hinweis der zusätzlichen cyclen beim Interrupt.
@Arduino F
Wie würde so eine "Toggle Maske" aussehen?
Schreiben einer '1' in PINx (das ja dem Sinn nach eigentlich zum Lesen bestimmt ist) bewirkt ein Toggeln (Umschalten) des entsprechenden Bits in PORTx. Z.B. PD7 kannst du also mittels einer einzelnen Anweisung umschalten:
Das klappt bei allen nicht 'uralten' AVR, hat nur den Haken, das man schon wissen sollte, wie der Pin vorher stand :-)
Wenn man vorher auslesen muss, lohnt sich das nicht.
Das klappt bei allen nicht 'uralten' AVR, hat nur den Haken, das man
schon wissen sollte, wie der Pin vorher stand :-)
Naja, es ging ja explizit ums Toggeln. Wenn man ein einzelnes Bit direkt setzen oder löschen will, nimmt man halt 'SBI PORTx, b' bzw. 'CBI PORTx, b', damit geht es auch in einem Takt.
irgendwo muss der Preisunterschied zwischen Original und Clone
SALEAE berechtigt sein
Generell halte ich es für hilfreich, seine Werkzeuge kennen zu lernen, bevor man sie ernsthaft benutzt. Alles hat irgendwo seine Grenzen, die sollte man kennen, dann ist es kein Problem.
Ich würde z.B. bei Netzteilen auf jeden Fall mal testen, wie sie sich beim ein/aus Schalten mit unterschiedlichen Lasten (keine, klein, mittel, groß, , ohmsch, kapazitiv, induktiv, Akkus) verhalten. Da gibt es oft Überraschungen, bis hin zur Zerstörung der Zielschaltung oder des Netzteils.