PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Drehzahlmesser (bis ca. 20000 Upm) - Reicht ein mega8(8) ?



HF SHOOTER
23.10.2007, 18:37
Hallo

Ich planen den Bau eines Drehzahlmesser für ein Kart. Dies baue ich für einen Freund. Er schätzt die Motorumdrehung auf 15k - 20k die bei Vollgas azuftreten.
Ich möchte somit eine 5 stelliges Display aus 7-Segment LED-Anzeigen verwenden um den gesamten Bereich draufzubekommen.
Bisher habe ich noch keinerlei Erfahrung mit zeitkritischen Schaltungen wie es hier der Fall ist. Programmiert wird dann in C.

Ein paar Probleme die mir spontan eingefallen sind:
- Reicht die Leistung des ATmega8 aus um die Drehzahl damit zu messen und gleichzeitig 5 7-Segmentdisplays im Multiplex verfahren anzusteuern und das flimmerfrei?

- Welche besondere Vorkehrungen bzw Schutzmaßnahemn sind notwendig wenn ich den Microcontroler am 12V Boardnetz betreibe?
- Reicht da ein einfach 7805 Festspannungsregler und ein zwei Schutzdioden oder benötigt es da mehr?

- Sollte ich besser den ATmega88 nehmen? Einen ganz anderen?

- Wäre es ratsam ein, zwei oder mehr Toggle-Flipflop vorzuschalten um nur die halbe bzw viertel Frequenz auswerten zu müssen (große Recheneinsparung bzw Timerauflösung nicht ausreichend!). Pro Zündung wird ein Impuls ausgelöst, d.h. bei 15k Upm 30k mal Interruptaufruf/min (2-Takter) - viel zu viel für den ATmega oder?

- Wie muss ich den Eingang filter um den AVR / Transistor nicht zu beschädigen?
12V liegen dauernd an, wenn Zündung kommt dann ist 0V. Signal wandel ich vorher mittles Transistors in 5V bzw 0V um, aber:
In der Zündspule findet ja eine Gegeninduktion statt, sobald der Unterbecherkontakt öffnet d.h. mehre tausend Volt werden auf die Basis des Transistors geleitet. Wie sicher ich das ab? Freilaufdiode oder einfach großer Widerstand?
Hier hab ich was schönes gefunden http://www.fda-technology.de/download/Schaltplan_1_5.gif
(links oben) das is getestet und funktioneirt also Übernehm ich diesen Teil einfach ;-)

Andere Vorschläge werden gerne angenommen, außer einfach was fertiges zu kaufen!

Hab ich mich mit meinem 1. Projet zu weit aus dem Fenster gelehnt oder ist sowas (für mich) machbar. Ich mache schon seit einigen Jahren mit PICs rum und löten kann ich auch. Außerdem bin ich im. 3. Lehrjahr in einer Ausbildung zum Elektroniker für Geräte und Systeme. Elektronik selbst hab ich schon seit dem ich klein bin als Hobby angefangen.

Vielen Dank für die Mühe sichdas ganze durchzulesen und für die hoffe nun bald folgenden Antworten :-)
Ich fang solange mal an einen Schaltplan zu entwerfen.

mfg
Benny

wkrug
23.10.2007, 19:10
Ich planen den Bau eines Drehzahlmesser für ein Kart. Dies baue ich für einen Freund. Er schätzt die Motorumdrehung auf 15k - 20k die bei Vollgas azuftreten.
Wenn man die Drehzahlerfassungsroutine in Assember proggt hab ich schon Drehzahlen bis 800.000 U/min ohne Probleme messen können, mit einem 8MHz Quarz - Also NO PROBLEM


Reicht die Leistung des ATmega8 aus um die Drehzahl damit zu messen und gleichzeitig 5 7-Segmentdisplays im Multiplex verfahren anzusteuern und das flimmerfrei?
Auch das sollte machbar sein.


Welche besondere Vorkehrungen bzw Schutzmaßnahemn sind notwendig wenn ich den Microcontroler am 12V Boardnetz betreibe?
- Reicht da ein einfach 7805 Festspannungsregler und ein zwei Schutzdioden oder benötigt es da mehr?
Da es im Auto immer wieder zu Spannungsspitzen kommen kann, würd ich vieleicht noch einen Vorwiderstand mit Varistor oder Z-Diode und eine Drossel vorschalten. Erst danach sollte ein 7805 kommen.
Aber da wissen sicher die Autoelektroniker hier mehr als ich.


Wäre es ratsam ein, zwei oder mehr Toggle-Flipflop vorzuschalten um nur die halbe bzw viertel Frequenz auswerten zu müssen (große Recheneinsparung bzw Timerauflösung nicht ausreichend!). Pro Zündung wird ein Impuls ausgelöst, d.h. bei 15k Upm 30k mal Interruptaufruf/min (2-Takter) - viel zu viel für den ATmega oder?
Nö, kannst Du Dir wirklich sparen und verschlechtert nur die Auflösung in niedrigen Drehzahlbereichen.

Zu deiner Eingansschaltung würde ich evtl gleich einen Optpkoppler nehmen.
Da hast Du dann gleich eine galvanische Trennung und eine Pegelwandlung in einem. Die LED des Optokopplers musst Du natürlich vor Überspannungen und hohen negativen Spannungen schützen.

Der ATMEGA8 sollte deinen Aufgaben gewachsen sein, wenn Du meinst kannst Du aber auch gerne den Pinkompatiblen ATMEGA88 einsetzen.

Zur Ansteuerung deiner LED's müsstest Du aber noch einen Treiberbaustein einsetzen, da ein ATMEGA 8 nur maximal 20mA gegen Masse schalten kann. Gegen +5V sind es meines Wissens nur 10mA, also zu wenig für deine LED's im Multiplexverfahren.

Da LED's dann doch einiges an Strom schlucken, wie wärs mit einem DOT Matix Display ? ein 1x16 oder 2x 16 kostet bei Pollin nicht die Welt ?

HF SHOOTER
23.10.2007, 19:56
Hallo

Vielen Dank für die promte ausführliche Antwort.

Sehr gut das die hier vorkommende Umdrehungszahl problemlos verarbeitet werden kann.

Die idee mit dem Optokopller ist sehr gut, ein CNY17 sollte das auch problemlos bewältigen können.
Wie schütz ich denn diese LED vor diesen negativen Spannungsspitzen die ja sehr häufig auftreten? Einfach durch eine Shotky-Diode kurzschließen?

das ich einen Treiber benötige ist mir eigentlisch schon klar - aber trotzdem danke für den aufmerksamen Hinweis. Ich denke ich nehm den Standart-Treiber ULN2803.

Ich möchte gerne 7-Segment Displays verwenden damit man es gut ablesen kann. Außerdem finde ich in diesem Fall passt es einfach besser und ich muss endlich mal ein Projekt mit Multiplexin machen, das wollt ich sowieso schon immer mal ;-)

Rofo88
23.10.2007, 20:01
Das ermitteln der Drehzahl sollte nicht das problem sein wenn mann die Drehzahlen auf nen Counter-Eingang legt und nach 100ms auswertet. Damit sollte das auch in Hochsprachen möglich sein und der µC hat genug Zeit zum Multiplexen. Das könnte man sich aber auch noch ersparen wenn man für die Anzeige Schieberegister einsetzt.

Das Projekt sollte also machbar sein mit nem Mega8

HF SHOOTER
23.10.2007, 20:16
Also wenn die Leistung ausreicht dann würde ich gerne dieses Projekt mit Multilexing machen weil ich wie oben bereits geschrieben das gerne schon immer mal machen möchte und auch mein Wissenstand durch praktische Erfahrung dann erweitern kann - theoretisch kann ichs, zumindest mehr oder weniger ;-).

Mit Counter-Eingang meinst Du doch für jede Flanke eine Variable um eins hochzuzählen.
Dann kann cih ja beim Überlauf eines Timers (z.B. nach 100ms) den Zählstand auswerten und mit ner Formel die Umdrehunszahl berechnen.

mfg
Benny

wkrug
24.10.2007, 17:54
Mit Counter-Eingang meinst Du doch für jede Flanke eine Variable um eins hochzuzählen.
Dann kann cih ja beim Überlauf eines Timers (z.B. nach 100ms) den Zählstand auswerten und mit ner Formel die Umdrehunszahl berechnen.
Nun ich denke das Rofo88 meint einen T Eingang zu benutzen.
Der ist eigentlich dafür gedacht um die Timer mit externen Takten zu versorgen. Allerdings könntest Du diesen Eingang in deiner Applikation auch als Taktzähler missbrauchen.
Ein zweiter Timer gibt dann die Torzeit vor und liest den Zähler aus um ihn anschließend wieder auf 0 zu setzen. Das verbraucht sehr wenig Rechenzeit, da fast die komplette Drehzahlerfassung mit Hardware realisiert ist.

Mit einer Torzeit von 100ms und Impulszählung würde ich den Drehzahlmesser nicht realisieren. Da bekommst Du eine Auflösung von 600U/min was gerade bei niedrigen Drehzahlen mehr als dürftig ist.

Bei niedrigen Drehzahlen ist meiner Meinung nach die Impulsdauermethode die beste Variante. Das bedeutet ein Timer läuft frei mit dem heruntergeteilten Quarztakt und wird bei jeder Umdrehung (= Impuls vom Geber) ausgelesen. Die Der Zählerstand dieses Zählers ist das Maß für die Drehzahl. Den Zählerstand durch eine Formel gejagt und man kriegt die Drehzahl raus. Dadurch bekommt man gerade bei niedrigen Drehzahlen eine sehr gute Auflösung. Je höher allerdings die Drehzahl wird umso höher wird der Fehler und umso größer ist die Prozessorbelastung.
Mit einem 16MHz getakteten ATMEGA8 sollten aber Drehzahlen bis 30.000 U/min mit einem maximalen Fehler von 60 U/min bei dieser Methode kein Problem sein. Schau mal im Datenblatt unter ICP nach. Dieser Eingang würde sich vorzüglich dafür eignen.
Noch eine kleine Krux bei dieser Variante ist, das die letzte gemessene Drehzahl bei Stillstand des Motors "stehen" bleibt. Aber das kann man ja durch ein Timeout detektieren und die Drehzahl dann auf 0 setzten.

Ich bastel schon ein wenig länger an Modellbau Drehzahlmessern rum und hab deshalb schon so einiges ausprobiert.
In meiner letzten Drehzahlmesser Variante benutze ich beide Methoden zur Drehzahlerfassung und schalte ab einer bestimmten Drehzahl zwischen den beiden Methoden um. Allerdings nehm ich dabei eine Torzeit von 1 sek, was für dich dann wohl zu langsam ist - Auch deshalb würd ich die Impulsdauermethode vorziehen, da dabei bei jeder Umdrehung ein neues Ergebnis zustande kommt.

Für die Ansteuerung deines Displays würd ich mir eine Look Up Table machen in der dann je nach anzuzeigender Zahl die entsprechenden Segmente aktiviert werden.

Die Umschaltung zwischen den einzelnen Stellen des Displays würd ich in einem Timer Overflow Interrupt ansiedeln.
Dein Hauptprogramm berechnet dabei dann die einzelnen Digits und speichert Sie in einer Tabelle ab. Der Timer Interrupt gibt dann einfach eine Stelle nach der anderen aus.
Ein wirklich kleines Problemchen dürfte noch das Unterdrücken der führenden Nullen sein, aber auch das ist mit ein klein wenig Hirnschmalz sicher ein lösbares Problem.

Evtl. würd ich mir noch einen Speicher für die maximal vorgekommene Drehzahl in den Drehzalmesser mit einbauen. Du willst ja schließlich wissen, wann es deinen Motor zerlegt hat ;-)

Na, dann kann ich Dir wohl nur noch viel Glück und Spaß bei der Realisierung deines Projektes wünschen.

HF SHOOTER
24.10.2007, 20:35
Uiuiui...

Mit so ner großen Resonaz in der Zeit habe ich wirklich nicht gerechnet. Großes Lob! Mir is klar das es sowohl mit einem ATmega8 und mit einem ATmega88 geht allerdings würd ich gerne den Rat eines Profis hören welchen ich lieber benutzen sollte.
Ode rmals anders gefragt: Wird der "Nachfolger" bei den neuen Entwicklungen bevorzugt eingesetzt oder bringt er keine Vorteile. Da er Pincompatibel ist ist ein Programm normalerweise auch relativ einfach für den anderen Controler umzuschreiben, oder?


Ich habe mich nunmal ein wenig genauer mit den Timern befasst, mit denen kann man ja doch ganz schön viele unterschiedliche Dinge machen, wie das beim PIC ist kann ich nicht beurteilen da ich mich da kaum mit anderen Anwendungen des Timers als den klassischen Overflow-Interrupt auseinander setzen musste. Also noch ein paar nähere Details bitte zu folgendes:

Mit einem T-Eingang, z.B. T0 (Pin 6) lege ich den Takt des Timers fest, dieser darf also auch nicht höher sein als die Taktfrequenz des Prozessors, richtig?
Aufwändiger kann ich es machen (hat aber im Endeffekt den selben Effekt)
indem ich eine Flanke an einem Interuppt-Eingang (z.B. Pin 4) erkenne und dann eine Variable um 1 inkrementier, oder?

Im Hintergrund lass ich nen weiteren Timer laufen damit ich dann bei einem festen Wert, wie z.B. alle 25 ms nachschaue wie viel Impulse aufgetreten sind und daraus dann die Drehzahl berechne.
Ist es möglich beim ersten Timer zusätzlich noch einen Interrupt auszuführen, z.B. nach 100 Impulsen.

Idee:
Sobald einer der beiden Timer überläuft bzw. den Soll-Wert erreicht hat (100 Impulse oder 25ms) setz ich beide auf 0.
Grund ist folgender:
- langsame Drehzahl (Timer 2 schlägt zuerst zu -> Impulsdauermethode)
- hohe Drehzahl (Timer 1 schlägt zuerst zu -> Impulsanzahlmethode?)

Setz ich nun beide Timer auf 0 sobald nur einer ausgelöst wird kommen sie sich nicht mehr in die Quere, denn z.B. folgender fall könnte das Ergebnis total verfälschen:
Timer 1 hat einen Zählstand von 80, Timer 2 erreicht 25ms -> korrekte Drehzahlbestimmung.
Timer 1 erreicht 100, Timer 2 z.B. erst bei 2ms -> oha 100 Impulse in nur 2 ms -> gigantische Drehzahl.

So wie Du das beschreibst mit der Ansteuerung der Segmentanzeige habe ich es auch schon vorgehabt.
Mittels Tabelle schauen welches Segment angesteuert werden muss und der restliche Schnickschnack wie führende Null wegbekommen ist denk ich kein Problem, aber da kann ich mich erst genaueres sagen wenn ich die Hardware habe und dann acuh anfange mit dem Multiplex Verfahren.
Genausowenig dürfte es ein Kinderspiel sein die Upm max abzuspeichern (EEPROM).
Schön wäre z.B. noch ein Blinken der Anzeige bei neuem Rekord ode rbei zu hoher Drehzahl.
Man kann ja wenn es dann funktioniert das ganze noch durch ein zwei Tastern erweitern.
Interesant wär auch noch ne Anzeige der Betriebsstunden bzw. -minuten des Motors auf Knopfdruck oder beim einschalten. Aber das alles nachdem die Grundfunktion funktioniert.


Sehe ich das richtig das ich 3 Timer benötige?
2 für Impulsdauer bzw Impulsanzahl
1 für Multiplex-Ausgabe


Wichtig wär mir noch einen Tipp zur Schutzbeschaltung für die auftretende Gegeninduktion beim Öffnen des Unterbrecher Kontakts. Normalerweiße müsste es doch wie bei einem Relai eine Freilaufdiode tun die die Sperrspannung an der LED auf 0,7V bzw 0,3V begrenzt.
Nur ist diese Didoe evtl. für diese Frequenzen zu langsam?


mfg
Benny

wkrug
25.10.2007, 19:58
Mit einem T-Eingang, z.B. T0 (Pin 6) lege ich den Takt des Timers fest, dieser darf also auch nicht höher sein als die Taktfrequenz des Prozessors, richtig?
Ich denk mal das die Frequenz nicht höher sein darf als 16MHz ansonsten dürfte es egal sein.
Du kannst den Timer über den T0 Eingang ansteuern, den internen Prozessortakt verwenden und ich glaub sogar den Watchdog Timer als Taktquelle verwenden.
Egal welchen dieser Eingänge du nimmst kannst Du mit dem Prescaler diesen Takt für den Timer nochmal runterteilen.
Die Timer des ATMEGA8 sind wirklich sehr vielseitig.


Im Hintergrund lass ich nen weiteren Timer laufen damit ich dann bei einem festen Wert, wie z.B. alle 25 ms nachschaue wie viel Impulse aufgetreten sind und daraus dann die Drehzahl berechne.
Ist es möglich beim ersten Timer zusätzlich noch einen Interrupt auszuführen, z.B. nach 100 Impulsen.
Das geht mit Timern die eine Comparematch Möglichkeit haben, aber was soll das bringen ?

Sobald einer der beiden Timer überläuft bzw. den Soll-Wert erreicht hat (100 Impulse oder 25ms) setz ich beide auf 0.
Ich würd nicht den INT0 für die Drehzahlerfassung verwenden, sondern den ICP des Timers 1. Bei dem wird nämlich der aktuelle Zählerstand gleich ins Input Capture Register des Zählers 1 abgespeichert.
Den Timer1 würde ich mit dem internen Prozessortakt 16MHz laufen lassen.
Er scafft dann 244 komplette durchläufe in einer Sekunde.
Wenn Du nun bei jedem Timer1 Overflow Interrupt ein Register mit hochzählst (Timer1 ist ein 16Bit Timer) bekommst Du einen Timer mit 24 Bit Auflösung. In diesem Timer1 Overflow Interrupt zählst Du dann noch ein zweites Register mit hoch. Dieses Register wird nach einem neuen Drehzahlimpuls wieder auf 0 gesetzt, ebenso wird das Flag "Drehzahl 0" eventuell gelöscht. Hat dieses Register einen Zählerstand höher als 244 (z.B.) wird ein Flag gesetzt das die Drehzahl 0 ist. Dieses Register fungiert also als Indikator für einen stehenden Motor.
Der Timer 1 und das zugehörige Überlauf Register wird niemals von Dir auf 0 gesetzt, sondern läuft frei durch.
Die Drehzahlermittlung wird durch abziehen des Timerwertes (24 Bit) des vorherigen ICP Interrupts ermittelt.
Die Berechnung der Drehzahl würd ich in der Hauptroutine erledigen, da dabei auch Divisionen oder ähnliches auftreten können.

Beispiel:
Ein ICP Interrupt bei 1234, der nächste bei 2345;
2345 - 1234 = 1111.
Die 1111 gehen in die Drehzahlberechnung ein die 2345 werden auf dem Speicherplatz der 1234 gespeichert - vorbereitung für die nächste Messung.

Somit erhältst Du bei jedem Impuls deines Drehzahlsensors eine neue Drehzahlausgabe.
Bei dieser Methode wird nur der Timer 1 verbraten, die beiden anderen Timer 0 und 2 bleiben für andere zwecke frei.

Im Timer1 Overflow Interrupt kannst Du dann auch gleich dein Multiplexing erledigen, wobei dann aber bei 5 Digits eine Refreshrate von unter 50Hz zustande kommt.

Also dann doch lieber einen eigenen Timer dafür verwenden z.B. Timer0 mit Prescaler 64 ( bin mir jetzt gerade nicht sicher ob das geht ) auf internen Takt. Dann komm ich auf eine Refresh Rate von 195Hz und da sollte nichts mehr flackern.

Da in deinen Interruptroutinen dann nur Speicherzugriffe, Additionen Subtraktionen und Inkremente auftreten ließe sich das wunderbar in Assembler proggen - wenn Du das willst.


Normalerweiße müsste es doch wie bei einem Relai eine Freilaufdiode tun die die Sperrspannung an der LED auf 0,7V bzw 0,3V begrenzt.
Hätte ich auch so gemacht.
Ich meine aber das Du für die LED im Optokoppler noch einen Vorwiderstand brauchst.
Wenn Du nun diesen Vorwiderstand aus 2 Widerständen aufbaust und am Mittelpunkt dieser 2 Widerstände nochmal eine Z-Diode einbaust sollten auch hohe induktionsspitzen deiner LED nichts anhaben können.
Wenn Du Angst hast die Freilaufdiode wäre zu lansam kannst Du eine Schottky Diode verwenden.

Übrigens hohe Frequenzen - bei einer Drehzahl von 20000 U/min liegt bei einem Impuls pro U/min eine Frequenz von 333Hz an. Das ist dann gerade mal ein wenig mehr als Gleichstrom ;-)

Zu ATMEGA88 kann ich leider nicht viel sagen, hab damit noch nichts damit gemacht.

Hanni
26.10.2007, 14:11
Ein ATmega 8 reicht leicht aus. Einem Anfänger würde ich diesen auch eher empfehlen als einen ATmega 88, da der 88'er ein paar kleine fiese Fallen hat.

Das Projekt selbst dürfte auch ein ziemlich guter Einstieg in die Mikrocontrollerprogrammierung sein, da eigentlich alles wichtige zumindest angerissen wird.

Grüße,
Hanni

Besserwessi
30.10.2007, 16:35
Der takt am T0 / T1 Einang darf aller höchstens so schnell wie der CPU takt sein, eventuell sogar nur halb so hoch, aber das ist hier eher uninteressant, denn hier liegt die Frequenz ja viel niedriger.

Eine normale Diode ist als Freilaufdiode immer schnell genug, denn beim "Einschalten" sind alle Dioden schnell (nur durch die Induktivität der Zuleitungen begrenzt). Die schnellen Dioden sind nur beim Ausschalten schneller. Wegen der eher niedrigen Frequenz kann man auch gleich einen Kondensator Prallel zu Sendeseite des Optokopplers schalten um kurze Spitzen zu vermeiden.

Da die Optokoppler immer etwas kappatzitive Kopplung haben, sollte auch an die Ausgangsseite ein Kondensator um kurze Spitzen und damit Fehltrigger zu vermeiden.

Es sollte sogar ein Mega48 reichen. In Assembler tuts auch ein Tiny2313, da werden aber die Portpins schon knapp. Ich habe z.B. einen Frequenzzähler mit einem Tiny2313 und gemultiplexten 7 Stellen LED Anzeige aufgebaut.

oberallgeier
30.10.2007, 17:17
... planen den Bau eines Drehzahlmesser für ein Kart. ... 15k - 20k die bei Vollgas azuftreten. ... 5 stelliges Display aus 7-Segment LED-Anzeigen verwenden um den gesamten Bereich draufzubekommen. ...
Und wer soll das beim Vollgasstress dann ablesen? Ich bin der Meinung, dass es ergonomisch viel sinnvoller wäre für jeden Tausender, oder jeden zweiten, eine LED anzuzünden. Vielleicht für die unteren 10000 fünf in Orange (nicht rot, das würde die folgenden stören), danach 4 Stück für alle 2000 (oder acht für die interessanten 8000 - die beiden letzten dann BESONDERS hell) in Grün - also bis 18000 - und darüber in Rot !? Aber die Aufteilung ist sicher wurscht, blos - bei Vollgas will doch keiner ein 5stelliges 7-Segment-Display lesen - es gibt ja Gründe für Vollgas - und die liegen bei Kartbahnen vermutlich nicht in einer endlos langen Geraden, oder?

Und denk daran, die letzten zwei oder drei Stellen werden so unruhig hin und her zappeln, dass man Schädelweh bekommen wird - ablesen wird man da doch nix können, denke ich.

Das Display wird nicht unnütz sein - das bau irgendwo neben dem Motor ein, für Einstellzwecke.

HF SHOOTER
30.10.2007, 17:47
Zu spät Bestellung ist heute angekommen.
Naja ich (besser gesagt mein Kollege) wirds dann merken aus Fehlern lernt man schließlich!

EDIT:
Danke für die bisherigen Beiträge ich habe nun die benötigten Bauteile soweit vollständig und kommende Tage nun die Versuchsschaltung aufbauen!

mfg
Benny

wkrug
30.10.2007, 21:25
Was mich persönlich schon immer gereitzt hätte wär eine Drehzahlanzeige mit LED's die in Form der Drehmomentkurve angeordet sind.
Wär doch auch mal ein Schönes Projekt.
Wenn Du deine Schaltung auf einen ATMEGA 16 aufmotzt wär vermutlich auch beides gleichzeitig möglich.

oberallgeier
30.10.2007, 21:31
Was mich persönlich schon immer gereitzt hätte wär eine Drehzahlanzeige mit LED's die in Form der Drehmomentkurve angeordet sind ... GENAU - das wärs. Die Drehzahl höre ich sowieso im Rahmen des Interessanten - steht ja schon in der Bibel: wer Ohren hat zu hören, der höre. Aber wenn ich wüsste, ob ich da nach "oben" noch Drehmoment habe, um den da vorn zu überholen - oder ob´s beim Hochdrehen eher schlapp wird . . . Hmmm, das ist eine SEHR feine Idee.

HF SHOOTER
04.11.2007, 19:47
So in der Zwichenzeit habe ich mich ein wenig mit der Programmierumgebung etc. vertraut gemacht. Und habe auch schon erste Ergebnisse laufen.

Im Moment zählt der mega8 von 0 -9 und gibt die Zahl auf dem 7-Segment Display aus. Davon hab ich auch mal ein Bild gemacht.

Jetzt würde ich gerne noch eine LED an PB0 blinken lassen, über den Timer0.

Folgender Code funktioniert nicht, die ISR vom Timer0 wird einfach nicht aufgerufen.


/* Projekt: Drehzahlmesser

Anzeige der Drehzahl auf 5 7-Segment-Anzeigen.
Anzeigen werden im Multiplexverfahren angesteuert,
die Drehzahl alle 100ms aktualisiert.

Später sollen noch max. Drehzahlspeicherung sowie eine
Begrüßung beim Einschalten hinzukommen.

AUTOR: Benjamin Ruppert
DATUM: 01.11.2007 - gute Frage */


#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>


/* Variablendeklaration */
uint8_t SEGMENT; // Bit0 = Seg. a ... Bit6 = Seg. g
uint8_t Zahl;


/* Prototypendeklaration */
void ZahlInSegment(uint8_t);


// Konvertierung Zahl -> Segmentanzeige
void ZahlInSegment(uint8_t Zahl) {

switch(Zahl) {
// Segment: gfedcba
case 0: SEGMENT = 0b00111111; break;
case 1: SEGMENT = 0b00000110; break;
case 2: SEGMENT = 0b01011011; break;
case 3: SEGMENT = 0b01001111; break;
case 4: SEGMENT = 0b01100110; break;
case 5: SEGMENT = 0b01101101; break;
case 6: SEGMENT = 0b01111100; break;
case 7: SEGMENT = 0b00000111; break;
case 8: SEGMENT = 0b01111111; break;
case 9: SEGMENT = 0b01100111; break;
// Segment: gfedcba
}


PORTC = 0x00; // PC0 - PC5 auf 0
PORTB &= ~(1 << 1); // PB1 auf 0


// Ausgänge setzen, wie 7-Segment angeschlossen ist
if (SEGMENT & (1 << 0)) { PORTC |= 0b00001000; } //a an PC3
if (SEGMENT & (1 << 1)) { PORTC |= 0b00010000; } //b an PC4
if (SEGMENT & (1 << 2)) { PORTC |= 0b00000001; } //c an PC0
if (SEGMENT & (1 << 3)) { PORTC |= 0b00000010; } //d an PC1

if (SEGMENT & (1 << 4)) { PORTB |= 0b00000010; } //e an PB1

if (SEGMENT & (1 << 5)) { PORTC |= 0b00000100; } //f an PC2
if (SEGMENT & (1 << 6)) { PORTC |= 0b00100000; } //g an PC5

}


// LED blinken lassen
ISR(TIMER0_OVF_vect)
{
if (PINB & (1 << 0)) { PORTB |= 0b00000000; }
else { PORTB |= 0b00000001; }
}



int main(void)
{

DDRC = 0b00111111; // PC0 - PC5 als Ausgang
DDRB = 0b00000011; // PB0 - PB1 als Ausgang
Zahl = 0;


// Timer konfigurieren und GIE-Flag setzen
TCCR0 |= (1 << CS01); // Vorteiler 8
sei();


while(1)
{

// Auf dem 7-Segment Display die Zahlen 0 - 9 anzeigen
ZahlInSegment(Zahl);
Zahl++;
if (Zahl > 9) { Zahl = 0; }

_delay_ms (250);
}
}


Über Tipps wäre ich dankbar.

EDIT: Habe vergessen den Timer0 Interrupt freizuschalten. Jetzt klappts.

mfg
Benny