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