Forum: Mikrocontroller und Digitale Elektronik Langzeit Timer mit ATtiny11 Kleine Steuerungsaufgabe


von Jan Purrucker (Gast)


Lesenswert?

Hallo,

ich bin absoluter MikroController-Einsteiger und möchte nun meine erste 
kleine Steuerungsaufgabe lösen:

PB0 soll für ca. 1 Stunde auf "logisch 1" sein, dann für ca. 15 Sekunden 
auf "logisch 0" sein, dann wieder für ca. 1 Stunde auf "logisch 1" und 
sofort (periodisch fortgesetzt). Dazu brauche ich irgendwie einen Timer 
für 1 Stunde und für 15 Sekunden, alles +- 20%, also nur ungefähr.
Als Quarz nehme ich den internen mit 1MHz.
Kann mir jemand einen Assembler Code-Schnipsel mit

- Timer Initialisierung
- Schleifen für die zwei Zeiten

kurz schreiben? Im AVR Tutorial und im Netz hab ich mich schon 
erkundigt, jedoch nichts brauchbares für dieses (ich denke) einfache 
Problem gefunden.
Ich wäre wirklich riesig erfreut, wenn jemand einen 
Assembler-Code-Schnipsel (ohne drum herum) schreiben könnte, oder mir 
einen Link sagen könnte.
Vielen Dank schon einmal für unterstützende Hilfen.

Gruß
Jan Purrucker
(aus dem Schwaben-Ländle)

von Tim (Gast)


Lesenswert?

Zwar kein vollständiger Code aber ein parr tipps (ohne Gewähr):
1
; Timer 0: Overflow IRQ alle CLK/1024/256 Ticks -> 0.262144 Sec
2
  ldi  r16, 0b00000101    ;clk/1024 -> 1,024mSec Periode
3
  out  TCCR0, r16
4
  ldi  r16, 0b00000010    ; enable overflow irq
5
  out  TIMSK, r16
6
  clr  r16      ; reset counter
7
  out  TCNT0, r16
Damit kommt der Overflow Irq alle 0.262144 Sec.
Dann must du im IRQ nur noch feststellen welcher der beiden
Zeiten laufen soll und dementsprechend von
0 bis 3600Sec/0.262144 Sec = 13733 oder
0 bis 15Sec/0.262144 Sec = 57 zählen.

Wenn der zähler seinen wert erreicht hat zurücksetzen, port
umschalten und in einem Register speichern das jetzt der andere
Zähler dran ist.

als Hauptprogramm braucht du dann nur noch eine endlosschleife, ggf
mit einem sleep befehl drin

btw: die internen Taktgeneratoren der AVRs sind keine Quarze sondern 
RC-glieder! Du solltest dir also mal die sache mit dem OSCCAL ansehen...

von Jan Purrucker (Gast)


Lesenswert?

Danke für die Hilfe!

Du hast Recht, es ist ein RC Glied der interne Takt. Der ist relative 
ungenau. Aber ich brauche die Zeiten wie gesagt nur ungefähr so genau, 
daher brauche ich auch kein OSCCAL, sondern muß nur die Fuse-Bits 
entsprechend auf den internen Oszillator einstellen.
Die Entscheidung, ob ich bis 57 oder 13733 zähle mache ich dann, indem 
ich den Status des PB0 abfrage.
Ich versuch mich mal demnächst, und frage hier wieder, sollte was nicht 
funktionieren.
Vielen Dank nochmals für die Hilfe.

Gruß
Jan

von kurfa (Gast)


Lesenswert?

Warum ATtiny11? Wäre nich ATtiny12, oder ATtiny13 besser? (tiny11 kann 
man nur mit assembler programieren...)

von sechseinssechs (Gast)


Lesenswert?

Das Problem ist genuegend trivial um mit ASM geloest zu werden.

von sechseinssechs (Gast)


Lesenswert?

Ob Zaehler0 oder Zaehler1 laeuft sollte man sich in einer Variablen und 
nicht in einem Portbit merken.

von AVRFan (Gast)


Lesenswert?

Das ist sehr einfach zu machen. Du brauchst nur zwei ineinander 
verschachtelte Software-Teiler.  Der eine teilt durch 57 (von 0.262144 s 
auf 14.9422 s), der zweite von 14.9422 s auf ca. 1 h).  Nach dem 
Zählerstand des zweiten schaltest Du den Portpin: "High" wenn 
Zählerstand = 0, "Low" wenn Zählerstand = 1, 2, 3 ... 239.  Das ist 
alles.
1
TOOverflowInterrupt:
2
3
// wird alle 0.262144 s durchlaufen
4
5
inc k
6
IF (k=57) 
7
    {
8
    // wird alle 57*0.262144 s = 14.9422 s durchlaufen
9
10
    k = 0
11
 
12
    inc i
13
    IF (i=240) 
14
        {
15
        i = 0
16
        }
17
18
    PortState = 0
19
    IF (i=0) PortState = 1
20
21
    [PortState auf gewuenschten Portpin ausgeben]
22
    }

von Jan Purrucker (Gast)


Lesenswert?

Hallo AVRFan,

vielen Dank für die nette Erklärung. Nur möchte ich jetzt erst einmal 
Assembler lernen. Könntest du (oder irgendwer hier) mir deshalb bitte 
diese Schleife in Assembler kurz schreiben. Kann nämlich mit C nicht 
viel anfangen. Hab auch schon überlegt wie ich es in Assembler mache, 
aber bin nicht drauf gekommen. Also wenn mir hier jemand weiterhelfen 
könnte wäre ich wirklich riesig dankbar.

Gruß
Jan Purrucker

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Ohne Garantie ;)
1
.def state=r19
2
.def counter_k=r20
3
.def counter_i=r21
4
5
.
6
.
7
.
8
.
9
10
timerint:
11
 inc counter_k
12
 ;counter >= 57 ?
13
 cpi counter_k, 57
14
 brlo int_ende
15
  ;Counter auf 0
16
  ldi counter_k=0
17
  inc counter_i
18
  ;counter = 240 ?
19
  cpi counter_i, 240
20
  brne weiter
21
   ;counter auf 0
22
   ldi counter_i, 0
23
   ;state = 1
24
   ldi state, 1
25
   rjmp int_ende
26
  weiter:
27
   ;state = 2
28
   ldi state, 2
29
int_ende:
30
 reti

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.