-         

Ergebnis 1 bis 3 von 3

Thema: Problem mit Drehzahlanzeige

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    07.04.2009
    Beiträge
    9

    Problem mit Drehzahlanzeige

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    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:

    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;
       		
    		}	
    	
    
    	
    
    }
    }
    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.

    Leider klappt das so nicht :P Die Anzeige zeigt immer 0000 an und flackert höchstens mal. Weiss jemand Rat?

    Gruss RevolT3c

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.183
    Wie ist denn die Gabellichtschranke angeschalten, die 100Ohm vom Pulse-Input nach GND kommen mir etwas komisch vor.
    Grüsse Hubert
    ____________

    Meine Projekte findet ihr auf schorsch.at

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    07.04.2009
    Beiträge
    9
    Richtig erkannt Das hab ich noch nicht geändert, da sind jetzt 10kOhm dran.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •