Forum: Mikrocontroller und Digitale Elektronik Frage zu Delays mit Timer und Frage zu Events


von hawx (Gast)


Lesenswert?

Wir haben folgende Aufgabenstellung:
Erstellen Sie ein Programm mit welchem die Prellanzahl der Taster SW1 
und SW2 gemessen
wird. Die Messung soll auf 2 Arten durchgeführt werden:
• SW1: Pegeländerungs-Interrupt und Hochzählen der Prellanzahl in der 
ISR
• SW2: Pegeländerungs-Event ist die Taktquelle für einen Timer ➜ 
Prellanzahl steht im
CNT-Register
Wird der erste „Preller“ detektiert, so muss kurz gewartet werden (Delay 
>100ms) um alle
Preller zu messen. Danach soll der Wert auf den 4 LEDs ausgegeben werden 
(Werte größer
15 auf 15 begrenzen, sonst stimmt die Anzeige nicht). Nach kurzem Delay 
(>1s) sollen die
LEDs wieder gelöscht werden und die Messung kann erneut durchgeführt 
werden.
Betreiben Sie den XMega mit 32MHz für ein genaueres Ergebnis.

Der µC ist ein ATXMEGA128A1
Mein bisheriger Fortschritt:
http://pastebin.com/VbuvnWLM

Nun zu meiner eigentlichen Frage:
Wie kann ich mit dem Timer Delays machen (also ohne 
Verzögerungsschleifen). Wie funktioinert das überhaupt? Der Lehrer 
meinte wir sollen einen OVF-interrupt benutzen, aber wieso?

Ich versteh die Aufgabenstellung nicht, denn wenn ein Preller mal 
erkannt wurde, wieso warte ich dann 100ms?(da sind die Preller wsl schon 
alle weg oder) und was soll ich da zählen wenn die eh schon alle weg 
sind?

von Karl H. (kbuchegg)


Lesenswert?


von Karl H. (kbuchegg)


Lesenswert?

> Ich versteh die Aufgabenstellung nicht, denn wenn ein Preller mal erkannt wurde, 
wieso warte ich dann 100ms?

Du wartest nicht 100ms, sondern du lässt den Versuch 100ms laufen. 
Beginnend mit der ersten Pegelveränderung.

> und was soll ich da zählen wenn die eh schon alle weg sind?

du sollst ja auch während dieser 'Wartezeit' die Preller zählen.

Nur musst du halt aber auch irgendwann mal sagen: jetzt kommt mit 
Sicherheit kein Preller mehr, noch länger Warten macht keinen Sinn mehr. 
Ich erkläre die Messaufnahme für abgeschlossen, das jetzt vorliegende 
Ergebnis ist das Endergebnis.
IN deinem Beispiel ist dieser Zeitpunkt dann eben 100ms nach Beginn des 
Tastendrucks (der ersten Pegeländerung am Port).

von NurEinGast (Gast)


Lesenswert?

> Ich versteh die Aufgabenstellung nicht, denn wenn ein Preller mal
> erkannt wurde, wieso warte ich dann 100ms?

Du sollst - nachdem der ersten Preller erkannt wurde 100 mS warten.
In dieser Zeit zählt der Zähler hoch.
Nach 100 mS sollte Du den Zähler auslesen und die Daten anzeigen.

Also - 100mS nach dem Event den Zähler auslesen. Dann hat er 100 mS Zeit 
die Preller zu zählen.

von hawx (Gast)


Lesenswert?

hmmm ok, das klingt wenigstens logisch

Kann mir jemand vielleicht erklären, wie man das jetzt mit den 100 ms 
genau realisiert (also wie macht man eine Warteschleife (ohne wirkliche 
Schleife) mit dem Timer

von Karl H. (kbuchegg)


Lesenswert?

hawx schrieb:
> hmmm ok, das klingt wenigstens logisch
>
> Kann mir jemand vielleicht erklären, wie man das jetzt mit den 100 ms
> genau realisiert (also wie macht man eine Warteschleife (ohne wirkliche
> Schleife) mit dem Timer

Das goile ist, dass mit diesen Vorgaben
1
• SW1: Pegeländerungs-Interrupt und Hochzählen der Prellanzahl in der ISR
2
• SW2: Pegeländerungs-Event ist die Taktquelle für einen Timer ➜ Prellanzahl steht im
3
CNT-Register
du die 100ms im Grunde überhaupt nicht mit einem Timer machen musst, 
weil die ganze Zählerei im Hintergrund durch Interrupts passiert, bzw. 
der Timer ganz von alleine die Preller zählt.

D.h. dein Code ist im Prinzip so
1
   warte auf Flanke am Tastereingang
2
3
   Setze den Zähler auf 0
4
   _delay_ms( 100 );
5
6
   Lies den Zähler aus

Ein Timer, der die 100ms abzählt, wäre zwar möglich, bringt aber 
überhaupt nichts. Zumal es an dieser Stelle noch nicht einmal darauf 
ankommt, dass die 100ms auf den Taktzyklus genau sind.

: Bearbeitet durch User
von Basti M. (counterfeiter)


Lesenswert?

1
while(1)
2
{
3
  if(PIN_X == low) {
4
    delay_ms(100);
5
    if(!show_cnt)
6
      zeige_isr_counter();
7
    else
8
      zeige_cnt_counter();
9
    delay_ms(1500);
10
    delete_leds();
11
  }
12
}

von hawx (Gast)


Lesenswert?

und wieso verwende ich da einen overflow interrupt

alles schön ung gut, aber das Ganze soll in Assembler geschehen (habe 
einen pastebin-Link gepostet, von meinem aktuellen Fortschritt) und mein 
Problem ist, dass ich eben nicht die Zusammenhänge nicht verstehe. In 
den CNT-Register schreibe ich die 100ms, oder wie? und im PER musss ich 
ja auch was tun?

von Basti M. (counterfeiter)


Lesenswert?

Du sollst den Timer nicht als Timer benutzen, sondern als Zähler und den 
sollst du anscheinend durch das XMega Eventsystem triggern!

Sollen wir dir jetzt das Programm in ASM vorkauen? Bisschen was, 
solltest du auch selbst für die Hausaufgabe machen...

von hawx (Gast)


Lesenswert?

das war die antwort, was ich gebraucht hab

Basti M. schrieb:
> Du sollst den Timer nicht als Timer benutzen, sondern als Zähler und den
> sollst du anscheinend durch das XMega Eventsystem triggern!

Basti M. schrieb:
> Sollen wir dir jetzt das Programm in ASM vorkauen? Bisschen was,
> solltest du auch selbst für die Hausaufgabe machen...

nicht alles vorkauen, sondern mir helfen:

Oder darf ich das alles jetzt so verstehen:
Taste gedrückt. Hier bei jedem overflow beim Timer zähle ich den counter 
hoch, dabei wird dieser zählschritt (bzw. interrupt) so oft wiederholt 
bis sich die 100ms fertig ausgeführt worden sind?

ABER wieso wird die Prellanzahl im CNT-Register gespeichert. CNT ist ja 
unser "Timer-Counter" der unser countervalue speichert der im 
Normalmodus bis PER zählen darf.

und bissl was hab ich sicher schon und zwar fehlt mir nur mehr das mit 
dem Zählen (siehst du im pastebin link) und das auch nur weil mir das 
unklar war bzw. immer noch nicht, falls ich mit der obigen 
Niederschreibung meiner Erkenntnisse aus euren Posts falsch liege :)

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.