ATtiny13 Erste Versuche

OP #2394002
Lesenswert?

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 ;)
Gast #2394064
Lesenswert?

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.
OP #2402641
Lesenswert?

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
OP #2402728
Lesenswert?

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 ;)
#2402735
Lesenswert?

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...

...
OP #2402991
Lesenswert?

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
#2403206
Lesenswert?

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...

...
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren