Guten abend, allerseits ich bin leider nur elektriker und ein hobbyelektroniker, daher die etwas gewagte frage ich nehme via schmitt trigger kapazitiv über das zündkabel eines kleinen 2 takt motors das signal ab ab und habe dann sauberes rechtecksignal am atmega 644 leider bringe ich das programm selber nicht hin habe schon einiges versucht, aber so recht will es nicht gedacht ist ein externer interupt, mit dem ich einen counter raufzählen lasse dann will ich mittels internem interupt ein zeitfenster vorgeben, wo der zähler ausgewertet wird in der while schleife mache ich mehrere if bedingungen rein, also pro led 1 bedingung.. Je höher die drehzshl, desto mehr leds sollen leuchten und ab bestimmter drehzahl sollen alle blinken kann mir da wer weiterhelfen mit dem code, den ich in atmel 6.2 schreibe? vl mache ich auch einen fehler beim initialisieren der interupts... beste grüsse
1a) Man kann direkt auf einen Timer/Counter Eingangspin gehen und der Counter zählt per Hardware (ohne Interrupt). 1b) Man kann einen Pin-Change Interrupt verwenden um damit einen Zähler per Software zu erzeugen. 2) Ohne Quellcode kann dir keiner helfen.
So...dann mal den code im main steht cli(); DDRA=0xff; DDRC=0xff; DDRD=0b11110111; TCCR2B=(1 <<CS22)|(1 <<CS21)|(1 <<CS20); TCNT2=10; TIMSK2|=(1 <<TOIE2); MCUCR=(1 <<ISC11)|(1 <<ISC10); sei(); In der while stehen nur die bedingungen, wo der zählwert verglichen wird, also das hier als beispiel.. If ((cnt> 2)&&(cnt<6)) { PORTA=0b00000001; PORTB=0b00000000; } Das mit unterschiedlichen werten dann das zeitfensted als internen interupt ISR(TIMER2_OFV_vect) { flag=1; // ist bei mir in der main eingebunden mit rücksetzung cnt=spark; spark=0; TCNT2=10; } und hier der externe interupt ISR(INT1_vect) { spark++; } Der atmega 644 muss eh nen schaden haben, denn nicht alle ports lassen 5v raus trotz beidseitiger spannungsversorgung Kann da wer helfen?
Mit dem Suchbegriff "Drehzahl" in 'Projekte & Code' findet man dies http://www.mikrocontroller.net/search?query=drehzahl&forums[]=4&max_age=-&sort_by_date=0 Da sollte doch etwas zu finden sein.
gartler p. schrieb: > So...dann mal den code Und deine Variablen hast du nicht irgendwo deklariert? Mir sticht da gerade spark ins Auge. So geht das Programm doch nichtmal durch den Compiler. > Der atmega 644 muss eh nen schaden haben, denn nicht alle ports lassen > 5v raus trotz beidseitiger spannungsversorgung - Wie hast du den angeschlossen? - Welche Ports sind betroffen? - Wie ist JTAG konfiguriert?
Wenn der Controller eh einen Schaden hat, brauchst Du einen neuen... Vielleicht ist dein Vollständiges Programm ja korrekt !? ;)
Dependency injections sagen mir leider gar nichts so sehr will ich gar nicht ins detail gehen die variablen, wie auch die defines und includes, sind natürlich definiert...alles globale variablen ich habe den prozessor gegen einen atmega 32 getauscht, alle ports gehen auch hier nicht, aber es gibt genug andere freie ports eigenartig, dass der 32er sich nur im intrcosc 8mhz programmieren lässt...ich denke aber, dass das programm so funktionieren wird. was genau stimmt mit der interupt routine nicht? sobald eine steigende flanke ansteht, wird spark um 1 erhöht....alle 1/4 sec vom anderen interupt spark eingelesen und wieder auf null gestellt wenn wer einen schnellem kurzcode für mich hätte, wäre ich dankbar
Naja, versuch es doch mal, verständlich und ev mit Code rüberzubringen...das wäre durchaus hilfreich
gartler p. schrieb: > Naja, versuch es doch mal, verständlich und ev mit Code > rüberzubringen...das wäre durchaus hilfreich Wenn ich dir einen Rat geben darf, das süße Spice-Girl trollt in vielen anderen Beiträgen auch nur rum und versucht alle zu beleidigen und Stunk zu verbreiten. Einfach ignorieren, ok?
gartler p. schrieb: > Dependency injections sagen mir leider gar nichts Und dir fällt auch nichts dazu ein, wie du zumindest eine grobe Vorstellung bekommen kannst, was damit gemeint ist? http://de.wikipedia.org/wiki/Dependency_Injection > die variablen, wie auch die defines und includes, sind natürlich > definiert...alles globale variablen Die Frage ist nicht, ob sie definiert sind, sondern wie. Ich war nicht davon ausgegangen, dass du nicht kompilierbaren Code auf den µC geladen hast - wie auch ;-)
spicy meint vermutlich sowas hier: http://martinfowler.com/articles/injection.html#InversionOfControl, wobei ich die Ausdrucksweise (genau wie Martin Fowler) auch verwirrend finde. Es hilft dir auch nicht, wenn du mit Fremdworten zugeschaufelt wirst, das kann ich gut verstehen. Der Ansatz an sich ist ja schon richtig. Ein wie auch immer gearteter Zähler zählt die Zündimpulse und ein Zeitgeber holt sich den Zählerstand und setzt den Zähler zurück. Aus deinem Codefragment geht aber leider nicht hervor, ob du z.B. die Variablen richtig deklariert hast. Variablen, die in ISR verwendet werden,sollten bis auf wenige Ausnahmefälle als 'volatile' erklärt werden, denn für den Compiler ist eine ISR ein Unterprogramm, das nirgends aufgerufen wird (geschieht ja durch ein externes Ereignis) und er neigt deswegen dazu, Variablen wegzuoptimieren, wenn sie nicht volatile sind. Dadurch entstehen lustige und weniger lustige Effekte. Um die Hardware des MC besser auszunutzen, ist es ausserdem sinnvoll, wie gvs schon vorschlug, die Impulse mit T0 (Counter/Timer 0) oder T1 (Counter/Timer 1) zu zählen, das geschieht dann vollautomatisch, ohne das eine ISR benötigt wird. Dazu konfigurierst du einen Timer als Counter mit externem Takt und schliesst die Pulse an T0 oder T1 an. (Pin 1 oder Pin2 am Mega 644) Dein Zeitfenster bildest du mit einem anderen Timer. Dieser löst alle z.B. 100ms einen Interrupt aus, der den zählenden Counter ausliest und zurücksetzt. Dein Hauptprogramm kann dann mit dem gespeicherten ausgelesenen Wert, machen was es will. gartler p. schrieb: > ich habe den prozessor gegen einen atmega 32 getauscht, alle ports gehen > auch hier nicht Mir klingt das Problem arg nach aktiviertem JTAG Interface. Wenn du mal die Fuses anschaust und umprogrammierst, sperre das JTAG und dann sollte sich Port C normal verhalten.
:
Bearbeitet durch User
gartler p. schrieb: > alle ports gehen > auch hier nicht das sind die jtag-Pins auf PortC ->Fusebits
spicy schrieb im Beitrag #3894986: > Was hat JTAG bitte mit einer fehlerhaften Programmstruktur zu tun? Tja, wer aus dem Zusammenhang zitiert, findet das verwirrend. Für dich also nochmal komplett: Matthias Sch. schrieb: > gartler p. schrieb: >> ich habe den prozessor gegen einen atmega 32 getauscht, alle ports gehen >> auch hier nicht > > Mir klingt das Problem arg nach aktiviertem JTAG Interface. Wenn du mal > die Fuses anschaust und umprogrammierst, sperre das JTAG und dann sollte > sich Port C normal verhalten. Jetzt sollte das auch dir klar werden.
Oder kurz: Wolfgang schrieb: > - Wie ist JTAG konfiguriert? spicy schrieb im Beitrag #3894986: > Was hat JTAG bitte mit einer fehlerhaften Programmstruktur zu tun? Du scheinst in deiner Programmstrukturwelt vor lauter Schlagwortschwurbelei nicht erkannt zu haben, dass es noch mehr Probleme gibt.
Also, die variablen sind als volatile definiert, also das sollte passen ich werde nächste woche den signalgenerator anhängen und mal durchtesten, ob es funktioniert die fuses werde ich mir genauer ansehen...es funktionieren im moment pc7, pc6, pc1 und pc0....die anderen geben definitiv zu wenig spannung raus, man kann gaaaaanz geringes leuchten sehen Ich habe nun timer 1 fürs zählen aktiviert.... @matthias....wie kann man sich da im detail die interupt routine am zähler 1 ersparen? Ich muss doch irgendwie definieren, dass bei z.b steigender flanke ein zähler hochzählt @ich...wer provoziert, muss anderswo n defizit haben, daher reagiere ich da nicht so wirklich drauf... ich suche nur rat und bleibe dabei freundlich anfänger bin ich ja, ich habe sonst mit mittelspannung zu tun..
gartler p. schrieb: > pc7, pc6, pc1 und pc0 nochmal: pc2..5 sind durch JTAG belegt, die musst du erst in den Fusebits freischalten
gartler p. schrieb: > Ich habe nun timer 1 fürs zählen aktiviert.... > > @matthias....wie kann man sich da im detail die interupt routine am > zähler 1 ersparen? Ich muss doch irgendwie definieren, dass bei z.b > steigender flanke ein zähler hochzählt Ich mische mich mal ein;-) Habe einen Drehzahlmesser wie du ihn beschrieben ast in Betrieb. Allerdings in ASM programmiert: Timer 1 wird als Zähler mit Input Capture Irq gestartet: ldi temp1, 0;Timer1 Counter out TCCR1A, temp1 ldi temp1, 1<<ICES1|1<<CS11|1<<CS10 out TCCR1B, temp1 ldi temp1, 1<<OCIE2|1<<TICIE1 | 1<<TOIE1 out TIMSK, temp1 Die Routine für den Timer 1 Capture: icp1: ;Drehzahl über Input Capture ; Frequenz: 172800 Hz ; 600-> 17.280rpm 12000-> 864rpm in savereg, SREG push temp1 in T1CaptureL, ICR1L;Counterwerte auslesen in T1CaptureH, ICR1H clr temp1 out TCNT1H, temp1 ;Counter auf Null setzen out TCNT1L, temp1 sbr Pst_status, 1<<0 ;Motor-an Flag pop temp1 out SREG, savereg reti Weiter gibt es noch eine irq-Routine für den Überlauf von Timer1. Tritt dieser Interrupt ein, dann wurde kein Zündimpuls gemessen. T1OVL: ;Timer 1 Overflow: -> Kein Zündimpuls in savereg, SREG push temp1 cbr Pst_status, 1<<0 ;Motor-aus Flag clr temp1 sts drehzahl, temp1 sts drehzahl+1, temp1 pop temp1 out SREG, savereg reti Ich hoffe dir mit diesem Beispiel helfen zu können. PS. Mein Controller ist ein Mega322 mit 11,059 MHz.
:
Bearbeitet durch User
gartler p. schrieb: > @matthias....wie kann man sich da im detail die interupt routine am > zähler 1 ersparen? Ich muss doch irgendwie definieren, dass bei z.b > steigender flanke ein zähler hochzählt Als erstes solltest du dein Impulssignal auch an T0 oder T1 anschliessen, das sind die externen Counter Eingänge für Timer 0 resp. Timer 1. Nimm dir das Datenblatt des Mega644 (oder Mega32, das können beide) und konfiguriere nun den Timer auf 'externen Clock'. Beim Timer 0 im Mega 644 ist das ' External clock source on T0 pin. Clock on rising edge.', also
1 | TCCR0B = (1 << CS02) | (1 << CS01) | (1 << CS00); |
Der Timer wird nun mit jeder steigenden Flanke am Eingang T0 um 1 hochgezählt, und zwar ohne, das du softwaremässig irgendwas machen musst. Du musst lediglich darauf achten, das es ein 8-bit Timer ist, der nach 256 Takten überläuft, also fragst du ihn vorher ab. Timer 1 konfiguriert du auf regelmässigen Überlauf in bekannten Intervallen, am besten im CTC Modus, damit kannst du dir z.B. genau 100ms oder 500ms aussuchen. In dessen ISR liest du TCNT0 aus, setzt es auf 0 zurück und speicherst den ausgelesenen Wert als Zündungen pro Zeitintervall. Du bist also mit einer einzigen ISR fertig und hast die gewünschte Drehzahl, die du nur nach auf z.B. Umdrehungen pro Minute skalieren musst. Edit: igel z.B. verfolgt noch einen anderen Ansatz. Natürlich könntest du auch den Abstand ziwschen zwei Impulsen messen, dafür bietet sich der ICP Modus an, das ist es was Thomas hier macht.
:
Bearbeitet durch User
Eine Drehzahlmessung für einen Benzin-Motor muß in der Regel mit niedrigen Frequenzen klarkommen. Eine Leelaufdrehzahl von 900 Upm entspricht 15 Hz. Hier ist eine Zählung der Eingangsimpulse in einem festen Zeitraster eine schlechte Lösung. Bei gewünschten drei Anzeigewerten/s (Torzeit 1/3 s) ergeben sich Meßwerte für die Frequenz von 4, 5, oder 6 und umgerechnet 720, 900 oder 1080 Upm. Eine stark wackelnde Anzeige mit erheblichem Fehler wäre das Ergenbis. Erheblich besser ist es, die Zeit zu messen, die zwischen zwei Impulsen liegt. Bei 900 Upm beträgt die Zeit zwischen den Impulsen rund 66,7 ms bei einer recht hohen Auflösung im <= µs-Bereich. Das Meßverfahren nennt sich 'reziproke Frequenzmessung' und liefert beste Ergebnisse gerade bei drehzahltypischen Frequenzen. Das kleinst Beispielprogramm, was ich als Demo habe, ist ein Frequenz-Spannungswandler, der schon auf einm ATtiny44 läuft und auf einem ATmega644 erst recht. http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp11 Versuche, den Code zu verstehen. Sobald eine Anzeige hinzukommen soll, wird der Code umfangreicher: http://www.mino-elektronik.de/7-Segment-Variationen/LCD.htm#lcd3 Eine allgemeine Beschreibung des Meßverfahrens findest Du hier: http://www.mino-elektronik.de/fmeter/fmeter.htm
Um dir also alle Möglichkeiten offenzuhalten, solltest du also das Zündsignal auch noch auf Pin 20 (ICP) routen. Dann kannnst du mit allen Ansätzen ausprobieren. Achte nur darauf, das du in der Initialisierung der Ports alle diese Pins als Inputs konfigurierst.
:
Bearbeitet durch User
Vielen dank werde mich morgen damit beschäftigen...der lösungsansatzvon matthias ist gut zu verstehen..danke
Hier nochmal päde... Hab mein altes programm getestet...es ging zwar, allerdings falsch, ungefähr 40% daneben versuchte es dann so: DDRA=0XFF; DDRC=0XF8; //(INSGESAMT 13 LEDS direkt angesteuert, soll gehen mit 11mA/led) DDRD=0b11111011; cli(); TCCR0=(1 <<CS02)|(1 <<CS01)|(1 <<CS00); //timer0 auf steigende flanke TCNT=0; TIMSK=(1 <<TOIE1); //ich nehme den overflow-modus des timer1 mit preload TCNT1=59; MCUCR=(1 <<ISC01)|(1 <<ISC00); GICR=(1 <<INT0); sei(); Dann das main mit while programm...abfrage der werte und die if-bedingungen und der interupt sieht so aus ISR(TIMER1_OVF_vect) { flag=1; //wird im main abgefragt und nach den bedinungen auf 0 gesetzt cnt=TCNT0; TCNT0=0; TCNT1=59; } LEIDER FUNKTIONIERT DAS PROGRAMM NUN NICHT MEHR....WAS HAB ICH DA VERGESSEN?
gartler p. schrieb: > WAS HAB ICH DA VERGESSEN? Kein Grund gleich rumzubrüllen. Poste doch mal dein gesamtes Programm. Aus den beiden Schnipseln kann man nichts rauslesen. Welche Aufgabe haben jetzt Timer0 und Timer1? Und hängt der Zündimpuls nun am INT0 oder ICP1 oder was? Was ist TCNT?
? Hab zwar das programm wieder hinbekommen, aber eben ungenau bei niedrigen frequenzen...vor allem flippt die anzeige...sieht nicht gut aus würde gern die reziproke messung vornehmen, kann mit der theorie was anfangen, das war es auch schon.. will da nicht zu viel zeit damit vergeueden und bitte euch, mir vl den start zu ermöglichen, da es eben massiv an praxis mangelt. Also ich benötige die voreinstellungen für die counter, so ganz blick ich nicht durch ich werde max. 20000rpm messen wollen, bei etwa 15 leds im wichtigen drehzahlbereich ich muss also einen timer auf ctc modus bauen? Sozusagen als referenzfrequenz dann einen counter, der diesen ctc timer startet und bei z.b. 2. flankenänderung stopt und ausliest, zu guter letzt resettet, richtig. ? das signal will ich via pin 20, also icp auswerten lassen PLEASE HELP
Thomas Forster schrieb: > gartler p. schrieb: > WAS HAB ICH DA VERGESSEN? > > Kein Grund gleich rumzubrüllen. > Poste doch mal dein gesamtes Programm. Aus den beiden Schnipseln kann > man nichts rauslesen. Welche Aufgabe haben jetzt Timer0 und Timer1? Und > hängt der Zündimpuls nun am INT0 oder ICP1 oder was? Was ist TCNT? Ich brüll nicht rum, sorry....feststelltaste ist nur hängengeblieben ..ggg mein programm ist nicht gut geeignet, weil bei niedrigen drehzahlen einfach nur schrott rauskommt, also reziprok...aber da ist momentan die umsetzungsgabe nicht da
gartler p. schrieb: > mein programm ist nicht gut geeignet, weil bei niedrigen drehzahlen > einfach nur schrott rauskommt, also reziprok...aber da ist momentan die > umsetzungsgabe nicht da Hast du keine Großbuchstaben? Es nervt, sowas dahingerotztes lesen zu müssen.
gartler p. schrieb: > DDRA=0XFF; > DDRC=0XF8; //(INSGESAMT 13 LEDS direkt angesteuert, soll gehen mit > 11mA/led) > DDRD=0b11111011; > cli(); > TCCR0=(1 <<CS02)|(1 <<CS01)|(1 <<CS00); //timer0 auf steigende flanke > TCNT=0; > > TIMSK=(1 <<TOIE1); //ich nehme den overflow-modus des timer1 mit preload > TCNT1=59; > > MCUCR=(1 <<ISC01)|(1 <<ISC00); > GICR=(1 <<INT0); > > sei(); Ich seh da nirgends eine Initialisierung des Timers 1 (Zeittor). Du gibst seinen IRQ frei und füllst seinen Counter, aber er wird nie gestartet.
1 | TCNT=0; |
Das soll bestimmt TCNT0 sein, oder? Ich wundere mich nur, das dein Compiler sowas zulässt, ohne über undefinierte Sachen zu jammern.
gartler p. schrieb: > mein programm ist nicht gut geeignet, weil bei niedrigen drehzahlen > einfach nur schrott rauskommt, also reziprok...aber da ist momentan die > umsetzungsgabe nicht da Das hatte ich ja schon angekündigt ;-) Ich habe Dir ein paar Links gegeben, die Du aufmerksam lesen solltest, da sie nicht zu geschwätzig sind. Diese Arbeit kann Dir keiner abnehmen! Wenn Fragen offen bleiben, frag ganz konkret nach. Ach, ich habe noch eine etwas einfachere Beschreibung, wie ich hoffe: http://www.mino-elektronik.de/Archiv/Elektronik25_1984.pdf
gartler p. schrieb: > Hab zwar das programm wieder hinbekommen, aber eben ungenau bei > niedrigen frequenzen...vor allem flippt die anzeige...sieht nicht gut > aus Wie ungenau und was heißt flippen? Ein kleiner Zweitakter mit Vergaser schwankt in der Drehzahl ständig um locker mal 100 rpm. Das hat mein Drehzahlmesser auch. Um die Anzeige zu beruhigen errechne ich einen gleitenden Mittelwert über vier Zündungen (glaub ich jedenfalls, ist schon lange her). > ich muss also einen timer auf ctc modus bauen? > Sozusagen als referenzfrequenz Also arbeitest du nun mit Timer-Capture. Dann also Timer1, da der 16-Bit breit ist. Das ist keine Referenz, sondern einfach der Zeitzähler, wieviel Zählimpulse zwischen den Zündungen auftreten. Niedrige Drehzahl -> lange Zeit -> hoher Zählerwert im ICR1. Achtung, der Zählwert steht im ICR1, nicht in TCNT1. Der Input-Capture-Mode von Timer1 bewirkt, dass bei einem Impuls am ICP-Pin der aktuelle Wert aus dem Zählregister in das ICR1-Register geschrieben wird. Du mustt diesen Wert dann nur noch auslesen. > dann einen counter, der diesen ctc timer startet und bei z.b. 2. > flankenänderung stopt und ausliest, zu guter letzt resettet, richtig? Ein zweiter Counter ist für die eigentliche Drehzahlerfassung gar nicht nötig. Das macht alles schon T1 im Input-Capture-Mode. Ein kleines Beispiel in C: http://www.mikrocontroller.net/attachment/highlight/20833
Ich habs 2 mal sorgfältig gelesen konkrete fragen dazu lauten 1.) Wie aktiviere ich mit der ersten flanke den referenztimer? 2.) Selbe Frage mit "wie stoppe ich den" 3.) Allgemeines Wirrwarr mit der anfänglichen konfiguration der register ich weiss, worum es geht, kann es nicht umsetzen...und falls ich es nicht hinbekomme, werd ich es einfach lassen und widme mich wieder nützlicheren dingen, kein thema bedanke mich aber trotzdem für die infos und tipps....habe leider keine zeit mich da ewig damit zu beschäftigen kurzum, ein einfacher code der isr und anfänglichen einstellungen wären für mich einfacher..
gartler p. schrieb: > 1.) Wie aktiviere ich mit der ersten flanke den referenztimer? > 2.) Selbe Frage mit "wie stoppe ich den" Mit 'init_timer()' wird Timer1 gestartet und nie wieder gestoppt! Mit jedem input-capture wird der Zeitpunkt erfaßt und die Anzahl der gemessenen Impulse erhöht. Auch die Anzahl wird nie wieder gelöscht, sondern wie bei der Zeit die Differenz zwischen den Werten (neuer_wert - alter_wert) verwendet. In 'main()' wird das entsprechend ausgewertet. > 3.) Allgemeines Wirrwarr mit der anfänglichen konfiguration der register Das ist doch hinreichend kommentiert? gartler p. schrieb: > kurzum, ein einfacher code der isr und anfänglichen einstellungen wären > für mich einfacher.. Den habe ich Dir gegeben. Die Programme sind mit AVR-Studio 4.19 erstellt und sollten auch unverändert auf 6.x laufen.
Mal vorneweg (vereinfacht ohne Überlauf): Die Zündfrequenz des Motors liegt grob zwischen 8Hz (800 U/min, 0.125s) und 350 Hz (21000 U/min). Gehen wir mal davon aus, dein uC läuft mit 1MHz (hast du bisher verschwiegen). TimerCounter1 geht bis 65535. TC1 soll innerhalb der 0.125s (800 U/min) nicht überlaufen. Man braucht also einen Prescaler für TC1. Bei Prescaler 8 zählt TC1 mit 125 kHz. Bei 8Hz Zündfrequenz ergibt das 125000/8=15625 Counts im Zähler. Das ist kleiner als 65535, Prescaler 8 passt also mal... Timer1 wird also initialisiert: TCCR1A = 0 TCCR1B = 1<<ICES1 | 1<<CS11 TIMSK = 1<<TICIE1 | 1<<TOIE1 > 1.) Wie aktiviere ich mit der ersten flanke den referenztimer? Das ist soeben geschehen. Die Flanke ist hier erst mal wurscht. > 2.) Selbe Frage mit "wie stoppe ich den" Wie m.n. schreibt: Nie mehr. Der läuft immer weiter. Tritt am ICP1-Pin die oben initialisierte steigende Flanke auf, dann kopiert TimerCounter1 automatisch den aktuellen Counterwert in das 16-Bit breite InputCaptureRegister1 und löst den ICP1-Interrupt aus. ISR( TIMER1_CAPT_vect ) { Time = ICR1; TCNT1 = 0; flag=1; //wird im main abgefragt } Die Interrupt-Routine liest nun das ICR1 aus und legt den Wert in der Variablen Time ab. Das muss sein, da bei der nächsten Flanke das ICR1 ja neu beschrieben wird. Der Counter wird noch schnell auf Null gesetzt, dann muss man nicht mit einem Überlauf über 65535 rumrechnen. Im Hauptprogramm kann man nun anhand von 'flag' den aktuellen Zeitwert in eine Drehzahl umrechnen und sonst was damit anstellen.
Liebe leute herzlichen dank....das hat geholfen...hab das programm von m.n. kapiert, nachdem die weiteren kommentare danach gekommen sind ich musste nur noch frequenz und prescaling anpassen, funktioniert wunderbar mit dem frequenzgenerator überprüft tooooop...danke demnächst mal die dazu gebaute schaltung mit dem schmitt trigger testen und das zündsignal kapazitiv abnehmen... mir will immer noch nicht in den kopf, dass man 1 timer 2 mal beschreiben kann, einmal im capture modus, einmal im overflow, nehme das aber einmal hin
Schön wenns jetzt geht. Zu meiner obigen Interrupt-Routine noch der Vollständigkeit halber, falls das mal jemand lesen sollte. ISR( TIMER1_CAPT_vect ) { Time = ICR1; TCNT1 = 0; flag=1; //wird im main abgefragt } Werden mehrere Interrupts verwendet, kann es mit diesem Code zu Messfehlern kommen: Ist bei steigender Flanke am ICP noch ein anderer IRQ aktiv, wird TIMER1_CAPT_vect verzögert aufgerufen. Bis dahin hat TCNT1 natürlich etwas weitergezählt und wird nun verspätet auf Null gesetzt. Um diesen Fehler auszugleichen muss es richtiger heißen: TCNT1 = TCNT1 - Time
Thomas Forster schrieb: > Bis dahin hat > TCNT1 natürlich etwas weitergezählt und wird nun verspätet auf Null > gesetzt. Um diesen Fehler auszugleichen ... darf man den Timer nicht löschen, sondern immer nur das capture-Register auslesen! Zum einen ist die ISR immer zu spät und der Timer ist für andere Verwendund 'kaputt'. Ich verweise noch einmal auf http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp11, wo mit Timer1 ein 10-Bit DAC (mit PWM), ein Millisekunden-Timer und die eigentliche Frequenzmessung inkl. ISR für die Überläufe erledigt werden: insgesamt 4 x ISR. Ein Löschen/Verändern des Timers würde diese Möglichkeiten zunichte machen. Ebenso ungeschickt ist es, die Überläufe zu löschen oder, wie an anderer Stelle gesehen, das TOV1-Bit außerhalb der entsprechenden ISR zu löschen. Die ISR-Routine ist damit für nichts anderes mehr zu gebrauchen.
m.n. schrieb: > Ich verweise noch einmal auf > http://www.mino-elektronik.de/fmeter/fm_software.htm#bsp11 Für deinen und wohl viele andere Anwendungsfälle ist das natürlich der bessere Weg. Da ich lediglich einen Drehzahlmesser für Ottomotoren gebastelt habe, kann ich hier vereinfachen und nutze den Timer1Overflow dann als Abbruchkriterium/Erkennung Motor aus.
Noch eine abschliessende frage: Würde einer der anwesenden hier insgesamt 13 LEDs an die ports hängen ohne treiber? Die leds kommen mit vorwiderstand 220 ohm und brauchen dann etwa 22mA 9 können permanent leuchten, ab 10 leds gibts blinken von allen also 13x blinken mit etwa 30% zeit an, rest aus 40mA pro pin werden zwar nicht überschritten, aber beim 32er in pdip ausführung steht nicht dezitiert drauf, wieviel belastung gesamt drauf sein darf ein input wird noch angeschlosseb, sonst nix was meint ihr?
Die Frage ist, ob du wirklich die 22mA brauchst. Meist reich auch ein wesentlich kleinerer Strom, um eine LED hell genug leuchten zu lassen. Probiere es einfach aus. Vielleicht kommst du ja auch mit beispielsweise 5mA hin...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.