Forum: Mikrocontroller und Digitale Elektronik Warteschleife!


von Lutz (Gast)


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!!!!

von Lutz (Gast)


Lesenswert?

Es handelt sich übrigens um C-Programmierung!

von Bernhard S. (bernhard)


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

von Lutz (Gast)


Lesenswert?

Ok, und wie funktiniert die Programmierung eines Timer Interruptes?

von Stefan (Gast)


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.

von Klaus (Gast)


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) !


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.