//Periodendauermessung mit Mexle 8252 //Autor: Christian, Eberle //Datum: 03.05.06 //Version: 1.0 /* An Port 3.5 wird das zu messende, Signal angelegt. Die ermittelte u/min wird kontinuierlich auf den 6 7-Segmentanzeigen des MEXLE Boards ausgegben. Es stehen 2 Modie zur Ermittlung der Periondedauer zur Verfügung. MODE1: Torzeit 1s ->Taster 1 ->START MODE2: Abnullen ->Taster 2 ->STOP Nach Reset bzw. bei der Inbetriebnahme ist der MODE1 (1s Torzeit) voreingestellt. Die ermittelte u/min werden direkt nach der Ermittlung ausgegeben. */ /* Configuration File Anzeige for MEXLE8252 ============================================================================*/ #include //Port Definition für MEXLE #define PORT_ANZEIGE P0 //7282 hängt an Port 0 #define PORT_BUTTON P0 //Tasten und Schalter an Port 0 //Control Definitions for 7228 #define ANZ_DATA_COME 0x80 //1: Data Coming Mode; 0: NO data #define ANZ_HEX 0x40 //1: Hex-Codierung; 0: Code B #define ANZ_NO_DECODE 0x20 //1: keine Decodierung; 0: mit decodierung #define ANZ_NORMAL_OP 0x10 //1: Normale Operation; 0: Shutdown #define ANZ_DIGITS 8 #define ANZ_BARGRAPH 0x06 //Digitadresse Bargraph #define ANZ_NO_DEC_PNT 0x80 //Ausschalten des Dezimalpunktes #define ANZ_MINUS 0x0A //Anzeige Minus mit Code B #define ANZ_STELLEN 6 //Anzahl der Stellen auf der Anzeige #define INPUT 0xFF //Port auf Input schalten //Steuerbits für 7228 sbit ButtonEn = P1^1; //Enable für Tasten sbit AnzMode = P1^2; //Modus für 7228 sbit AnzWR = P1^3; //WR-Signal für 7228 // Konstanten _____________________________________________________________ #define ON 1 //EIN-Bit #define OFF 0 //OFF-BIT #define VORTEILER_WERT 50 //Faktor Vorteiler 50 #define HUNDERTSTEL_WERT 10 //Faktor Hundertstel 10 #define ZEHNTEL_WERT 10 //Faktor Zehntel #define ZEITKONSTANTE 250 //Periode Timer 0: 250 x 0,8µs 250 // Variable _______________________________________________________________ unsigned char data vorteiler = VORTEILER_WERT; //Zahlenvariable Vorteiler unsigned char data hundertstel = HUNDERTSTEL_WERT; //Zahlenvariable Hundertstel unsigned char data zehntel = ZEHNTEL_WERT; //Zahlenvariable Zehner unsigned long wert = 0x00000000; //Ausgabewert an Anzeige unsigned int overflow = 0x0000; //16-Bit Speicherbereich für Überläufe des Timers unsigned int zwsp = 0x0000; //Counterwert Zwischenspeicher_neu unsigned char modus = 0x01; //Variable für Modusauswahl unsigned char bdata buttons; //Zwischenspeicher für Tastenwerte bit bdata takt10ms; //Bit-Botschaft alle 10 ms bit bdata takt100ms; //Bit-Botschaft alle 100 ms bit bdata takt1s; //Bit-Botschaft alle 1 s // Zwischenspeicher Tastenwerte sbit sw1 = buttons^0; //Bitspeicher für Taste 1 sbit sw2 = buttons^1; //Bitspeicher für Taste 2 bit sw1ALT = 1 ; //Alter Wert von Taste 1 bit sw2ALT = 1 ; //Alter Wert von Taste 2 bit Messbereit = 0; //Bit-Botschaft für Start/Ende der Torzeit /*Funktionsprototypen ============================================================================ */ void DisplayUnsignedLong(unsigned long content); void Timer0InitMode2(unsigned char timeconst); void TimerInt0 (void); void Modeabfrage(void); void InitT1Counter(void); unsigned char CheckButton(void); void Umdrehung(void); void Rueckstellen(void); void Modus_bearbeiten(void); /*Initialisierung und Hauptprogramm ============================================================================ */ void main() { //Initialisierung Timer 0 Timer0InitMode2(ZEITKONSTANTE); //Initialisierung Timer 0 mit Auto-Reload ET0 = ON; //Timer 0 Interrupt aktivieren EA = ON; //generell Interrupt aktivieren EX0 = ON; IT0 = ON; //Initialisierung Timer 1 InitT1Counter(); /*Hauptprogrammschleife ============================================================================ */ while(1) { Modus_bearbeiten(); if (takt10ms==1) { Modeabfrage(); //Aufruf Modeabfrage takt10ms = 0; //Botschaft takt10ms zurücksetzen } if(takt100ms==1) { DisplayUnsignedLong(wert); //Aufrauf Anzeige-Funktion takt100ms = 0; } } } /*Funktion zur Abfrage der Tasten und Schalter des MEXLE-Boards ============================================================================ */ unsigned char CheckButton(void) // Die Stellungen der 4 Tasten und des DIL-Schalters werden in eine Variable // eingelesen. Dazu muss der verwendete Port erst auf Eingang geschaltet werden. // // Ausgangsvariable: keyPressed (Rückgabewert der Funktion) { unsigned char keyPressed ; // interne Variable für Schalterabfrage PORT_BUTTON = INPUT; // Port des 8252 µC auf Eingang schalten ButtonEn = 0 ; // Tristate-Buffer HCT541 freigeben keyPressed = PORT_BUTTON ; // Schalterstellungen abfragen ButtonEn = 1 ; // Tristate-Buffer HCT541 sperren return keyPressed ; // Rückgabe der aktuellen Schalterwerte } //Initialisierung Timer 0 in Mode 2(8 Bit-Reload-Funktion) void Timer0InitMode2(unsigned char timeconst) { TMOD = (TMOD&T1_MASK_)+T0_M1_; // Modus 2, Timerfunktion, kein Gate TL0 = -timeconst; // Zeitkonstante in Timerregister laden TH0 = -timeconst; // Zeitkonstante in Timerregister laden TR0 = ON; // Timer 0 starten } //Initialisierung Timer 1 als 16-Bit Counter void InitT1Counter() { TMOD = (TMOD&T0_MASK_)+T1_M0_+T1_CT_; TL1 = 0x00; //Zählerstand löschen (LowByte) TH1 = 0x00; //Zählerstand löschen (HighByte) TF1 = 0; //Timer 1 Starten TR1 = 1; //Timer 1 Interrupt starten ET1 = 1; //Interrupt Timer 1 } /*Interrupt Routine ============================================================================ In der Interrupt Routine sind die Softwareteiler realisiert, die die Botschaften (10ms, 100ms, 1s). Die Interrupts werden von Timer 0 ausgelöst (Interrupt Nr. 1). Veränderte Variable: vorteiler hunderstel zentel Ausgangsvariable: takt10ms takt100ms takt1s */ void TimerInt0(void) interrupt TF0_VECTOR // T0_INT { --vorteiler; //Vorteiler dekrementieren if (vorteiler==0) //wenn 0 erreicht: 10ms abgelaufen { takt10ms = 1; //Botschaft 10ms senden vorteiler = VORTEILER_WERT; //Vorteiler auf Startwert setzen --hundertstel; //Hunderstelzähler dekrementieren if (hundertstel==0) // wenn 0 erreicht: 100ms abgelaufen { takt100ms = 1; //Botschaft 100ms senden hundertstel = HUNDERTSTEL_WERT; //hundertstel auf Startwert setzen --zehntel; //Zehntel dekrementieren if (zehntel==0) // wenn 0 erreicht: 1s abgelaufen { zehntel = ZEHNTEL_WERT; //zehntel auf Startwert setzen takt1s = 1; //Botschaft 10s senden } } } } // Interrupt-Funktion des Timer 1_____________________________________________ //Diese Interruptfunktion wird ausgeführt, //sobald der 16-Bit Counter einen überlauf hat (nach 65536 negativen Signalflanken) void timer1Interrupt() interrupt TF1_VECTOR using 1 { overflow++; //Überlaufspeicher incrementieren } /*Modusabfrage und Anzeigewert bilden ============================================================================ Modusabfrage Ein Modus ist so lange gesetzt bis anderer Modus gewählt wird (Selbsthaltung) Initial ist Modus 1 angewählt Die Funktion wird alle 10ms abgefragt, was eine Tastenentprellung darstellt. */ void Modeabfrage(void) { buttons = CheckButton(); //aktuelle Tastenwerte einlesen if (sw1==0 && sw1ALT==1) modus = 1; //Modus 1 anwählen if (sw2==0 && sw2ALT==1) modus = 2; //Modus 2 anwählen sw1ALT = sw1; //Entprellungsspeicher (Speichern des alten Wertes) sw2ALT = sw2; } /*Modus bearbeiten ============================================================================ */ void Modus_bearbeiten(void) { switch (modus) { case 1: if(takt1s==1 && Messbereit == 1) //der Torzeit 1s { takt1s = 0; //Botschaft takt1s abnullen Umdrehung(); //Unterprogramm Anzeige erstellen aufrufen Rueckstellen(); //Unterprogramm Counter zurückstellen aufrufen Messbereit=0; } if(takt1s==1 && Messbereit == 0) { Rueckstellen(); Messbereit = 1; takt1s=0; } break; case 2: if (sw2==1) { Rueckstellen(); //Reset der Zählstände TR1=0; //Counter Stoppen wert=wert; } break; } } /*Zähler zurückstellen ============================================================================ */ void Rueckstellen (void) { overflow = 0x0000; //Überlaufzähler zurücksetzen TH1 = 0x00; //Timer1 high Byte zurücksetzen TL1 = 0x00; //Timer1 low Byte zurücksetzen } /*Berechnung ============================================================================ */ void Umdrehung(void) { TR1=0; //Counter Stoppen zwsp=(TH1<<8)+TL1; //Zählerwert in einen Zwischenspeicher laden wert = overflow; //Zählerüberläufe des Timer1 umkopieren wert = (wert<<16)+zwsp; //Anzeigewert verschieben und umkopieren wert=wert*60; // ==>umdrehung/min TR1=1; //Counter wieder starten } /*Funktion zur Ausgabe einer 32-BIT-Zahl der vorzeichenlosen u/min ============================================================================ */ void DisplayUnsignedLong(unsigned long content) { unsigned char digit; //interner Stellenzähler for (digit=ANZ_STELLEN; digit>0; --digit) { AnzWR = 1; //Initialisirung AnzMode = 1; //Modus im 7228 einspeichern PORT_ANZEIGE = ANZ_NORMAL_OP + digit -1; //Schreibimpuls AnzWR = 0; //WR-Signal auf 0 ziehen AnzWR = 1; //wieder auf 1 AnzMode = 0; //auf Daten-Modus schalten PORT_ANZEIGE = content%10+ANZ_NO_DEC_PNT; //Inhalt der stelle //Schreibimpuls AnzWR = 0; //WR-Signal auf 0 ziehen AnzWR = 1; //wieder auf 1 content=content/10; //nächste Stelle bereitstellen } }