www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Warteschleife!


Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HAllo!
Ich bin absoluter Anfänger! Ich habe einen Freescale HCS08 MC9S08GT60 
Mikrocontroller und ich soll zwei wait Methode schreiben. Die eine soll 
exakt einmal in ms und die andere in us ablaufen. Also nach wait_ms 
(200) (oder wait_us (100) ) soll wieder etwas passieren. Kann mir einer 
sagen, wie ich das machen muss??? Gibt es da sowas wie einen Universalen 
Samplecode?
Schon mal 1000 Dank!!!!

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es handelt sich übrigens um C-Programmierung!

Autor: Bernhard S. (bernhard)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Es gibt mindestens zwei Lösungsvarianten.

A: Man verwendet einen Timer-Interrupt

B: Man beschäftigt den µC durch eine Warteschleife, wenn er x Takte 
abgearbeitet hat, dann geht's weiter


Bernhard

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, und wie funktiniert die Programmierung eines Timer Interruptes?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grundsätzlich gibt es mehrere Ansätze dafür. Einmal geht sowas über 
Interrupts (Timer, RTC) und zweitens über eine Funktion mit einer 
Däumchendrehschleife.

Beim Däumchendrehen schreibst du dir eine Funktion und berechnest oder 
misst, wie lange die Funktion braucht. Dabei justierst du bei der 
Entwicklung bei gegebener Taktfrequenz solange Anzahl ms gegen 
Schleifendurchläufe, bis die gewünschte Wartezeit erreicht ist. Diese 
Kalibierung pro Taktfrequenz verwendest du dann im finalen Code.

Im allgemeinen hast du dabei eine Grundwartezeit für einen Aufruf der 
Funktion plus Umrechnungen und einen konstanten Zusatzwert für jeden 
zusätzlichen Schleifendurchlauf. In der Schleife selbst wird gerne der 
kürzeste, nichtsmachende Assemblerbefehl "NOP" ausgeführt, damit die 
Schleife nicht wegoptimiert wird.

Das Berechnen kannst du mit Kenntnis der Taktfrequenz des µC, dem 
Assemblerlisting und dem Manual der Assemblerbefehle machen. Manche 
Entwicklungsumgebungen haben Simulatortools mit Anzeige der 
Ausführungszeit von Codeabschnitten.

Das Messen kannst du mit Porttoggeln und Monitoring des Ports auf einem 
Qszilloskop oder Frequenzzähler machen.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man verwendet die Timer-Funktionen.
Einen Interrupt braucht man NICHT bzw. nicht zwingend.
Man nimmt den Timer 7 mit TCNT und TC7.
Siehe unten, Beispiel mit main() // Variante 1

Statt der "Wartezeit" kann man die Sequenzen auch in der Hauptschleife 
unterbringen und am Anfang TC7 laden und am Ende das TFLG1 über while 
abfragen. Dann hat man eine Hauptschleife, die im Raster 1ms läuft 
(natürlich nur wenn restliche Programmlaufzeit < 1ms).
Siehe main() // Variante 2

Längere Zeiten kann man machen, wenn Vorteiler TSCR2 erhöht wird.
Dann TIMECONST_1MS Wert anpassen ; muss sowieso an Clock angepasst 
werden.
Beispiel hier geht davon aus, dass HCS12 mit PLL bereits initialisiert.


Beispiel gilt für HCS12 !
Für HCS08 Timer Doku nachschauen ; vermutlich ähnlich (oder gleich?)



typedef unsigned short uint16;
#define TIMECONST_1MS 6000    // see comment below

void Timer_init(void)
{
 // Assume: System clock is 24 MHz (CPU runs at 48 MHz)
 // prescale is used with "divide by 4" --> 6 MHz
 // this means that 6000 counts represent   1 ms


  TSCR1 = 0x80 ;                  // enable timer by "TEN" bit
  TSCR2 = 2    ;                  // prescale 4
  ;
  TIOS  |= 0x80 ;                 // timer 7 is used
  TOC7M |= 0x80 ;                 // TEST: set output pin on PORT_T
  TCTL1 |= 0x40 ;                 // TEST: invert output pin when OC
  ;
}

//********  wait_ms  ***************
// wait multiple of 1 milli-second,
// Note: uses output compare 7

void Wait_ms(uint16 ms)  { uint16 i;
  for(i=0; i<ms; i++){
     TC7 = TCNT + TIMECONST_1MS ;    // 1ms wait
     TFLG1 = 0x80;                   // clear C7F
     while((TFLG1 & 0x80)==0)  {};   // wait until flag ist set
  }
}

void main(void)    // Variante 1
{
Timer_init();
while(1) // immerzu
  {
  LED_EIN();         // fehlt (Beispiel)
  //  sonstnochwas machen 1
  Wait_ms(23);       // warte jetzt 23 ms
  LED_AUS;           // fehlt (Beispiel)
  }   // immerzu
}

void main(void)   // Variante 2
{
Timer_init();
while(1) // immerzu
  {
  TC7 = TCNT + TIMECONST_1MS ; }  // Delay count for 1 ms wait
  TFLG1 = 0x80;                   // clear C5F
  ;
  LED_EIN();         // fehlt (Beispiel)
  ;
  //  sonstnochwas machen  Teil a)
  //  sonstnochwas machen  Teil b
  //  usw.
  ;
  while((TFLG1 & 0x80)==0)  {};   // warte bis definierte Zeit 
abgelaufen
  ;
  LED_AUS;           // fehlt (Beispiel)
  }   // immerzu
}   // main


 ... oder so ähnlich ... (nicht aktuell getestet) !


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.