Forum: Mikrocontroller und Digitale Elektronik Bestimmte Anzahl Pulse ausgeben mit Timer (Atmega8)


von Stefan B. (stefan361)


Lesenswert?

Hallo,

ich würde gerne an einem Pin ein Rechtecksignal ausgeben, das immer 
zwischen 0 und 1 mit einer bestimmten Frequenz wechselt. Soweit kein 
Problem, ich nehme einen Timer, lasse bei Overflow einen Interrupt 
auslösen und bekomme mein Signal. Mit Hilfe des CTC- Modus und Prescaler 
kann ich auch meine Frequenz variabel gestalten. (Das brauch ich für 
Beschleunigungs- und Bremsrampen). Leider weiß ich nun nur nicht wie ich 
es schaffe, mein Signal so anzupassen, dass ich eine vorher definierte 
Anzahl von High-Pegeln bekomme. (in meinem Fall soll ein Schrittmotor, 
der über eine Schrittmotorsteuerung angesteuert wird (mit Takt und 
Richtung) eine definierte Anzahl Schritte machen) Am liebsten wäre mir 
ein Register, mit dem dann verglichen wird, bis die Anzahl erreicht ist. 
Meine Idee ist, einen zweiten Timer laufen zu lassen, der mit den 
Interrupts des anderen getaktet ist. Ich weiß aber nciht, ob das möglich 
ist.

Ich habe im Forum noch folgenden Artikel gefunden:
Beitrag "LED x-mal blinken lassen mit Timer"

Hier ist es das gleiche Problem, nur halt mit LEDs. Die Idee mit einem 
Vergleich finde ich gut, aber ich kann damit leider nichts anfangen. 
Mein Programm soll in Assembler geschrieben werden und ich möchte wenn 
möglich drei Schrittmotoren ansteuern. (ich befürchte aber, dass ohne 
Muliplexing nur zwei möglich sein werden, wenn ich den einen Timer zum 
Zählen brauch).

Vielen Dank im Vorraus, ich hoffe ich habe keinen Forumsbeitrag 
übersehen in dem das Thema behandelt wird.

Viele Grüße,

Stefan

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:
> Hallo,
>
> ich würde gerne an einem Pin ein Rechtecksignal ausgeben, das immer
> zwischen 0 und 1 mit einer bestimmten Frequenz wechselt. Soweit kein
> Problem, ich nehme einen Timer, lasse bei Overflow einen Interrupt
> auslösen und bekomme mein Signal. Mit Hilfe des CTC- Modus und Prescaler
> kann ich auch meine Frequenz variabel gestalten. (Das brauch ich für
> Beschleunigungs- und Bremsrampen). Leider weiß ich nun nur nicht wie ich
> es schaffe, mein Signal so anzupassen, dass ich eine vorher definierte
> Anzahl von High-Pegeln bekomme. (in meinem Fall soll ein Schrittmotor,
> der über eine Schrittmotorsteuerung angesteuert wird (mit Takt und
> Richtung) eine definierte Anzahl Schritte machen) Am liebsten wäre mir
> ein Register, mit dem dann verglichen wird, bis die Anzahl erreicht ist.
> Meine Idee ist, einen zweiten Timer laufen zu lassen, der mit den
> Interrupts des anderen getaktet ist. Ich weiß aber nciht, ob das möglich
> ist.

Wozu?

Du nimmst eine globale Variable und die zählst du mit jedem Interrupt 
Aufruf herunter (solange sie ungleich o ist). Nur dann wenn dieser 
Zähler ungleich 0 ist, generierst du einen Puls.

> Hier ist es das gleiche Problem, nur halt mit LEDs. Die Idee mit einem
> Vergleich finde ich gut, aber ich kann damit leider nichts anfangen.
> Mein Programm soll in Assembler geschrieben werden

Das macht nichts.
Die Grundidee ist dieselbe. Du musst lernen, dass Programmiersprachen 
eine Idee ausdrücken. Und diese Idee kann man von einer Sprache zur 
anderen transferieren. Ob der Compiler dir eine Variable anlegt, oder ob 
du selber dir mittels .db einen Speicher im SRAM reservierst, dem du 
einen Namen gibst, beides kommt aufs gleiche raus. Der C Compiler nimmt 
dir nur etwas Arbeit beim Zugriff auf den dich interessierenden Wert im 
Speicher ab. Aber er erfindet keine Ideen für dich.

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:
> Hallo,
>
> ich würde gerne an einem Pin ein Rechtecksignal ausgeben, das immer
> zwischen 0 und 1 mit einer bestimmten Frequenz wechselt. Soweit kein
> Problem, ich nehme einen Timer, lasse bei Overflow einen Interrupt
> auslösen und bekomme mein Signal. Mit Hilfe des CTC- Modus und Prescaler
> kann ich auch meine Frequenz variabel gestalten. (Das brauch ich für
> Beschleunigungs- und Bremsrampen). Leider weiß ich nun nur nicht wie ich
> es schaffe, mein Signal so anzupassen, dass ich eine vorher definierte
> Anzahl von High-Pegeln bekomme. (in meinem Fall soll ein Schrittmotor,
> der über eine Schrittmotorsteuerung angesteuert wird (mit Takt und
> Richtung) eine definierte Anzahl Schritte machen) Am liebsten wäre mir
> ein Register, mit dem dann verglichen wird, bis die Anzahl erreicht ist.
> Meine Idee ist, einen zweiten Timer laufen zu lassen, der mit den
> Interrupts des anderen getaktet ist. Ich weiß aber nciht, ob das möglich
> ist.

Wozu?

Du nimmst eine globale Variable und die zählst du mit jedem Interrupt 
Aufruf herunter (solange sie ungleich 0 ist). Nur dann wenn dieser 
Zähler ungleich 0 ist, generierst du einen Puls.

> Hier ist es das gleiche Problem, nur halt mit LEDs. Die Idee mit einem
> Vergleich finde ich gut, aber ich kann damit leider nichts anfangen.
> Mein Programm soll in Assembler geschrieben werden

Das macht nichts.
Die Grundidee ist dieselbe. Du musst lernen, dass Programmiersprachen 
eine Idee ausdrücken. Und diese Idee kann man von einer Sprache zur 
anderen transferieren. Ob der Compiler dir eine Variable anlegt, oder ob 
du selber dir mittels .db einen Speicher im SRAM reservierst, dem du 
einen Namen gibst, beides kommt aufs gleiche raus. Der C Compiler nimmt 
dir nur etwas Arbeit beim Zugriff auf den dich interessierenden Wert im 
Speicher ab. Aber er erfindet keine Ideen für dich.

von Stefan B. (stefan361)


Lesenswert?

Hallo Karl Heinz,

danke für deine Antwort. Mir ist schon bewusst, dass man nur eine Idee 
transferiert. Das mit dem Assembler am Ende so direkt ist etwas 
missverständlich geschrieben, da ich eigentlich nur angegeben wollte, 
dass ich in Assembler programmiere. Ich suche nur dannach ein klares 
Verständnis dafür zu finden was passiert.

So wie es aussieht kann ich die globale Variable herunterzählen und habe 
damit mein Problem gelöst. So ähnlich hatte ich das ja auch vor, nur 
weiß ich nicht genau wie ich das umsetzen kann, da ich noch nicht so 
viel Erfahrung in Assembler habe und mir diese eben aneignen möchte. Ich 
kenn mich in Hochsprachen besser aus, und kann dann schon eine Variable 
definieren oder das übernehmen aber genau deshalb weil ich wissen möchte 
wie es ohne Hochsprache geht, beschäftige ich mich mit Assembler.

Wie wird so eine Idee in Assembler umgesetzt bzw. nach was muss ich 
suchen oder mir anschauen?

Vielen Dank,

Stefan

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:

> So wie es aussieht kann ich die globale Variable herunterzählen und habe
> damit mein Problem gelöst. So ähnlich hatte ich das ja auch vor, nur
> weiß ich nicht genau wie ich das umsetzen kann, da ich noch nicht so
> viel Erfahrung in Assembler habe

Dann wirds Zeit das AVR-Tutorial zu studieren.
Dort findest du auch einen Abschnitt, wie man das SRAM dazu benutzt um 
sich dort Werte zu speichern, bzw. von dort zu lesen.
Eben das, was man in einer Hochsprache eine Variable nennt.

AVR-Tutorial: SRAM

von Stefan B. (stefan361)


Lesenswert?

Danke ich werde mir das mal ausgiebig anschauen.

Und die Aktion führe ich dann mit einer ISR, bei jedem Interrupt aus 
oder?

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:
> Danke ich werde mir das mal ausgiebig anschauen.
>
> Und die Aktion führe ich dann mit einer ISR, bei jedem Interrupt aus
> oder?

Ja.
Dort wo du dann ja auch deine Pulse generierst.
Im Moment generierst du sie immer. In späterer Folge nur dann, wenn die 
zu erzeugende Anzahl noch nicht erreicht ist. Das wiederrum verrät dir 
diese 'Variable', die bei jedem ISR Aufruf um 1 heruntergezählt wird. 
Hat sie 0 erreicht, dann weißt du, dass alle Pulse erzeugt wurden.

von Stefan B. (stefan361)


Lesenswert?

Danke eine Frage hätte noch. Ich werde diese das nächste mal kompakter 
gleich mit in die andere Frage stellen, dass ist nicht der beste Weg so. 
Entschuldigung dafür.

Diesmal gehts eher um hardwaretechnische Sachen.
Ich möchte ja insgesamt drei Schrittmotoren ansteuern. Da ich drei Timer 
zu Verfügung habe solle dies doch gehen oder?

Nun ist bei mir an Port PB3 (Atmega8) auch ein Teil des ISP-Anschlusses 
angelegt. Im Teil I/O-Grundlagen ist ja zu lesen, dass dies für LEDs 
keine Rolle spielt. Gilt dies auch für meine Art von Signalen?

Nochmals Danke und einen schönen 2.Weihnachtsfeiertag Rest,

Stefan

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:

> Ich möchte ja insgesamt drei Schrittmotoren ansteuern. Da ich drei Timer
> zu Verfügung habe solle dies doch gehen oder?

Da du die Beschleunigungsrampen über Timereinstellungen abwickeln 
willst, wirds wohl darauf hinauslaufen.

> Nun ist bei mir an Port PB3 (Atmega8) auch ein Teil des ISP-Anschlusses
> angelegt. Im Teil I/O-Grundlagen ist ja zu lesen, dass dies für LEDs
> keine Rolle spielt. Gilt dies auch für meine Art von Signalen?

Sagen wir mal so:
Aus AVR Sicht:
  Alles was aus AVR Sicht ein Ausgang darstellt, ist aus seiner Sicht
  erst mal unproblematisch. Probleme gibts nur dann, wenn deine externe
  Schaltung partout den Pin auf +5V ziehen will und dein Brenner den Pin
  auf 0V ziehen will. Dann arbeiten 2 Schaltungen gegeneinander und
  jeder wird versuchen seine Sicht der Dinge am µC Pin durchzusetzen.
  Was meistens schief gehen wird.

Aus Sicht der externen Schaltung:
  Der ist es ja egal, wer am Pegel wackelt. Die interessiert nur
  die Spannungspegel. Ob an dem Pin jetzt abwechselnd 0V oder 5V
  anliegen, weil dein Programm an den Pins spielt, oder ob die
  Pegel anliegen, weil der Brenner gerade ein neues Programm
  einspielt .... das kann ja deine Hardware nicht wissen. Die wird
  daher das tun, wofür sie gebaut wurde, wenn der Pegel laufend
  sich ändert. Wenn da ein paar LED drann hängen, dann flackern die
  halt während des Programmierens, aber das tut keinem weh.
  Wenn da allerdings ein Schrittmotor drannhängt, der laufend
  Schritte macht, .....

von Stefan B. (stefan361)


Lesenswert?

Ok gut, dass sollte aber kein Problem sein. Ich werde einfach den 
Schrittmotoren während des Programmierens die Versorgungsspannung 
entziehen, dann bewegen sich die auch nicht.

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.