Servus, also wir haben folgendes Problem. Wir wollen eine Funkuhr bauen. Die Antenne und alles läuft schon. Bei der Dekodierung des Signals stoßen wir jedoch auf ein Problem. Wie bringen wir unserem Timer bei, dass er jede Millisekunde einmal auslöst und eine Variable incrementiert. An unserem Oszi haben wir nie die richtige Zeit. Hier der Code: .include "m16def.inc" .def ms=r17 .org 0x0000 rjmp main .org 0x10 rjmp timer1_o main: ldi r16, LOW(RAMEND) out SPL, r16 ldi r16, HIGH(RAMEND) out SPH, r16 ldi r16, 0b00001000 out DDRD, r16 ldi r16, 0b10001000 out PORTD, r16 ldi r16, 0b00000000 ;Kontrollregister, Prescaler = clk/64 out TCCR1A, r16 ldi r16, 0b00000011 out TCCR1B, r16 ldi r16, 0b00000100 ;Overflow Interrupt... out TIMSK, r16 ldi r16, LOW(0xFD7F) ;Wert vorbelegen out TCNT1L, r16 ldi r16, HIGH(0xFD7F) out TCNT1H, r16 sei loop: rjmp loop timer1_o: cbi PORTD, 3 ;für das Oszi... rcall wait ;sonst kommt der Pin nicht HIGH bzw. LOW sbi PORTD, 3 ;und wieder weg... ldi r16, 0xFD ;den Wert neu laden... out TCNT1H, r16 ldi r16, 0x7F out TCNT1L, r16 reti wait: ;kurze Pause, sehr kurze... ldi r20,1 delay1: ldi r21,5 delay2: dec r21 cpi r21,0 brne delay2 dec r20 cpi r20,0 brne delay1 ret soo, wir wären froh über jede Hilfe aber bitte nicht in C... Wir könnens nicht mehr sehen. Gruß Nineteen und Redmouth
Von dem Setzen der Register TCNT1H:TCNT1L im Interrupt-Handler ist abzuraten, weil der Timer ja munter weiterläuft, bis der µC zur Ausführung der entsprechenden Befehle kommt (man müßte also die Anzahl der Systemclocks für die Ausführung dieser Befehle abzählen und den Setzwert von TCNT1H:TCNT1L um diese Anzahl verringern). Die Standardlösung des Problems "Erzeugung von Interrupts mit einem Takt von genau x Millisekunden" ist, den Timer T/C1 im CTC-Mode zu betreiben ("CTC" = clear on compare match"). Der Timer bekommt einen Compare-Wert vorgegeben (Register OCR1AH:OCR1AL), und wenn sein Zählwert diesen erreicht ist, wird er von der Timer-Logik automatisch auf Null gesetzt, sowie ein Compare-Match-Interrupt ausgelöst. Hard- und softwaremäßige Details siehe Datasheet. PS: Und nicht die Sicherung des SREG im Interrupt-Handler vergessen!
Hallo, also danke erst mal für die Antwort. Ich habs bisher auch so versucht, bis ich im Internet die andere Möglichkeit entdeckt habe. Habs jetzt wieder geändert. Frage: Ich arbeite mit dem STK500 und dem ATMega16 also mit einem CPU-Takt von 3,69Mhz. Wie groß muss OCR1AH/L sein wenn ich eine ms haben will. Ich hatte mir E6A also 3690 ausgerechnet. Stimmt das? Mein Oszi sagt NEIN! Danke Nineteen...
servus, also ich hab jetzt noch mal ne zwischenfrage. Komm mir selber ein bisschen dumm vor. Wenn ich die Taktfrequenz im AVR-Studio ändere. Ändert sich absolut nichts. Wie ist also diese berühmte überall genannte clk/IO Frequenz. Welchen Zahlenwert hat die?
Servus, Clk ist der hardwaremässige Systemtakt. Bei dir 3690000Hz. Dein Prescaler ist 64. Also 3690000/64=57656.25 counts/sec. Für 1ms also ca. 57.7 counts/msec. OCR1AL= 58 OCR1AH= 00
>Frage: Ich arbeite mit dem STK500 und dem ATMega16 >also mit einem CPU-Takt von 3,69Mhz. Wie groß muss OCR1AH/L sein wenn >ich eine ms haben will. Ich hatte mir E6A also 3690 ausgerechnet. >Stimmt das? Mein Oszi sagt NEIN! 3690, also 0xE6A, stimmt natürlich (wenn Du T/C1 ohne Prescaler betreibst, d. h. T/C1 mit vollem Systemtakt läuft). Was sagt denn das Oszi? Beim Laden der 3690 in das Output-Compare-A-Register-Paar OCR1AH:OCR1AL muß unbedingt die Reihenfolge beachtet werden: Zuerst das High-Byte und dann das L-Byte; nicht andersrum. Das High-Byte wird zuerst intern in einem Extraregister gepuffert; die 3690 gelangen erst mit dem Setzen des Low-Bytes als komplettes Wort (!) in OCR1AH:OCR1AL Also so: ldi t, High(3690-1) out OCR1AH, t ldi t, Low(3690-1) out OCR1AL, t Die "-1" ist notwendig, wenn kein Prescaler verwendet wird. Hast Du berücksichtigt, daß Du jetzt nicht mehr den T/C1-Overflow-, sondern den T/C1-Output-Compare-Match-A-Interrupt verwenden mußt? >Wenn ich die Taktfrequenz im AVR-Studio ändere. >Ändert sich absolut nichts. Wie ist also diese berühmte überall >genannte clk/IO Frequenz. Welchen Zahlenwert hat die? Die Taktfrequenz auf dem STK500 wird durch den eingesteckten Quarz bestimmt. Für Zeitmessungen im Simulator ist es sinnvoll, die Frequenz dieses Quarzes in den Optionen im AVRStudio (Hauptmenü: "Debug/Simulator Options") einzustellen.
Servus, mann mann mann mann mann aua aua aua... Also ich glaub echt ich spinn. Mindestens tausend Beiträge hab ich durchforstet und überall wurde mir gesagt das dieser verschickte Prozessor auf diesem noch verschickterem STK 500 mit 3,69 Mhz getaktet ist. Erst nach durchforsten des Datenblattes dann die Erlösung. Er läuft mit 1Mhz standardmäßig. Für alle, die dies einmal über google oder direkt im Forum suchen sollten: DER ATMEGA16 HAT EINEN TAKT VON 1,000000000 MHZ !!!!!!!!!!!!!!!!!!!!! Trotzdem danke für jegliche Hilfe... Gruß nineteen und redmouth
Das ist weder die Schuld des STK noch des M16, sondern einzig und allein Deine ! Ich käme garnicht erst auf die Idee einen MC zu programmieren ohne das Datenblatt griffbereit zu haben. Alle AVRs mit der Option "interner Takt" haben diesen im Auslieferungszustand aktiviert. Der Sinn dahinter ist, es sollen ja auch Schaltungen ohne externen Takt laufen. Abschalten läßt sich der interne Takt ja immer, auch ohne Quarz. Peter
Du weißt schon, daß die kürzeste Pulsbreite beim DCF-77 min 100ms ist ? Da reichen 20ms Abtastrate dicke aus, 1ms ist völlig übertrieben. Peter
Das ist uns schon alles klar. Das Datenblatt hatten wir ja auch. Nur wir gingen davon aus, dass mit "CLK" im Datenblatt die Taktfrequenz des Controllers gemeint ist und nicht die Frequenz der Timer Clock Source!!! Jetzt funktioniert es jedenfalls! Das mit den 10ms machen wir schon noch. Die eine ms war nur mal so ein Test!!! Gruß Redmouth
Also Leute, ich kann mich Redmouth nur anschließen. 1.) Sind wir Anfänger 2.) Haben wir bisher immer nur den AT90S8535 genommen. Bei dem gibt's keinen internet Takt, oder? Deswegen sind wir halt durcheinander gekommen. 3.) Zum Thema 20,10 oder 1 ms. Also wir werden dann schon 10 ms nehmen ist ja klar aber um die Genauigkeit unserer Berechnung zu testen gilt ja wohl: um so kleiner desto besser. Jetzt noch eine Praxis-Frage... Wie würdet ihr die Antenne anschließen. Mein Vorschlag wäre das Signal an die Int0 und Int1 Pins zu hängen. Beim int0 auf eine LOW-Flanke zu reagieren um den Sekunden-Takt zu bekommen und die gezählten Millisekunden auf 0 zu setzen. Beim int1 Pin auf eine HIGH-Flanke zu reagieren und die gezählten Millisekunden auszuwerten. Also bei 100 ne 0 und bei 200 ne 1 abzuspeichern. Würdet ihr das auch etwa so machen oder ist das zu umständlich oder ungenau oder was auch immer?... Vielen Dank für die Hilfe aus dem Forum. Gruß nineteen
Die Idee mit dem Timerinterrupt ist schon o.k. Ein externer Interrupt fängt nur unnötig Störungen mit ein. Externe Interupts sollte man nur für wirklich schnelle Sachen nehmen (z.B. Frequenzmesser, Ethernet-Interface), wo es auf µs ankommt. In der Codesammlung ist ein Beispiel von mir. Peter
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.