Hallo Kann mir jemand helfen.Ich bekomme es nicht hin das der Timer bei einem Interrupt in das Label Licht_80s springt.Weiss nicht wo der Fehler liegen könnte.Bin für jede Hilfe dakbar
Unterscheidet Assembler in Groß/Kleinschreibung? Du hast Licht_80s und licht-80s geschrieben. (Ich verstehe nicht viel von Assembler, nur das ist mir aufgefallen) MfG Paul
Ähm... es wird dir zwar nicht bei der Lösung deines Problems helfen, aber: bewirkt --> ldi temp,128 --> out SREG,temp und -->sei nicht ein und das selbe? Wenn ja, warum gibst du die INTs doppelt frei? Gruß, Magnetus
Hi Weil ich mir nicht sicher war ob sie freigegeben werden.und da dachte ich mir doppelt hält besser.Aber Danke
Oh... habs gerade selber gemerkt... ist nicht das selbe. --> sei ...setzt das I-Bit im SREG --> ldi temp,128 --> out SREG,temp ...setzt das I-Bit und löscht alle anderen! ...warum tust du das?
Wer aufpasst bei der Simulation wird schlau: Der Interrupt tritt sehr wohl auf, du hast aber dein "rjmp Licht_80s" eine Zeile zu weit unten geschrieben bzw. ein "rjmp RESET" zu viel drüber. Ratsam ist immer die benuzten stellen nochmal explizit mit .org an die entsprechende Speicherzelle zu rücken. Wenn dann ein "rjmp RESET" zu viel drin is beschwert sich der Assambler. Sebastian PS: Lang bleibt das Licht ja nicht an...
Hallo, ich habe mal ein paar Stellen hier reinkopiert, die mich verwirren: .include <tn2313def.inc> ist also ein Tiny2313 rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp Licht_80s rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET rjmp RESET Mehr als Anregung: wenn Du IRQs nicht benutzt, setze reti statt rjmp RESET. Hat den Vorteil, das ein versehentlich ausgelöster IRQ eben einfach als bearbeitet verlassen wird. reset: ldi temp,128 ;gibt die interrupts frei out SREG,temp Daß das überflüssig ist, wurde ja oben schon diskutiert. Ein Prozessor macht nicht unbedingt was er soll, er macht aber IMMER, was man ihm gesagt hat. ;-) ldi temp,0b00000000 out ddrd,temp ;portd ist eingang Ich weiß zwar nicht, was an PortD bei Dir dran ist, falls es offene Pins gibt, unbedingt die internen PullUps einschalten. Ein offener Eingang nimmt jeden Pegel an, die Nebenwirkungen sind genauso unberechenbar. ldi Temp, 2 ;hier wird der timer interupt freigegeben out TIMSK, Temp Du hast dem Timer immernoch gesagt, in welchem Mode mit welchen Werten er eigentlich laufen soll, der kann nicht hellsehen... sei Warum gibst Du hier die Interrupts frei, ohne überhaupt irgendwas initialisiert zu haben? Das kann dazu führen, daß schon ein IRQ ausgelöst wird, bevor Du die Zugehörigen Daten vorbereitet hast. ldi temp,5 out TCCR0,temp ; mit 1024 geteilte frequenz Das Register TCCR0 ist nur aus Kompatibilitätsgründen zu Vorgängertüpen auf das Register TCCR0A definiert, der Tiny2323 hat TCCR0A und TCCR0B. Man sollte auch immer mit den aktuellen Registernamen arbeiten... timer: ldi tmp , 255 out TCNT0, tmp ;timer zählt bis 255 Hier setzt Du nun endlich den Zählwert des Timers, daß muß vor SEI passieren. Es ist immernoch unklar (wenigstens als Kommentar für uns hier) in welchem Mode er läuft...). Warum setzt Du das hier überhaupt??? ldi temp,0 cp zahl,temp breq licht_aus rjmp timer licht_aus: ldi temp,0b11111111 out portb,temp rjmp ende Licht_80s: In der IRQ-Routine wird nur dec Zahl gemacht. Wenn der Timer im One-Shot-Mode läuft, zählt er genau bis 0 und bleibt dann stehen, es wird also nie was weiteres passieren... Dazu müsste hier TCNT0 wieder gesetzt und der Timer gestartet werden. Habe gerade mal nachgesehen, er müsste im Normal-Mode sein, damit zählt er aufwärts, also von Deinen 255 direkt auf 0, danach immer von 0...255 usw. Damit müsste Dein Licht genau einen Taktzyklus lang leuchten, falls Du es beim Reset einschaltest. Etwas kurz? in sregsave ,SREG push sregsave dec zahl pop sregsave out SREG,sregsave reti ende: rjmp ende Gruß aus Berlin Michael
> timer: ldi tmp , 255 > out TCNT0, tmp ;timer zählt bis 255 Das halte ich für ein Gerücht. Wenn Du in TCNT0 255 reinschreibst, dann läuft er genau beim nächsten Takt über, da es sich um einen 8-Bit-Timer handelt. Was ganz gefährlich ist, ist die Freigabe der Interrupts VOR der Initialisierung des Stack Pointers. Weg damit! Habe den Eindruck, Du solltest Dich vielleicht mal in Ruhe hinsetzen und ein Ablaufdiagramm von Deinem Programm zeichnen und jeden Abschnitt mal anhand des Datenblattes auf seinen Sinn überprüfen. Da es kein sonderlich langes und kompliziertes Programm ist, sollte das in endlicher Zeit machbar sein.
hallo Danke für die Tipps.habe irgendwo im Internet gelesen das wenn die 255 in das TCNT0,der Zähler bis 255 zählt.Das war dann die ganze Zeit in meinem Kopf.Habe es jetzt geändert.Aber noch ne Frage.Lässt sich der Timer wieder abstellen oder kann ich nur den Interrupt verbieten. Danke seeadler78
Mal ehrlich: Das steht alles in den Datenblättern Ich versteh wirklich nicht, wie jemand (du bist ja nicht alleine) einen µC programmieren kann ohne die Datenblätter neben sich liegen zu haben. Einfach den Vorteiler komplett wegnehmen und der Timer bleibt stehen.
Schau dir doch einfach mal im Datenblatt die Register des Timers an. Dann wirst du sehen, dass du jederzeit die Einstellungen des Timers verändern kannst, also kannst du ihn auch abstellen, auf anderen Vorteiler umstellen, Betriebsart umschalten usw... Man gut, dass es Datenblätter gibt... ;-) Übrigens läuft bei mir so ziemlich jedes Programm mit einem Timer im Hintergrund, der in regelmäßigen Zeitabständen diverse Aufgaben erledigt (Tasten entprellen, Software-Timer behandeln, manchmal auch PWM erzeugen, usw.). Meist schubst der Timer-Int auch die nächste Runde der Mainloop an, in der die hauptsächliche Arbeit gemacht wird, und wo der AVR nach getaner Arbeit in den Sleep geschickt wird, aus dem er vom nächsten Interrupt geweckt wird. Dein Programm erscheint mir recht konfus, die meisten Mängel wurden aber bereits genannt. Du solltest dir angewöhnen, zu jeder Programmzeile Überlegungen anzustellen, warum du das so und nicht anders machen willst. Dann gehört zu (fast) jeder Programmzeile ein Kommentar, der aber nicht unbedingt den benutzten Befehl erklären soll, sondern was dieser Befehl in diesem konkreten Fall an der Gesamtaufgabe bewirken soll. Du solltest dir auch mal die Register r0..r15 ansehen. Die Tatsache, dass die nicht mit Konstanten operieren können, macht sie nicht unbenutzbar. Für SREG-Sicherung sollte man daher ein unteres Register verwenden, die oberen sind dazu zu wertvoll. Ähnlich gilt das für andere Aufgaben, in denen nicht mit Konstanten operiert werden muss. Ich weiß, aller Anfang ist schwer. Vielleicht solltest du dir mal die Programme anderer Leute etwas genauer ansehen und versuchen zu verstehen. Wenn du etwas im Forum herumblätterst, dann wirst du eine Menge Beispielcode finden. Mit der Suchfunktion wirst du allerdings nicht allzuviel finden, da der Betreff eines Threads in den seltensten Fällen dem tatsächlichen Thema entspricht... Beste Grüße, auch an alle Nicht-ASM-Programmierer... ;-) ...
> Ich weiß, aller Anfang ist schwer. Vielleicht solltest du dir > mal die Programme anderer Leute etwas genauer ansehen Den Vorschlag unterstütze ich zu 100%. Da lernt man eine Menge. Wenn du einen (meiner Meinung nach) erstklassigen Assmebler-Code sehen und studieren willst, dann geh mal auf die Website vom Hannes. http://hanneslux.de/avr/index.html So guten Code sieht man selten.
> Wenn du einen (meiner Meinung nach) erstklassigen > Assmebler-Code sehen und studieren willst, Sorry... - Das kann ich so nicht stehen lassen. Erstklassigen ASM-Code gibt es vielleicht bei PeDa oder anderen wirklichen Könnern. Bei mir gibt es allerhöchstens gut lesbaren bzw. gut verständlichen Anfängercode, der allerdings meist üppig und verständlich kommentiert ist. Viele der auf meiner Webseite vorhandenen Programme sind (aus heutiger Sicht) alles andere als optimal programmiert. Ich werde aber nicht alle alten Programme (die ja ihre Aufgabe erfüllen) neu schreiben, nur weil ich inzwischen bessere Möglichkeiten kenne. Dem Anfänger konnen diese Programme aber schon den richtigen Weg zeigen. Man gut, dass es AVRs gibt... ;-) ...
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.