#include "hardware.h" #include #define SYSFREQ 12000000l /* Systemtakt in Hz */ #define FREQPWM 2000l /* Taktfrequenz fuer Drehspulanzeige und Tastenabfrage */ #define PERIODEPWM (SYSFREQ / FREQPWM /2) /* Wert fuer Timer um FREQPWM zu erreichen */ #define TASTENZEIT (FREQPWM / 10) /* Wartezeit fuer Tastenentprellung */ #define TASTENZEITREPEAT (FREQPWM / 3) /* Wartezeit fuer Auto-Repeat der Tasten */ #define SCANTEMPO 400 #define STUETZSTELLEN 24 /* Liste der Zaehlerwerte fuer die gewuenschten Frequenzen, die durchgescannt werden */ /* Der Wert in Hz ist SYSFREQ / freq[x] / 2, da mit jedem Interrupt der Ausgang die Polaritaet wechselt. */ /* Die Zaehlerwerte sind gerundet und treffen die gewuenschte Frequenz nicht immer genau. */ const int freq[STUETZSTELLEN] = {300, 255, 222, 197, 176, 160, 146, 135, 125, 117, 109, 103, 97, 92, 87, 83, 79, 75, 72, 69, 67, 64, 62, 60}; #define DREHSPULMAX 100 /* Da die Drehspulanzeige nicht linear ist, wird fuer jede Frequenz der enstprechende PWM- Wert hier in dieser Liste hinterlegt. */ /* 20,0 23,5 27,0 30,5 34,0 */ const int anzeige[STUETZSTELLEN] = { 1, 6, 9, 12, 15, /* 37,5 41,0 44,5 48,0 51,5 */ 17, 20, 22, 25, 27, /* 55,0 58,5 62,0 65,5 69,0 */ 30, 32, 36, 38, 41, /* 72,5 76,0 79,5 83,0 86,5 */ 45, 49, 53, 58, 62, /* 90,0 93,5 97,0, 100*/ 70, 75, 81, 89}; volatile int findex; /* Index der momentan benutzten Frequenz */ volatile int anzzaehler; /* Zaehler fuer Drehspul PWM */ volatile int anzeigenwert; /* Wert, der ans Drehspulwerk ausgegeben werden soll */ volatile int delayzaehler; /* Fuer Wartezeit */ volatile int tastenzaehler; /* Fuer Autorepeat bei gedrueckter Taste */ volatile int tastenwert; /* Wert der gedrueckten Taste */ volatile int taste_gedrueckt; /* Flag, dass Taste gedrueckt wurde */ /* Dieser Interrupt kommt mit der Folgefrequenz * 2, die fuer den Mischer gebraucht wird Der Ausgang wechselt mit jedem Auftreten automatisch. Die Interruptroutine muss nur den neuen zu erreichenden Zaehlerwert eingeben. */ interrupt (TIMERA0_VECTOR) timera0_interrupt(void) { TACCR0 += freq[findex]; } /* Dieser Interrupt kommt mit der PWM Frequenz von 2kHz. Er wird zur Tastenabfrage, Zeitmessung und Drehspulmesswerkansteuerung benutzt. */ interrupt (TIMERA1_VECTOR) timera1_interrupt(void) { eint(); /* Interrupts wieder zulassen, damit TIMERA0 weiterhin drankommen kann. */ switch (TAIV) { /* Nur bei Ueberlauf von TACCR1 */ case 2: TACCR1 += PERIODEPWM; /* Neuen Zaehlervergleichswert speichern */ /* Zeitmessung */ delayzaehler++; /* Fuer Backgroundzeitmessungen hochzaehlen */ /* Anzeige PWM */ anzzaehler++; /* Zaehler fuer Drehspul PWM hochzaehlen */ if (anzzaehler >= DREHSPULMAX) { /* Drehspul PWM zaehlt bis DREHSPULMAX */ anzzaehler=0; FREQANZ_AN; /* Beim Zuruecksetzen wird der Ausgang auf Eins gesetzt */ } if (anzzaehler > anzeigenwert) { FREQANZ_AUS; /* Wenn der momentane PWM Wert erreicht ist, wird der Ausgang abgeschaltet */ } /* Tastenbehandlung */ if (TASTE_GEDRUECKT) { if (tastenzaehler == (TASTENZEIT - 1)) { /* Kurz vor Ende der Tastenentprellzeit wird der Tastenwert gespeichert */ tastenwert = TASTE_WERT; } if (tastenzaehler >= TASTENZEITREPEAT) { /* Wenn die Repeatzeit abgelaufen ist, wird wieder gemeldet, dass Taste erneut gedrueckt wurde */ taste_gedrueckt = 1; tastenzaehler = 0; /* Zeit beginnt erneut fuer Repeatzeit */ } tastenzaehler++; /* Bei gedrueckter Taste wird diese Zeit gezaehlt */ } else { if (tastenzaehler >= TASTENZEIT) { /* Wenn nach TASTENZEIT losgelassen wird, gilt Taste als gedrueckt. */ taste_gedrueckt = 1; } tastenzaehler = 0; /* Fuer Autorepeat Zaehler erneut beginnen */ } break; case 4: break; case 10: break; default: ; } } /********************************************************************/ int main(void) { int scan; WDTCTL = WDTCTL_INIT; /*Init watchdog timer */ P1OUT = P1OUT_INIT; /* Init output data of port1*/ P2OUT = P2OUT_INIT; /* Init output data of port2*/ P1SEL = P1SEL_INIT; /*Select port or module -function on port1 */ P2SEL = P2SEL_INIT; /*Select port or module -function on port2 */ P1DIR = P1DIR_INIT; /* Init port direction register of port1*/ P2DIR = P2DIR_INIT; /*Init port direction register of port2*/ P1REN = P1REN_INIT; P2REN = P2REN_INIT; P1IES = P1IES_INIT; /*init port interrupts*/ P2IES = P2IES_INIT; P1IE = P1IE_INIT; P2IE = P2IE_INIT; DCOCTL = CALDCO_12MHZ; /* 12MHz sind die gewuenschte Systemfrequenz */ BCSCTL1 = XT2OFF | CALBC1_12MHZ; TACTL = TASSEL_SMCLK | ID_DIV1 | MC_CONT | TACLR | TAIE; findex = 0; TACCR0 = freq[findex]; TACCR1 = PERIODEPWM; TACCTL0 = CM_DISABLE | CCIS_GND | SCS_ASYNC | CAP_COMP | OUTMOD_TOGGLE | CCIE | OUT_LOW; TACCTL1 = CM_DISABLE | CCIS_GND | SCS_ASYNC | CAP_COMP | OUTMOD_TOGGLE | CCIE | OUT_LOW; eint(); scan = 1; /* zu Beginn wird automatisch gescannt */ anzzaehler = 0; anzeigenwert = 0; taste_gedrueckt = 0; /* zunaechst gilt keine Taste als gedrueckt */ while (1) { if (scan) { /* Wenn der automatische Scan eingeschaltet ist */ /* naechst hoehere Frequenz einstellen */ if (findex < STUETZSTELLEN - 1) { findex++; } else { /* wieder unten anfangen, wenn hoechste erreicht */ findex = 0; } /* Den neuen Frequenzwert anzeigen */ anzeigenwert = anzeige[findex]; /* Ein wenig auf dieser Frequenz warten */ delayzaehler = 0; while (delayzaehler < SCANTEMPO); /* Danach nachsehen, ob der Anwender eine Taste gedrueckt hat */ if (taste_gedrueckt == 1) { /* Wenn Taste gedrueckt: Scan stoppen, Tastendruck zuruecknehmen */ scan = 0; taste_gedrueckt = 0; } } else { /* Wenn nicht gescannt wird, werden nur noch Tasten abgeprueft */ if (taste_gedrueckt == 1) { /* Es wurde eine Taste gedrueckt */ if ((tastenwert & TASTE1) == 0) { /* TASTE1 stellt niedrigere Frequenz ein, wenn noch nicht die niedrigste erreicht */ scan = 0; if (findex > 0) { findex--; } } if ((tastenwert & TASTE2) == 0) { /* TASTE2 erhoeht die Frequenz */ scan = 0; if (findex < STUETZSTELLEN - 1) { findex++; } } if ((tastenwert & (TASTE1 | TASTE2)) == 0) { /* Wenn beide Tasten gemeinsam gedrueckt werden, wird der Scan wieder gestartet */ scan = 1; } /* In jedem Falle Tastendruck zuruecknehmen */ taste_gedrueckt = 0; } /* Neue Frequenz im Drehspulmesswerk anzeigen */ anzeigenwert = anzeige[findex]; } } }