Hallo liebe Gemeinde,
ich komme am besten gleich zur Sache im Anhang ist ein Timingdiagramm
und mein Quellcode in ASM gegeben. Leider funktioniert das nicht ganz so
wie ich mir das denke.
Meine Vermutung: Timer 1 ist nicht richtig konfiguriert und die
Interrupts vermurcheln mir mein SP (siehe Timingdiagramm), der CP
funktioniert einwandfrei und ist an PD5 angeschlossen (PB3<->PD5)
Ich benutze den Atmega168 mit einem 20 MHz- Quarz. In dem Quellcode sind
meine Gedankengänge im entsprechenden Bereich kommentiert.
Ich hoffe Ihr könnt mir helfen den Fehler in meinen Gedanken oder im
Code zu finden.
> ldi temp, 0b00100110 ; Aktiviere Interrupts für OCR1A & OCR1B> sts TIMSK1, temp
Da sind 3 Stück 1 Bits in der Maske. Du schreibst aber nur von 2
Interrupt Service Routinen und hast auch nur 2 definiert.
generell würdest du dir viel leichter tun, wenn du diesen blödsinnigen
Binärschreibweisen-Fetischismus aufgeben würdest. Ohne Not
Binärschreibweise zu verwenden oder ohne dafür etwas zu kriegen ist
nicht cool, sondern fehleranfällig.
Laut Datenblatt ja auch die Beispielcodes sind so aufgebaut ich bekomme
dann aber beim Compelieren einen Fehler und bei Timer 2 funktioniert das
ja auch.
Philipp H. schrieb:> Laut Datenblatt ja auch die Beispielcodes sind so aufgebaut ich bekomme> dann aber beim Compelieren einen Fehler und bei Timer 2 funktioniert das> ja auch.
Ist das die Antwort auf die STS <-> OUT Frage?
Das heißt nichts, wenn es beim Timer 2 auch funktioniert. Die einzige
Autorität ist das Datenblatt und dort wiederrum die Tabelle, in der die
Adresslage der einzelnen Register aufgeführt ist. Wenn dort zu entnehmen
ist, dass ein spezifisches Register nur mit STS zu erreichen ist, dann
muss STS benutzt werden. Unabhängig davon, ob andere Register deselben
oder eines anderen Timers mittels OUT zu erreichen wären oder nicht.
Hi
STS passt schon. Die Register der Timer liegen alle oberhalb von
$3F/$5F.
>ldi temp, 0b00100110 ; Aktiviere Interrupts für OCR1A & OCR1B
So etwas schreibst du besser
ldi tmp,1<<ICIE1|1<<OCIE1B|1<<OCIE1A
Wobei mir allerdings unklar ist, was du mit dem Input Compare Interrupt
willst. Zumal, wie KHB schon bemerkt hat, du keine Interruptroutine
hast.
MfG spess
Ja danke das war es, ja vlt hat sich der Compare Interrupt durch meine
unpassende schreibweise eingeschlichen, aber genau der hat eben dieses
zappeln ausgelöst. Ich werde mir das versuchen so anzugewöhnen ;) nur
die Zeit zwischen den SP-Impulsen passt noch nicht da hab ich wohl OCR1A
noch falsch beschrieben, habt ihr da vlt auch ein Tipp wie das besser
geht?
Danke nochmals
Philipp H. schrieb:> Ja danke das war es, ja vlt
nicht vielleicht.
Sondern sogar sicher!
> die Zeit zwischen den SP-Impulsen passt noch nicht da hab ich wohl OCR1A> noch falsch beschrieben, habt ihr da vlt auch ein Tipp wie das besser> geht?
warum schreibst du es nicht so
1
ldiH_byte,HIGH(2600)
2
stsOCR1AH,H_byte
3
ldiL_byte,LOW(2600)
4
stsOCR1AL,L_byte
beim Stack-Pointer beschreiben hast du ja auch die HIGH und LOW Makros
benutzt.
Warum diese Schreibweise besser ist, brauch ich wohl nicht extra
anführen.
spess53 schrieb:> STS passt schon. Die Register der Timer liegen alle oberhalb von> $3F/$5F.
Alles klar, danke. Ich war so dämlich nicht ins Datenblatt zu schauen,
den M168 hatte ich noch nie beim Wickel. Sorry.
Was wäre zu tun? Den Interrupt nicht zu aktivieren, oder erst mal ein
Reti an die angesprungene Adresse setzen. So kreise ich meine Fehler
ein, wenn Oszi-Debugging nicht mehr hilft.
noch einmal danke Karl Heinz ich programmiere noch nicht lange in ASM
aber dieses mal ist es notwendig. Man lernt halt nie aus ^^ und
Ratschläge nehme ich gerne an.
Ich werd den Code wohl noch einmal überarbeiten :D
Karl Heinz schrieb:> Philipp H. schrieb:>> Ja danke das war es, ja vlt>> nicht vielleicht.> Sondern sogar sicher!>>> die Zeit zwischen den SP-Impulsen passt noch nicht da hab ich wohl OCR1A>> noch falsch beschrieben, habt ihr da vlt auch ein Tipp wie das besser>> geht?>> warum schreibst du es nicht so>
1
>ldiH_byte,HIGH(2600)
2
>stsOCR1AH,H_byte
3
>ldiL_byte,LOW(2600)
4
>stsOCR1AL,L_byte
5
>
>> beim Stack-Pointer beschreiben hast du ja auch die HIGH und LOW Makros> benutzt.> Warum diese Schreibweise besser ist, brauch ich wohl nicht extra> anführen.
1
ldi H_byte,0b00101000
2
sts OCR1AH,H_byte
3
ldi L_byte,0b00001010
du hast dich beim Abschreiben der Binärzahl aus dem
Windows-Taschenrechner in der Reihenfolge der Bytes vertan.
Dezimal 2600 ist binär 00001010 00101000
Schreibs vernünftig, dann passiert dir so ein Leichtsinnsfehler nicht.
Lass den Assembler für dich arbeiten!
Was interessiert mich die Binärform. HIGH(2600) ist das Highbyte davon,
LOW(2600) ist das Low-Byte davon. Mehr muss ich nicht wissen und dann
ist auch die Chance kleiner, dass ich da beim Umrechnen und
auseinanderdividieren auf Binär einen Fehler mache.
Generell: Binärschreibweise ist fast immer die schlechteste Form, die du
finden kannst. Für fast alles gibt es bessere Schreibweisen, die dir als
Mensch entgegen kommen und deine Chance Fehler zu machen verkleinern.
Zum Teil massiv verkleinern.
Wenn auch etwas spät möchte ich mich bei dir bedanken @der alte Hanns
dein Code funktioniert prächtig. Ich denke ich habe jetzt verstanden was
Ihr an meiner Binärschreibweise kritisiert habt ;). Ich habe für mich
selber deinen Code noch etwas detalierter kommentiert und wollte diesen
nun noch um eine Funktion ergänzen. Leider klappt das nicht so ganz, ich
denke das hat was mit der Verzweigung im Interrupt zu tun. Ich habe
bereits probiert mit JMP und CPSE zu arbeiten und dann mittels JMP in
eine weiter Subroutine zu springen. Ohne Erfolg. Was ich vor habe, ist
bei jedem Flankenwechsel an PD2 die Frequenz von CP zu wechseln -->
OCR2A ändern. Das klappt auch, aber nur einmal. Also von 1MHz auf 500
kHz. Könntet Ihr mir dabei vlt. noch einmal helfen ?
Mit freundlichem Gruß
Phil
1
#define fkHz 20000 ; Clock-Frequenz in kHz
2
#define fOCR2A 1000 ; 1 MHz: 1 us auf phiCP == OC2A
3
#define f1OCR2A 500 ; 0,5 MHz: 2 us auf phiCP == OC2A