B.4  Aufgaben aus Kapitel 4

1.
Welche verschiedenen Betriebsarten kennt der Timer B? Wozu brauche ich diese?
Continuous-Mode:
Das Zählregister wird kontinuierlich bis zum höchsten Wert 0xFFFF hochgezählt, beginnt dann wieder bei 0x0000.
Up-Mode:
Das Zählregister wird bis zum Wert des TACCR0-Registers hochgezählt, beginnt dann wieder bei 0x0000.
Up/Down-Mode:
Das Zählregister wird bis zum Wert des TACCR0-Registers hochgezählt, wo es dann seine Zählrichtung ändert und bis 0x0000 heruntergezählt wird. Dort ändert es wieder seine Zählrichtung.
Stop-Mode:
Der Timer ist angehalten.

 
 

2.
Erweitere die in den Aufgaben zu Abschnitt 2.5 entwickelte Ampelsteuerung so, dass die Grün- und Rotphase genau zehn Sekunden dauert und im Wechsel zwischen den Phasen genau eine Sekunde gelb ist.
Anstelle der Waiting-Funktion verwenden wir eine Timer-basierte Wartefunktion

 
 

  void waiting(int zeit) 
  { 
   int index; 
   TACTL |= MC_2;        // los gehts im Continuous-Mode 
   for (index=0; index<zeit; index++) 
   { 
    TACTL |= TACLR;     // Rücksetzen des Zählers 
    while (TAR <32768); // warten bis Ablauf 
   } 
  } 
 
int main ( void ) { 
... 
  // wir haben einen 32kHz-Uhrenquarz angeschlossen 
  BCSCTL1 &= ~XTS;          // LF-Mode 
  _BIC_SR(OSCOFF);          // XT1 anschalten 
  TACTL    = TASSEL0;       // wähle ACLK, DIV = 1 
... 
}
3.
Wozu brauche ich den Watchdog-Timer?
Zur Überprüfung der korrekten Betriebsfunktion meiner Software. Geht bei der Programmabarbeitung etwas schief und die Abarbeitung des Programms erfolgt nicht mehr geordnet, so wird auch der Watchdog nicht zurückgesetzt. Läuft er ab, löst er einen Reset des Prozessors aus und stellt so einen definierten Zustand her.

 
 

4.
Schreibe ein Programm, das für eine Autorennbahn einen Rundenzähler mit Zeitmessung realisiert.
Im Wesentlichen greifen wir dazu auf das eben in Frage 6 implementierte Task-System zurück. In der Interrupt-Routine zählen wir einfach die Sekunden hoch. Das Überschreiten der Ziellinie messen wir mit einer Lichtschranke, die wir an Port 1.1 und 1.2 anschließen. Die Zeitnahme erfolgt in der zugehörigen Interrupt-Routine. Immerhin kann man so 18 Stunden ohne Zeitüberlauf Autorennen fahren.

 
 

 \\.... Interrupt Routine und Initialisierung aus 
 \\     RTC-Beispiel 
 
 #pragma vector=PORT1_VECTOR 
__interrupt void Port_1(void) 
 { 
  if(P1IFG & BIT1) 
  { 
  runde_bahn1 ++; 
  rundenzeit1 = sekunde-altezeit1; 
  altezeit1=sekunde; 
  } 
 
  if(P1IFG & BIT2) 
  { 
  runde_bahn2 ++; 
  rundenzeit2 = sekunde-altezeit2; 
  altezeit2=sekunde; 
  } 
 
 P1IFG = 0x00;           // Interrupt-Flag löschen 
 }
5.
Wozu besitzt der Timer A mehrere Capture/Compare-Kanäle
Auf einfache Art und Weise können so parallel mehrere Ausgänge, die auch noch miteinander synchronisiert sind, erzeugt werden.

 
 

6.
Schreibe ein einfaches Task-System, das einmal pro Sekunde eine Funktion ausführt. Überwache die Betriebsbereitschaft mit dem Watchdog-Timer.
#include  <msp430x16x.h> 
 
#pragma vector=TIMERA0_VECTOR 
__interrupt void TIMERA0(void){ 
// Der Interrupt kommt ja 1* pro Sekunde 
// hier die Funktionalität implementieren 
} 
 
void main(void) { 
 
  // Watchdog-Timer konfigurieren: 
  WDTCTL=WDTPW+WDTIS1;     // SMCLK/8192 
 
  // wir haben einen 32kHz Uhrenquarz angeschlossen 
  BCSCTL1 &= ~XTS;          // LF-Mode 
  _BIC_SR(OSCOFF);          // XT1 anschalten 
 
  TACTL    = TASSEL0;       // wähle ACLK, DIV = 1 
  TACTL   |= MC_1;         // Up-Mode 
  TACCTL0  = CCIE;          // Cap/Comp-Interrupt aktivieren 
  TACCR0   = 32767;         // von 0 bis 32767 zählen 
 
  _enable_interrupts ();    // Interrupts global aktivieren 
 
  while(1) {                // Endlosschleife 
  WDTCTL=WDTPW+WDTCNTCL;    // Watchdog-Reset 
  } 
}
7.
Wie kann ich einen 32-Bit-Timer realisieren?
Indem ich den Ausgang eines Timers auf einen Pin lege und diesen mit dem Takteingang des zweiten Timers verbinde. Alternativ zähle ich in jedem Überlauf-Interrupt ein zweites Zählregister hoch.