mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer in Assembler / Beispielaufgabe?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: O. A. (sokrates1989)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe mich ein wenig in die Theorie zum Thema des Timers in AVR 
eingelesen. Allerdings weiß ich nicht wie soetwas praktisch aussehen 
würde.

Angenommen ich möchte eine Led genau 2sec einschalten und 2 sec 
ausschalten.
(Mit einem Atmega8)
Wie mache ich das? Gibt es irgendwo ein einfaches Beispiel wo man sich 
soetwas anschauen könnte. Wie gestalte ich den Timer dass ich ihn im 
Sekundentakt verwenden kann. Müsste man das mit Vorteiler machen? Aber 
wie?

Danke...

Autor: S. Landolt (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Artikelsammlung - nicht gesucht, nicht gefunden oder nicht verstanden?
Z.B.
https://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer
bietet doch einiges.

Autor: O. A. (sokrates1989)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
S. Landolt schrieb:
> Artikelsammlung - nicht gesucht, nicht gefunden oder nicht verstanden?
> Z.B.
> https://www.mikrocontroller.net/articles/AVR-Tutorial:_Timer
> bietet doch einiges.

doch habe ich gesehen...werde ich gleich mal ausprobieren.

Autor: O. A. (sokrates1989)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das Beispiel im AVR Studio durchgespielt. Wenn ich den 
Prescaler erhöhe, z.b auf 1024 dann reduziert sich meine Frequenz. Aber 
ich wüsste immer nicht wie ich etwas im Sekundentakt ansteuere.

Ich habe eine Aufgabe vorliegen, da sollen 2 Ausgänge geschaltet werden.
Der erste Einschaltverzögert mit 3 sec.
Der zweite Ausschaltverzögert mit 5 sec.

Würde mich über Hilfe freuen.

Autor: Karl M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo O. A.,

im Datenblatt des Atmega8 findet man Informationen über 8 Timer.
Jeder Timer[0-2] hat andere Eigenschaften, insbesondere lässt er sich 
unterschiedlich einstellen.
Je nach Einstellung und Timervorteiler ergeben sich eine andere 
Berechnung, dazu findet man eine Formel im Datenblatt.

*8-bit Timer/Counter0*
...

*16-bit Timer/Counter1*
unter "Modes of Operation" findet man:
# Normal Mode
# Clear Timer on Compare Match (CTC) Mode
# Fast PWM Mode
# Phase Correct PWM Mode
# Phase and Frequency Correct PWM Mode

*8-bit Timer/Counter2*
...

_Beispiel_:
Wir setzen Timer1, im CTC Modus

Aus Tabelle 39 lesen wir ab:
Mode = 4 --> WGM1[3-0] = 0b0100

Zählregister ist OCR1A

Im Datenblatt auf Seite 88 finden wir folgende Formel:
f_OC1A = F_CPU / (2  N  (1+OCR1A))

Diese kann man einfach umstellen --> Schule:
f_OC1A = F_CPU / (2* N* (1+OCR1A)) <==>
2* N* (1+OCR1A) = F_CPU / f_OC1A   <==>
1+OCR1A = F_CPU / (f_OC1A *2 *N)   <==>
OCR1A = F_CPU / (f_OC1A *2 *N) -1

Wobei N E {1,8,64,256,1024}, der Timer1 Prescaler ist

N ist dabei die "Abstufung" für den Timer.

Reale Rechnung in meinen Programmen:
F_CPU = 8*10⁶ ; [Hz]
f_OC1A = 1000 ; [Hz]
Da OCR1A eine 16Bit Werte Aufnehmen kann, muss für die Rechnung der 
passenden Timer1 Prescaler gewählt werden.

OCR1A = 8*10⁶ /(1000 *2 *N) -1
OCR1A = 8*10³ /(2 *N) -1

Wir setzen hier N = 8:
OCR1A = 8*10³ /16 -1
OCR1A = (500 -1)

Wäre N = 1, so folgt:
OCR1A = 8*10³ /2 -1
OCR1A = (4000 -1)

Wir sehen also für N = {1,8} ergeben sich sinnvolle Einstellungen, um 
eine 1000Hz Schwingung zu erzeugen.

Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
O. A. schrieb:
> Aber
> ich wüsste immer nicht wie ich etwas im Sekundentakt ansteuere.

Wichtig ist, dass du erstmal sowas wie ein Timer Tick hin bekommst.
Das scheinst du ja schon geschafft zu haben....

Dann brauchst du einen Tick Zähler im Speicher.
Und immer, wenn 1 Sekunde erreicht, dann tue dein Ding.
Die Anwendung der Grundrechenarten und ein paar Vergleiche reichen 
dafür....

: Bearbeitet durch User
Autor: Christian S. (roehrenvorheizer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch ein alter Hut:

Beitrag "Die genaue Sekunde / RTC"

MfG

Autor: S. Landolt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, da gibt es viele Wege!
(... sagte der Geist und strahlte)

Eine Art Uhr und dann rechnen, hat bereits Arduinos Fanboy 
vorgeschlagen.
Wenn man etwas mehr über Timer lernen will, dann für jede Teilaufgabe 
einen eigenen Timer nehmen, der ATmega8 hat ja deren 3.
Und dann gibt es sicher noch ein halbes Dutzend Variationen davon.

Haben Sie denn schon eine Idee oder einen Ansatz, den Sie uns vorzeigen 
können und worauf sich aufbauen lässt?

Autor: S. Landolt (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
In Ergänzung des Beispiels aus dem Artikel hier etwas mit den verlangten 
3 Sekunden, minimalistisch, d.h. ohne Interrupt (führt in dieser Form 
jedoch in eine Sackgasse, dient also nur zur Anschauung bzw. zum 
Lernen).

; cave: setzt Startwerte nach Reset laut Datenblatt voraus

.include "m8def.inc"               ; mit Werkseinstellung: 1 MHz

.equ    DDR_A1      = DDRB          ; Ausgang1: einschaltverzoegert 3 s
.equ    PORT_A1     = PORTB
.equ    A1          = 0

.def    tmp0        = r16

.cseg   ; flash
.org $0000

    sbi     DDR_A1,A1               ; Pin auf Ausgang schalten

; Startereignis:
    ; keine Ahnung

; Ausgang1: Timer1 mit 1 ms -> 3 s
    cbi     PORT_A1,A1              ; ausschalten
    ldi     tmp0,high(3000)         ; Timer1-Output-Compare auf 3000 (ms)
    out     OCR1AH,tmp0
    ldi     tmp0,low (3000)
    out     OCR1AL,tmp0
    ldi     tmp0,(1<<CS12)|(1<<CS10) ; 1 MHz /1024: so etwa 1 ms
    out     TCCR1B,tmp0             ; Start

loop:
     in     tmp0,TIFR               ; warten, bis Timer1 auf 3000 (ms)
     sbrs   tmp0,OCF1A              ; gezaehlt hat
    rjmp    loop    

    sbi     PORT_A1,A1              ; einschalten

  rjmp      pc


Autor: c-hater (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
S. Landolt schrieb:

> In Ergänzung des Beispiels aus dem Artikel hier etwas mit den verlangten
> 3 Sekunden, minimalistisch, d.h. ohne Interrupt (führt in dieser Form
> jedoch in eine Sackgasse, dient also nur zur Anschauung bzw. zum
> Lernen).

Verlorene Liebesmüh'. Der Kerl will einfach nur seine Hausaufgaben von 
einem anderen für lau gemacht bekommen. Der ist weder willig, sich 
irgendwas anzuschauen, noch will er irgendwas lernen.

Autor: S. Landolt (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
O.A. hat in gepflegter Form um Hilfe gebeten.
Er hat meine Eingangsfrage indirekt beantwortet: "nicht verstanden".
Ich vergebe mir nichts mit dieser Fingerübung.
Warum sollte ich nicht versuchen, ihm zu helfen?

Autor: Staatsversager (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
c-hater schrieb:
> Verlorene Liebesmüh'. Der Kerl will einfach nur seine Hausaufgaben von
> einem anderen für lau gemacht bekommen. Der ist weder willig, sich
> irgendwas anzuschauen, noch will er irgendwas lernen.

Es gibt noch etwas, was vergebliche Mühe bedeutet: Auch nur einen Satz 
von Deinem immer gleichen Gesülz für bare Münze zu nehmen.

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
S. Landolt schrieb:

> Warum sollte ich nicht versuchen, ihm zu helfen?

Weil Hilfe auch kontraproduktiv sein kann.

Wenn der Kerl sich in seiner Auffassung des Lebens bestätigt sieht (man 
muss nur einen Idioten finden, der mir das für lau liefert) wird er 
zeitlebens ein Sozialfall sein und damit schädlich für sich und die 
Gesellschaft.

Das ist in etwa so, als wenn du einem Drogenabhängigen als "Hilfe" die 
nächste Dosis seines Gifts besorgst...

Er hatte im Thread bereits alles bekommen, was nötig ist, um aus eigener 
Kraft das Problem lösen zu können. Das ist echte Hilfe. Hilfe zur 
Selbsthilfe.

Das schöne Bild: gib dem Hungernden keinen Fisch, sondern erkläre ihm 
Bau und Benutzung einer Angel. Dann steht er nämlich nicht morgen schon 
wieder bei dir auf der Matte und bittet um Mitleid und Almosen...

Autor: S. Landolt (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Ich hatte, im Gegensatz zu Ihnen, den Eindruck, dass O.A. eben noch 
nicht alles Nötige bekommen hatte, nicht bei seinem Kenntnisstand. Und 
für mich gilt auch hier der alte Geschäftsgrundsatz 'Ich muss den Kunden 
dort abholen, wo er steht'.
  Was nun aber den Begriff 'Sozialfall' angeht, so kann man diesen auch 
ganz anders interpretieren!
  Damit ist aber das Thema für mich durch, ich wünsche Ihnen einen Guten 
Abend.

Autor: O. A. (sokrates1989)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Ich weiß nicht welche Mission du hast C-hater. Anstatt hier irgendwelche 
unnötigen Diskussion über mich anzufangen, bitte ich dich inständig: 
Vergeude doch einfach nicht deine Zeit mit einem Sozialfall wie mir. Und 
für die anderen Antworten möchte ich mich schonmal bedanken, ich werde 
es mir morgen in aller Ruhe anschauen.

: Bearbeitet durch User
Autor: Dirk B. (dirkb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kinderkram wie das Hausaufgaben Problem musste der Betroffene nach 
seinem Bericht schon vor 30 Jahren machen,ohne dass es wohl was gebracht 
hat, aber eine etwas andere Wortauswahl bzw.Vorstellung der Tätigkeit 
eines Timer/ Counter kann (muss nicht) evtl. helfen das Problem zu 
finden.
Nicht nur im deutschen wird Hz genauso für Anzahl der Schwingungen und 
Anzahl der Tätigkeiten je Sekunde genutzt, was ja auch häufig sehr eng 
verbunden ist, aber manchmal für den einen die eine Betrachtungsweise 
und den andere verständlicher macht.

Etwas albern eine altmodische Uhr mit 2 Hz (Tick + Tack)/sek vorgestellt 
bei der der Prescaler 60 gerade in der Werkstatt ist und mit 8 bit 30min 
gewartet werden soll. Prescaler 2 (wg. Zeiger) 10,100,1000 sind noch in 
Ordnung, aber ohne den gewohnter 60er ist das fast wie die andere 
Aufgabe.
Der erste Versuch mit praktischem 1min-Tick :
1 Min==60s*2 Tätigkeiten/sek[2Hz] == 120 Tätigkeiten bzw. Takte vom 
Prescaler zumindest bis 60 zählen zu lasen geht wg. der Werkstatt schief
Der zweite Versuch: 30min = 30*60*2 Tätigkeiten = 360TfZ [TfZ:zu 
zählende (T)ätigkeiten (f)ür die (Z)eit] mit Prescaler 10 passt dann in 
ein byte und ein Programm könnte:
prescaler10 timer //'Vorzähler' tick/tack/tick/....und 

  bool compZ (int anz_tät){ ret= timer > anz_tät}
  
 lampe_aus
   while !compZ(36)do ;
 lampe_an  //30min gewartet
  sehr sehr ungefähr so aussehen. Die Funktion compZ ist praktisch schon 
im counter eingebaut und wird ansonsten  eher mit
loop:
     in     tmp0,func(compZ)+div.t_flags ; warten, bis Timer1 auf 30 (min)
     sbrs   tmp0,flagbit(compZ)         ; gezaehlt hat
    rjmp    loop   
aufgerufen.

Beim dritten Versuch die Uhr dann mit 8MHZ übertakten und nachzählen wie 
viele Tätigkeiten (bei timern/coutern meist Berechnung von t=t+1 ) von 
den 8 Millionen in der Sekunde gezählt werden müssten bis eine Sekunde 
vorbei ist....

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.