PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rechteck Frequenz messen



oZe
12.08.2007, 00:38
Hallo!
Also nachdem ich mir überlegt habe das es Schwachsinn ist eine Frequenz erst über nen D/A Wandler zu wandeln und anschließend mit dem ADC vom Mikrocontroller zu wandeln und weiter zu verarbeiten (is ja dumm weil ich dann ja "umsonst" umwandel) habe ich mir folgendes Programm überlegt um eine Rechteckfrequenz zu messen:



$regfile = "2313def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 8000000
$baud = 9600

Config Portb.0 = Output 'definiert Portb.0 als output

Config Pind.5 = Input 'Ein Pin (PD5) wird als Eingang definiert
Portd.5 = 1 'Interner Pullup Widerstand ein

Config Timer1 = Timer , Prescale = 256 'Konfiguriere Timer1
Enable Timer1 'schalte den Timer1 ein
On Timer1 Isr_von_timer1 'verzweige bei Timer1 überlauf zu Isr_von_Timer1
Enable Interrupts
Timer1 = 34285 'Timer1 soll schon von 34285 wegzählen


Dim Signale As Integer
Signale = 0

Do

If Pind.5 = 0 Then
Incr Signale

Else
'nichts tun da wir keinen Eingangsimpuls haben
End If
Loop

End

Isr_von_timer1: 'ISR von Timer1
'Timer1 soll wieder von 34285 wegzählen
If Signale > 3 Then
Portb.0 = 1
Else
Portb.0 = 0
End If
Wait 1
Signale = 0
Timer1 = 34285


Return



Ich lege also an PD5 eine rechteckfrequenz an die den Eingang nach Masse zieht. Sobald der Eingang nach Masse gezogen wird wird die Variable "Signale" incrementiert. Der Timer ist so konfiguriert, dass jede Sekunde überprüft wird wieviele Eingangsimpulse in der Sekunde angekommen sind. Momentan überprüfe ich dann ob es mehr als 3 sind. Falls ja wird PB0 auf high gesetzt woran ich eine LED klemmen habe.


Zum testen habe ich einen Taster nach masse gelegt von PD5. Über diesen erzeuge ich also zum testen meine Rechteckfrequenz. Wenn ich jetzt schneller als 3 mal pro sekunde drücke sollte eigentlich die LED angehen. Leider ist die LED schon an sobald ich die Stromversorgung vom MC anmache....
Hab ich einen Denkfehler in meinem Programm?

for_ro
12.08.2007, 10:41
Hi,
in deiner Do ... Loop Schleife überprüfst du dauernd - und zwar so schnell wie der Controller läuft - ob dein Eingang auf 0 ist und erhöhst dann die Variable. Du musst auch noch feststellen, ob der Eingang zwischendurch wieder auf 1 gegangen ist, weil du ja eigentlich die Wechsel zählen willst.

Gruß

Rolf

oZe
12.08.2007, 13:36
hmm wie lässt sich das denn am besten realisieren? Zum testen würds ja reichen einfach 100ms pause zu machen (waitms 100) so das ich quasi zeit habe um den taster wieder loszulassen aber für die letztendliche Anwendung (drehzahlbestimmung) wären die 100ms eventuell schon wieder zu viel.

for_ro
12.08.2007, 13:51
Na ja, wenn du ein Taster bedienst, dann musst du den entprellen.
Schau dir mal den Debounce Befehl an. Dabei wird Prellen weggefiltert und eine Sub aufgerufen, wenn zwischendurch der Pegel mal anders war.
Wenn du die Flanken von einem Geber bekommst, würde ich einen externen Interrupt Eingang nehmen
In beiden Fällen in der ISR eine Variable hochzählen.

Gruß

Rolf

oZe
12.08.2007, 13:55
Wunderbar den schau ich mir direkt mal an. Danke dir für deine Hilfe! Ich finds echt gut das Anfängern hier wirklich gut geholfen wird ;-)

oZe
12.08.2007, 23:20
Oh man auch wenns jetzt wieder nervig wird: Mein bascom weigert sich mir die Hilfe anzuzeigen... Ich kann zwar den Debounce artikel raussuchen aber wenn ich auf "Anzeigen" klicke passiert nix.... Wäre es möglich das mir jemand den Artikel rauskopiert oder aber mir ne ordentliche Seite sagt wo die Funktion beschrieben ist? Danke!

MeckPommER
13.08.2007, 07:53
Maximiere mal das Anzeigefenster ... manchmal fällt die Hilfeseite einfach nur rechts aus dem Fenster.

for_ro
13.08.2007, 09:37
Außerdem findest du hier online die Hilfe zur letzten freigegebenen Version:
http://avrhelp.mcselec.com/bascom-avr.html

Gruß

Rolf

oZe
13.08.2007, 14:55
Maximiere mal das Anzeigefenster ... manchmal fällt die Hilfeseite einfach nur rechts aus dem Fenster.

Oh man darauf hätt ich auch selber kommen können... *g*
Danke für den Tipp und danke für den Link. Ich schaus mir gleich mal alles genauer an ;-)

oZe
13.08.2007, 22:41
So also ich habe das ganze jetzt mal mit dem Debounce befehl gemacht bin mir aber immernoch nicht sicher ob das so hinhaut. Ausprobieren kann ichs momentan nicht weil ich meinen MC geschrottet habe... (Programmer war im eimer). Kann mir eventuell noch mal jemand auf die Sprünge helfen ob das so geht und falls nicht was ich für fehler gemacht habe? Ich bin mir nicht sicher ob ich nicht in der SUB "Eingangerkannt" bereits wieder prüfen muss ob der Eingang wieder auf high steht.

Hier mein Code:



$regfile = "2313def.dat" 'ATtiny2313 Definitionen laden
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 8000000 '8MHZ Systemtakt einstellen
$baud = 9600

Config Portb.0 = Output 'PortB.0 ist mein Ausgang an dem die LED hängt

Config Pind.5 = Input 'PIND.5 ist mein Signaleingang
Portd.5 = 1 'Internen Pullup Widerstand aktivieren

Config Timer1 = Timer , Prescale = 256 'Timer einstellen
Enable Timer1 'Timer starten
On Timer1 Isr_von_timer1 'Sprungmarke bei Overflow einstellen
Enable Interrupts 'Interrupts aktivieren
Timer1 = 34285 'Timer auf 34285 einstellen damit eine Sekunde realisiert ist


Dim Signale As Integer 'Meine Zählervariable in der die Signale pro Sekunde gezählt werden
Signale = 0 ' Signale erst mal auf 0 setzen

Do

Debounce Pind.5 , 0 , Eingangerkannt 'Überprüfen ob PIND.5 auf low gezogen wurde
Debounce Pind.5 , 1 , Leer 'Überprüfen ob PIND.5 wieder auf high steht um doppeltzählen zu vermeiden

Loop

End



Eingangerkannt:
Incr Signale 'Die Sinale Variable wird um 1 erhöht

Return


Leer:
'Hier passiert nichts. Nur zum Sicherstellen das nicht doppelt gezählt wird
Return



Isr_von_timer1:

If Signale > 3 Then 'Überprüfen ob mehr als 3 Signale in der Sekunde angekommen sind
Portb.0 = 1 'Falls ja wird PORTB.0 auf High gesetzt (LED geht an)
Else
Portb.0 = 0 'Falls nicht wird PORTB.0 auf Low gesetzt (LED geht aus bzw. bleibt aus)
End If
Wait 1 'Eine Sekunde Pause damit man das Leuchten der LED sehen kann
Signale = 0 'Zählervariable wieder auf 0 setzen um eine neue Messung zu veranlassen
Timer1 = 34285 'Timer wieder auf 34285 vorstellen um wieder eine Sekunde zu messen


Return

oZe
15.08.2007, 23:12
Kann mir denn wirklich keiner Helfen und einmal schnell den Code durchschauen?

Stromi
15.08.2007, 23:41
Ich denke das funzt, bis zur welchen Frequenz soll es den können?

oZe
16.08.2007, 04:49
150Hz reichen. Sollte aber doch keinen einfluss auf den Code haben. Es ist auch nicht wirklich ausschlaggebend das es zu 100% genau ist.