Forum: Mikrocontroller und Digitale Elektronik ATtiny13 Erste Versuche


von Mike L. (loug)


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 ;)

von Bastler (Gast)


Lesenswert?

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)

von Mike L. (loug)


Lesenswert?

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"?

von Hannes L. (hannes)


Lesenswert?

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.

...

von Bastler (Gast)


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.

von Mike L. (loug)


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

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

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

von Mike L. (loug)


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 ;)

von Hannes L. (hannes)


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

...

von Jürgen W. (juergen_w) Benutzerseite


Lesenswert?

Du hast vergessen den Stack zu initialisieren.

z.B.
1
    ldi   r16, RAMEND      ;Stack
2
    out   SPL, r16

von Jürgen W. (juergen_w) Benutzerseite


Lesenswert?

Ups hast du ja weiter unten, würde ich aber an den Programm anfang 
setzen.

von Peter D. (peda)


Lesenswert?

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

von Mike L. (loug)


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

von Hannes L. (hannes)


Angehängte Dateien:

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

...

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
Noch kein Account? Hier anmelden.