PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Drehzahlanzeige



RevolT3c
27.12.2010, 15:50
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:




///////////////////////////////////////////////////////////////////

// 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

Hubert.G
27.12.2010, 20:37
Wie ist denn die Gabellichtschranke angeschalten, die 100Ohm vom Pulse-Input nach GND kommen mir etwas komisch vor.

RevolT3c
27.12.2010, 20:59
Richtig erkannt :) Das hab ich noch nicht geändert, da sind jetzt 10kOhm dran.