Hallo liebe Leute! Ich habe mir ein kleines Board gebaut mit dem ATtiny13, einer weißen LED, einem Taster und einem Poti. Die LED soll mit 100Hz blinken. Tastgrad (Einschaltdauer / Periodendauer) 75%. Solange die Taste gedrückt ist, geht der Tastgrad auf 20% zurück. Soweit sogut...wie man die Ausgänge einstellt, mit Pullup etc weis ich mitlerweile. Kann mir einer von euch für die Sache mit dem Tastgrad ein Codebeispiel in Assembler geben? Mit erklärung wenns geht. Das mit dem 100 Hz blinken krieg ich noch hin, aber beim Tastgrad endet mein Wissen. Vielen Dank schonmal ;)
100Hz blinken (wenn man es so nennen kann) mit tastgrad 75% bedeutet nichts anderes als 7,5ms an und 2,5ms aus ( Summe: 10ms => 100Hz)
achsoo...okey ich werd mal ein bisschen an nem code schreiben und stell den dann hier rein. Danke für den Tipp ;) Was bedeutet es dann..."solange die Taste gedrückt ist geht der Tastgrad auf 20% zurück"?
Andreas Becker schrieb: > Was bedeutet es dann..."solange die Taste gedrückt ist geht der Tastgrad > auf 20% zurück"? Der Tiny13 ist ansich sehr zuverlässig, er macht genau das, was man in sein Programm schreibt. Zeig' Dein Programm, dann braucht man nicht spekulieren. ...
Wenn taste gedrückt, dann 2ms an und 8ms aus. Du musst also eine An-Zeit und eine Aus-Zeit mit einer Variabeln halten. In ASM geht das auch mit einem Register direkt. Und diese ändern, je nachdem ob die Taste gedückt ist oder nicht. Vorschlag: Timer mit 0,5ms laufen lassen und die Einsprünge zählen.
Hallöchen ;) Sorry dass iche rst so spät schreibe, aber ich hatte die letzten Tag viel an Arbeit zu tun. Hab trotzdem noch einen Code geschrieben, allerdings nur für 100Hz blinken...für den Rest muss ich mich noch ein bisschen einlesen, wie das mit den Variablen geht. Würde das Programm so funktionieren? .nolist .include "tn13def.inc" .list .def temp1 = r16 .def temp2 = r17 .def teiler = r18 ;Interruptvektoren rjmp init ;Reset reti ;externer INT0 reti ;Pin Change Int request rjmp t0_overf ;Timer/Counter 0 Overflow reti ;EEPROM Ready reti ;Analog Comparator reti ;Timer/Counter 0 Compare Match A reti ;Timer/Counter 0 Compare Match B reti ;Watchdog Time out reti ;ADC Conversion Complete init: sbi DDRB,DDB1 ;PB1 zum Ausgang machen ldi temp1,(1<<CS02) out TCCR0B,temp1 ;Presaler auf 256 einstellen ldi temp1,(1<<TOIE0) ;Timer 0 Overflow freigeben out TIMSK0,temp1 ldi Teiler,3 ;Vorteiler auf 3 stellen ldi temp1,RAMEND ;Endadr. des RAM-Speichers in out SPL,temp1 ;den Stackpointer laden sei ;generelle Interruptfreigabe main: nop ;nichts zu tun für nop ;das Hauptprogramm rjmp main t0_overf: ldi temp1,0xff-125 ;9,6MHz/256/125=300Hz out TCNT0,temp1 ;Timer0 zurücksetzen dec teiler ;nochmaliges teilen durch 3 brne t0_end ;führt zu einem Takt von 100Hz ldi teiler,3 ;Vorteiler auf 3 zurückstellen ldi temp2,(1<<PB1) in temp1,PORTB ;Zustand der Lampe kippen eor temp1,temp2 ;Alle anderen Bit vom Port B out PORTB,temp1 ;bleiben unverändert t0_end: reti
> Würde das Programm so funktionieren?
was spräche dagegen, den Code im Simulator oder auf deiner realen
Hardware laufen zu lassen? Damit könntest du dir die geeigneten
Antworten gleich selbst geben ....
Wegstaben Verbuchsler schrieb: >> Würde das Programm so funktionieren? > > was spräche dagegen, den Code im Simulator oder auf deiner realen > Hardware laufen zu lassen? Damit könntest du dir die geeigneten > Antworten gleich selbst geben .... So habs laufen lassen, keine Probleme beim Übersetzen...aber läuft nix. Wenn ich den Bit aktiviere kommt am Ausgang nichts...allerdings geht die Simulation immer auf stop. Der tolle Simulator kann mir aber auch nicht sagen was denn falsch ist, wegstabenverbuchsler ;)
Andreas Becker schrieb: > Der tolle Simulator kann mir aber auch nicht sagen was denn falsch ist, Dann frage doch den Simulator einfach mal danach. Setze einen Haltepunkt beim Aufruf der ISR, lasse das Programm (mit F5) bis dahin laufen, steppe dann das Programm mit F11 (Einzelschritt) durch und beobachte dabei die Werte in den Registern (Watch-Fenster). Dann vergleiche die Werte mit denen, die Du erwartest. Einfach nur vom Zugucken wird da nix... ...
Du hast vergessen den Stack zu initialisieren. z.B.
1 | ldi r16, RAMEND ;Stack |
2 | out SPL, r16 |
Ups hast du ja weiter unten, würde ich aber an den Programm anfang setzen.
Jürgen W. schrieb: > Du hast vergessen den Stack zu initialisieren. Nö. "This Stack space in the data SRAM is automaticall defined to the last address in SRAM during power on reset." Ist bei allen neueren AVRs so, die nach dem ATmega8 kamen. Peter
Hannes Lux schrieb: > Andreas Becker schrieb: >> Der tolle Simulator kann mir aber auch nicht sagen was denn falsch ist, > > Dann frage doch den Simulator einfach mal danach. > > Setze einen Haltepunkt beim Aufruf der ISR, > lasse das Programm (mit F5) bis dahin laufen, > steppe dann das Programm mit F11 (Einzelschritt) durch und > beobachte dabei die Werte in den Registern (Watch-Fenster). > Dann vergleiche die Werte mit denen, die Du erwartest. > > Einfach nur vom Zugucken wird da nix... > > ... In den Watch Fenstern passiert nichts unter den Ports, tut mir leid, dass ich nicht die Sorte Anfänger bin die alles sofort begreift... Abgesehen hilft mir das auch nicht weiter, wenn ich eh nicht weis wie ich dass mit dem Tastgrad lösen kann...Variablen schön und gut...besser wär ein Beispiel mit Erklärung
Andreas Becker schrieb: > In den Watch Fenstern passiert nichts unter den Ports, Hmmm, bei mir passiert was, siehe beide Screenshoots. Dein Programm funktioniert, es macht das was Du programmiert hast, aber eben nicht das, was Du gern programmiert hättest. Aber wir haben ja alle mal klein angefangen. > tut mir leid, > dass ich nicht die Sorte Anfänger bin die alles sofort begreift... Naja, ein bissel durch die Menüs wuseln und entdecken, was sich hinter den Menüpunkten verbirgt schadet aber auch nichts. > Abgesehen hilft mir das auch nicht weiter, wenn ich eh nicht weis wie > ich dass mit dem Tastgrad lösen kann... Naja, der Wortlaut lässt darauf schließen, dass es eine Hausaufgabe ist. Und Hausaufgaben lösen wir hier nicht so gerne. Dafür gibt es www.hausaufgaben.de. Unter Tastgrad verstehe ich die Einschaltdauer im Verhältnis zur Periodendauer. Er kann also 0% (aus) bis 100% (ein) betragen. Da Du den Pin durch Toggeln änderst, wobei für Ein-Phase und Aus-Phase dieselbe Zeitverzögerung benutzt wird, beträgt der Tastgrad 50%. > Variablen schön und gut... Variablen hast Du doch schon angelegt, indem Du Speicherplätzen bzw. Registern Namen zugewiesen hast. Wenn die 32 Register nicht mehr ausreichen, dann wird eben SRAM benutzt. > besser > wär ein Beispiel mit Erklärung Diese findest Du zu Hauf im Tutorial: http://www.mikrocontroller.net/articles/AVR-Tutorial Nur eben nicht konkret für Deine Aufgabe. Du willst/sollst eine LED mit 100 Hz blinken lassen... Nagut, ich würde es nicht blinken nennen, da man 100 Hz nicht mehr als Blinken erkennt. Aber das steht ja nicht zur Debatte. Also willst/sollst Du einen Pin mit 100 Hz "klappern lassen". Dabei willst/sollst Du den Tastgrad modulieren, zwar erstmal nur mit Werten 75% und 20%, aber später werden bestimmt andere Werte verlangt, die dann auch wieder in % angegeben werden. Also bietet es sich an, die Auflösung so zu wählen, dass man die Periode von 10 ms (T=1/f) in 100 gleiche Teile aufteilt. Ein Teil wäre dann 100 µs. Nun stellst Du den Timer so ein, dass er nach jeweils 100 µs einen Interrupt auslöst. Der Überlauf-Interrupt ist dazu zwar geeignet, der Compare-Interrupt mit CTC ist dazu aber besser geeignet, siehe Datenblatt. Um den Taster abfragen zu können, setzt Du in der Init das zugehörige Bit im Portregister PORTB (internen PullUp-Widerstand einschalten) und schaltest den Taster gegen GND. Somit hast Du am entsprechenden Bit des Input-Registers PINB bei unbetätigtem Taster H-Pegel und bei betätigtem Taster L-Pegel. Im Timer-Interrupt, der alle 100 µs zuschlägt, zählst Du den Teiler hoch. Bei 100 setzt Du ihn wieder auf 0 und fragst den Taster ab. Anhand des Zustandes des Tasters weist Du der (neu anzulegenden) Variable "Tastgrad" den Wert 75 oder 20 zu. Weiterhin vergleichst Du in diesem Timer-Interrupt die hochlaufende Variable Teiler mit dem Tastgrad und entscheidest danach, ob Dein Ausgang auf H- oder L-Pegel gesetzt wird. Das wars eigentlich auch schon. Wenn Du das realisiert hast, dann kannst Du ja den Tastgrad gleitend ändern (dimmen) und mit anderen Werten spielen. Und dann nimmst Du den ADC dazu und stellst den Tastgrad mittels Poti ein. Ich hoffe, das ist Erklärung genug, wenn ich Dir jetzt auch noch den Code dazu schreibe, dann lernst Du dabei nix... ...
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.