reziproker Frequenzzähler mit BASCOM-AVR

Gast #4027044
Lesenswert?

So schnell kann es gehen: gestern wußte ich noch nicht, wie man BASCOM 
schreibt und heute habe ich schon mein erstes Programm damit geschrieben 
;-)

Verwendet wurde die kostenlose Demo-Version mit 4K Code-Limit. Es reicht 
für einen reziproken Frequenzzähler mit ATmega328, wobei noch ca. 500 
Byte frei bleiben. Gegenüber C gibt es einige Einschränkungen; 
insbesondere die Seiteneffekte beim Aufruf von Funktionen nerven nicht 
schlecht. Das kennt man schon garnicht mehr.

Aktuell ist der Frequenzbereich auf 0,01 Hz - ca. 100 kHz begrenzt; 
schneller geht es mit BASCOM nicht. Die Ergebnisse sind immer 6-stellig, 
weshalb der ext. Quarz schon abgeglichen sein sollte oder besser ein 
TCXO verwendet wird. Ganz bequem kann man 'F_clock' auf einen sinnvollen 
Wert setzen: probieren und anpassen!
Wer mag, kann das Programm noch für einen automatischen Vorteiler 
erweitern. Beispiele von mir dazu gibt es genug.
Viel Spaß!

Korrektur: bitte an den beiden Stellen, wo Timsk1.1 steht, auf Timsk1.0 
ändern.
Angehängte Dateien:
Gast #4031955
Lesenswert?

Als kleine Spielerei habe ich die Interruptverarbeitung optimiert, indem 
nur noch die Register gerettet werden, die offensichtlich benötigt 
werden. Ferner lassen sich Ausdrücke wie:
"wert = wert + 1" durch "incr wert" beschleunigen.
Die Obergrenze für Frequenzmessung steigt damit auf ca. 200 kHz.

Neben Frequenz und Periode kann jetzt auch die Drehzahl ausgegeben 
werden. Die Ausgabe selber erzeugt nun einen formatierten String mit 
Dimensionsangabe. Daher ist nicht nur ein Print auf die serielle 
Schnittstelle, sondern auch z. B. eine Ausgabe auf ein angeschlossenes 
LCD möglich.

Für die auf 4K Code begrenzte Version ist es besser, anstatt eines 
ATmega328 einen ATmega48/88 zu verwenden. Durch kürzere Adressierung 
wird deutlich Code gespart. Die gezeigte Version benötigt von einem 
ATmega48 rund 83%, wodurch noch Platz (knapp 700 Byte) für eigene 
Erweiterungen bleibt.
Angehängte Dateien:
Gast #4032303
Lesenswert?

Die letzte Version ist noch einmal optimiert, indem beide 
Interruptroutinen nun komplett in Assembler geschrieben sind. Der Code 
wurde dadurch kleiner und die maximale Eingangsfrequenz liegt nun über 
600 kHz mit einem ATmega48 @ 16 MHz. Das ist nicht schlecht!
Angehängte Dateien:
#4040140
Lesenswert?

Für hohe Frequenzen (> 10kHz) solltest Du besser fahren (weiter als 
200kHz kommen), wenn Du statt Periodendauer die Impulse (mit dem ICP, 
ohne ICP-INterrupt) zählst.. Also prinzipiell

- Timer1 mit dem ICP hochzählen, in der Overflow-ISR die Overflows 
mitzählen
- Timer0 auf genau eine Sekunde Messzeit stellen (ISR für die Overflows) 
und starten

Dabei beachten, dass zwischen diesen beiden Schritten auch schon Impulse 
anliegen (Anfangswert vom Timer1 bei der ersten Timer0-Auslösung am Ende 
abziehen).

Wenn Du es gang gut machen willst, misst Du erstmal ungefähr, und 
benutzt dann eine der beiden Methoden (Periodendauer oder Torzeit wie 
oben beschrieben)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren