Hi @ all,
ich hab mir eine kleine Schaltung gebastelt die mir über eine Gabellichtschranke und einer 4-stelligen 7-Segmentanzeige die Drehzahl meiner Bohrmaschine anzeigen soll.
Leider bin ich noch Anfänger in C und was das programmieren mit µC angeht also habt Gnade [-o<
Das Ganze soll über Multiplexing funktionieren.
Hier ein Bild zum Schaltplan:
http://www.abload.de/img/planclhl.png
Und hier der Code:
Eigentlich soll nach 2 steigenden Flanken der Wert ausgelesen werden und die Drehzahl ermittelt werden. Gemessen wird 28x und dann ein Mittelwert gebildet. Der Mittelwert soll dann auf die 7-Segmentanzeige ausgegeben werden.Code://///////////////////////////////////////////////////////////////// // Drehzahlmessung: // Das zu messende Signal wird an den Input Capture Pin des Prozessors // angelegt. Zur Freqenzbestimmung wird mittels Timer1 die Perioden- // dauer des Signals von einer steigenden Flanke bis zur naechsten // steigenden Flanke ermittelt. Daraus laesst sich dann die Frequenz // errechnen. Zwischen den Messwerten ist jeweils ein Takt der nicht gemessen wird. // // // // ///////////////////////////////////////////////////////////////////// // Prozessor Taktfrequenz einstellen sofern es nicht eine Vorgabe // beim Aufruf des C Compilers gab. #ifndef F_CPU #define F_CPU 8000000 #endif #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <stdlib.h> #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif // Ports der entsprechenenden Ausgänge #define seg_port1 PORTC //a - f #define seg_port2 PORTD //g #define seg_masse_port PORTB //massepins // 7seg LED Pins #define sega PC0 #define segb PC1 #define segc PC2 #define segd PC3 #define sege PC4 #define segf PC5 #define segg PD0 //Masse Pins #define seg1 PB4 // 1er #define seg2 PB3 // 10er #define seg3 PB2 // 100er #define seg4 PB1 // 1000er volatile unsigned char NrOverflows = 0; // Anzahl der Timer Overflows die waehrend der Messung passiert sind volatile unsigned int StartTime = 0; // ICR-Wert bei 1.High-Flanke speichern volatile unsigned int EndTime = 0; // ICR-Wert bei 2.High-Flanke speichern volatile unsigned char Ausgabe = FALSE; // Job Flag volatile unsigned char Messungfertig; // Job Flag volatile unsigned char ErsteFlanke = TRUE; volatile uint32_t Erg = 0; volatile int drehzahl; volatile int ziffer = 0; volatile int zahl = 0; volatile int stelle= 0; volatile int Mittelwert = 0; volatile int schleife =0; void ausgabe(int ziffer, int stelle); int main(void); ISR ( TIMER1_CAPT_vect ) { if (Ausgabe == TRUE) // Das Display wurde mit den Ergebnissen der vorhergehenden { return; } // Messung noch nicht upgedated. Die naechste Messung // verz?gern, bis die Start und EndTime Variablen wieder // gefahrlos beschrieben werden koennen if( ErsteFlanke == TRUE ) { StartTime = ICR1; // Startzeit= ICR 1 NrOverflows = 0; ErsteFlanke = FALSE; // Die naechste Flanke ist das Ende der Messung } // das ist die zweite Flanke im Messzyklus. Die Messung wird gestoppt else { EndTime = ICR1; // Stopzeit für die Messung= ICR1 Ausgabe = TRUE; // Eine vollst?ndige Messung. Sie kann ausgewertet werden ErsteFlanke = TRUE; // Bei der naechsten Flanke beginnt der naechste Messzyklus } } ISR( TIMER1_OVF_vect ) { NrOverflows++; return; } void init_interrupt(void) // Interrups klar machen { TCCR1B = (1<<ICES1) | (1<<CS10); // Input Capture steigende Flanke an ICT-Pin(PB0), kein PreScale TIMSK = (1<<TICIE1) | (1<<TOIE1); // Interrupts akivieren, Capture + Overflow sei(); //Interrups freigeben } int Messwerte_auslesen() //Unterprogramm zur Messwertausgabe { schleife++; // liegt eine vollst?ndige Messung vor? Erg = (NrOverflows * 65536) + (EndTime - StartTime); // ... mit der bekannten Taktfrequenz ergibt sich dann die Signalfrequenz Erg = F_CPU / Erg; // f = 1 / t //aus der Frequenz berechnet sich die Drehzahl zahl = Erg * 60; // Drehzahl berechnen aus der Frequenz f*60sec= U/min Mittelwert+=zahl; //Mittelwert aus 28 Messungen bilden if (schleife<29) { return; } else { drehzahl=Mittelwert/28; Mittelwert=0; schleife=0; } } void Messwerte_ausgeben(void) { static int zahl3; zahl3 = drehzahl; //Drezahlwert wird übergeben ziffer = zahl3/1000; // 1000er Stelle für Segmentanzeige zahl3 = zahl3 - ziffer*1000; ausgabe (ziffer,4); _delay_ms(1); ziffer = zahl3/100; // 100er Stelle für Segmentanzeige zahl3= zahl3 - ziffer*100; ausgabe (ziffer,3); _delay_ms(1); ziffer = zahl3/10; // 10er Stelle für Segmentanzeige zahl3 = zahl3 - ziffer*10; ausgabe (ziffer,2); _delay_ms(1); ziffer = zahl3; // 1er Stelle für Segmentanzeige ausgabe (ziffer,1); _delay_ms(1); } void ausgabe(int iziffer, int istelle) { seg_port1=0; seg_port2=0; seg_masse_port=0; //Steuerleitungen ausgeben switch(iziffer) { case 0: seg_port1 |= ((1<<sega)|(1<<segb)|(1<<segc)|(1<<segd)|(1<<sege)|(1<<segf)); break; case 1: seg_port1 |= ((1<<segb)|(1<<segc)); break; case 2: seg_port1 |= ((1<<sega)|(1<<segb)|(1<<segd)|(1<<sege)); seg_port2 |= (1<<segg); break; case 3: seg_port1 |= ((1<<sega)|(1<<segb)|(1<<segc)|(1<<segd)); seg_port2 |= (1<<segg); break; case 4: seg_port1 |= ((1<<segb)|(1<<segc)|(1<<segf)); seg_port2 |= (1<<segg); break; case 5: seg_port1 |= ((1<<sega)|(1<<segc)|(1<<segd)|(1<<segf)); seg_port2 |= (1<<segg); break; case 6: seg_port1 |= ((1<<sega)|(1<<segc)|(1<<segd)|(1<<sege)|(1<<segf)); seg_port2 |= (1<<segg); break; case 7: seg_port1 |= ((1<<sega)|(1<<segb)|(1<<segc)); break; case 8: seg_port1 |= ((1<<sega)|(1<<segb)|(1<<segc)|(1<<segd)|(1<<sege)|(1<<segf)); seg_port2 |= (1<<segg); break; case 9: seg_port1 |= ((1<<sega)|(1<<segb)|(1<<segc)|(1<<segd)|(1<<segf)); seg_port2 |= (1<<segg); break; default: seg_port1 = 0; seg_port2 = 0; break; } //Masse schalten switch(istelle) { case 1: seg_masse_port |= (1<<seg1); break; case 2: seg_masse_port |= (1<<seg2); break; case 3: seg_masse_port |= (1<<seg3); break; case 4: seg_masse_port |= (1<<seg4); break; default : break; } return; } int main(void) { DDRD |= 0xFF; DDRC |= 0xFF; DDRB &= ~(1 << DDB0); DDRB |= (1 << DDB1) | (1 << DDB2) | (1 << DDB3) | (1 << DDB4); PORTD = 0; PORTC = 0; PORTB &= ~(1<<PB0); //Interrups klar machen init_interrupt(); while(1) //diese Schleife soll das Programm immer wiederholen. { Messwerte_ausgeben(); if (Ausgabe==TRUE) { Messwerte_auslesen(); Ausgabe=FALSE; } } }
Leider klappt das so nicht :P Die Anzeige zeigt immer 0000 an und flackert höchstens mal. Weiss jemand Rat?
Gruss RevolT3c







Zitieren

Lesezeichen