PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfe frei Frequenzgenerator



Basteltisch
08.10.2009, 19:46
Hallo zusammen,
ich habe mir folgende Funktion ausgedacht um eine Frequenz zu erzeugen:



Sub Genhz(byval Freq As Integer , Byval Lenms As Integer)
Dim Idelay As Integer

Dim Tgone As Integer

Tgone = 0

Idelay = Freq / 2
Idelay = 1 / Idelay
Idelay = Idelay * 1000

While Tgone < Lenms
Portd.5 = 1
Waitms Idelay
Tgone = Tgone + Idelay
Portd.5 = 0
Waitms Idelay
Tgone = Tgone + Idelay
Wend

End Sub

dieser Funktion wird zum einen die Frequenz, zum anderen die dauer der Frequenz übergeben.

Es erzeugt auch einen Ton, allerdings funktionieren 2 Sachen nicht:

1) Ist es immer ein sehr hoher Ton, selbst bei 200 Hz ist er noch immer sehr hoch.
2) Die Schleife wird nicht verlassen. Die Variable Tgone zählt zusammen wie lange die Schleife schon läuft anhand der gewarteten Zeit um die Wellen zu formen, jedoch macht es endlos weiter. Leider habe ich noch keine gute debugging Infrastruktur und muss dort mit Logik rangehen.

Doch ich finde keinen Fehler :/

Weiss jemand Rat?

Es grüßt,
Basteltisch

Thomas$
08.10.2009, 20:01
waitms und dann eine zahl aber eine variable geht nicht da musst du das umschreiben
for bla = 1 to milliskunden
waitms a
next bla

Besserwessi
08.10.2009, 20:05
Wenn man nur eine Frequenz erzeugen will, macht man das besser mit einem Timer. Entweder per Interrupt, oder ganz in Hardware über einen OC... Pin. Das geht entweder per PWM oder über den Toogle Mode am Augang. Mit dem Timer kann man dann nebenher noch andere Dinge machen, wenn man will, und blockiert nicht den µC. Alternativ geht auch ein Stromsparmode, wenn nichts weiter zu tun ist.

Basteltisch
08.10.2009, 20:29
Hallo,
danke für die Antworten.

Ich möchte es ersteinmal ohne Timer probieren.

Das mit der For Schleife habe ich umgesetzt:


Sub Genhz(byval Freq As Integer , Byval Lenms As Integer)
Dim Idelay As Integer
dim Tgone As Integer
Dim I As Integer

Tgone = 0

Idelay = Freq / 2
Idelay = 1 / Idelay
Idelay = Idelay * 1000


While Tgone < Lenms
Toggle Portd.5

Tgone = Tgone + Idelay

For I = 1 To Idelay
Waitms 1
Next I


Wend

End Sub

jedoch befürchte ich, dass ich wieder irgend eine Besonderheit von Bascom übersehen habe, denn es funktioniert auch nicht.

Was kann man alles falsch machen, wo darf man keine Variablen verwenden?

Es grüßt,
Basteltisch

for_ro
08.10.2009, 21:19
waitms und dann eine zahl aber eine variable geht nicht da musst du das umschreiben
for bla = 1 to milliskunden
waitms a
next bla
Hallo Thomas,
das stimmt so nicht. Waitms kann sehr wohl mit Variablen angegeben werden, nur Waitus nicht.

@basteltisch
Die Dims in deiner Funktion sind globale Variablen. Lokale variable deklariert man mit LOCAL.
Das hier
Idelay = Freq / 2
Idelay = 1 / Idelay 'Falls Freq >=4 ist Idelay danach 0 wegen der Integer Typen
Idelay = Idelay * 1000
solltest du besser so schreiben
Idelay = 500 / Freq

Außerdem setzt du den Rückgabewert der Funktion gar nicht.
Ansonsten kann ich mich nur Besserwessi anschließen: Nimm einen Timer.

Thomas$
08.10.2009, 22:05
wieder was gelernt, ich war immer davon ausgegange es geht beides nich weil waitus var nich ging.

Basteltisch
09.10.2009, 17:17
Hallo,
bei Idelay = 500 / Freq komme ich auf ganz andere Ergebnisse als bei meiner Rechnung. welche ist denn nun richtig?

Ich habe meinen QUellcode abermals geändert, diesesmal benutze ich für alle Variablen den Typ Single (wegen den Nachkommastellen).

Der ganze Code:


Sub Genhz(byval Freq As Single , Byval Lenms As Single)
Dim Idelay As Single
Dim Tgone As Single

Tgone = 0

Idelay = Freq / 2
Idelay = 1 / Idelay
Idelay = Idelay * 1000

While Tgone <= Lenms
Toggle Portd.5

Tgone = Tgone + Idelay

Waitms Idelay


Wend
Return
End Sub


Bei Timern schreckt mich ein wenig ab dass ich nicht wie ich es aus anderen Sprachen kenne einfach einen Milisekundenwert angeben kann sondern mit der Taktfrequenz rumrechen muss, was meiner Meinung nach eine Fehlerquelle ist.

stimmt das so?

Es grüßt,
Basteltisch

edit: fehler ist weg, habs nicht declared

edit2: Grundsatzproblem ist immernoch da, es kommt immer der selbe Ton und aus der Schleife raus will er auch nicht.

Sauerbruch
09.10.2009, 18:12
Bei Timern schreckt mich ein wenig ab dass ich nicht wie ich es aus anderen Sprachen kenne einfach einen Milisekundenwert angeben kann sondern mit der Taktfrequenz rumrechen muss, was meiner Meinung nach eine Fehlerquelle ist.

Okay, aber die ultimativ fehlerfreie Lösung scheint Dein Ansatz bisher ja auch nicht zu sein, oder? Will sagen, dass es manchmal sogar Spaß macht, sich mit Fehlern auseinanderzusetzen und sie zu suchen :-)

Was ist denn genau Dein Ziel? Wenn Du z.B. "nur" Signaltöne (z.B. als Tastenquittung oder so) erzeugen möchtest, dann wäre der Befehl "Sound" vielleicht das richtige. Eine Zeile Code, und mit ein bisschen rumprobieren kommt gut das heraus, was man möchte.

Sollen´s aber hochgenaue Rechtecksignale sein, dann wäre ein Timer und PWM garantiert das beste.

Um welche Frequenzbereiche geht´s denn?

Basteltisch
09.10.2009, 18:52
Hallo,
wenn du andeuten möchtest dass ich selbst nicht nach Lösungen suche sondern nur alles hier reinschreibe und hoffe das es irgendjemand löst dann liegst du falsch.

Ich möchte es hinbekommen auf z.b. Lautsprecher einen Ton auszugeben den ich selbst mit einer Prozedur berechnet habe. Fertige Lösungen sind zwar schön, aber wenn ich nur fertige Lösungen verwenden würde könnte ich mir ja sämtliche Projekte bei Ebay fertig kaufen. Das ist aber nicht der Sinn der Sache.

Ich möchte jetzt z.b. herausfinden wie Leistungsfähig diese kleinen Handy Kopfhöhrer sind (welche Frequenzbereiche sie wiedergeben). Ich habe mit einem .net Programm über meine PC Lautsprecher herausgefunden, das ich bis ca 18kHZ einen Ton wahrnehme, und dies möchte ich bei den kleinen Lautsprechern wiederholen.

Also es geht um 0 bis 20kHZ.

Der Fehler im aktuellen Programm muss aber an der Syntax liegen, etwas anderes kann ich mir nicht erklären. Der Ton wird dauerhaft ausgegeben, d.h. wird wohl die Variable Tgone nicht hochghezählt. Aber was ist so falsch an tgone = tgone + idelay?

Und einen Ton höhre ich ja, deswegen kann idelay ja nicht 0 sein.

Ich bin an dieser Stelle wirklich ratlos.

Es grüßt,
Basteltisch

for_ro
09.10.2009, 19:41
Hallo Basteltisch,
ich war davon ausgegangen, dass du die Freq in Hertz und die Dauer des Tons Lenms in Millisekunden angibst.
Bei einer Freq von 2000Hz und 1000 ms Länge wäre dann nach deiner Rechnung

Idelay = Freq / 2 '2000/2=1000
Idelay = 1 / Idelay '1/1000=0,001
Idelay = Idelay * 1000 '0,001*1000=1ms Verzögerung
Dies wäre gleich
Idelay = 2000/Freq

Bei 2000Hz is die Periodendauer aber nur 0,5ms.
Da du toggelst muss du aber zweimal umschalten für eine Periode. Die halbe Periodendauer ist 0,25ms.
Dies erreichst du mit

Idelay = 500/Freq

Bei Frequenzen über 2000Hz käme bei dir schon immer 0 heraus, bei der richtigen Rechnung sogar schon über 500Hz. Damit dies dennoch funktioniert, müsstest du über 500Hz auf waitus umschalten.
Und lass mal das Return in der Sub weg, das ist dort falsch.
Kann es sein, dass dein µC sofort wieder resettet oder auf einer anderen Frequenz läuft als du denkst?
Mach mal am Anfang direkt ein Wait 1 rein um zu erkennen ob er einen Reset ausführt.

Zeig doch mal dein ganzes Programm, dann kann man sicher mehr sagen.
Und anschließend probieren wir dir mal zu helfen, verschiedene Frequenzen mit einem Timer zu erzeugen.