Also, das gehört eigentlich zu diesem Audio-Thread, aber dort wäre es sicherlich untergegangen. hab immer noch das gleiche problem, da das ding aber in spätestens 2 wochen ferig sein sollte, bin ich von der audo-datei auf einen hochfrequenten ton umgestiegen. das mit der datei ist einfach jetzt zu kompliziert, werde ich aber auch noch ausprobieren. Hab schon ein bissl gesucht, hab aber keinen so richtigen Assembler-Code gefunden, mit dem ich den Ton am AVR erzeugen könnte. kann mir da jemand helfen?
ja, du dir selbst: Du hörst auf, irgendwelchen fertigen Code zu suchen, und: SCHREIBST IHN EINFACH SELBST ;-)
1,667µs high 1,667µs low dann sind es 30KHz Periodendauer 3,3333333µs
30kHz und Ton.... ich weiß ja nicht wozu du diese Anwendung brauchst, aber hören wirst du diesen Ton wohl eher nicht.
Das Komma muß natürlich eine Stelle nach rechts. 16,67µs high 16,67µs low dann sind es 30KHz Periodendauer 33,333333µs
Wobei hast du Schwierigkeiten? Einen Timer aufsetzen: Timer 1 CTC Modus * entweder im Interrupt einen Pin toggeln * oder die OCR Einheit den Pin toggeln lassen noch ein bischen rumrechnen, wie der Vorteiler und der CTC-Top Wert eingestellt werden muessen. Fertig. Sollte selbst für einen Anfänger nicht länger als 2 Stunden dauern (wobei 1 Stunde 35 Minuten fürs Datenblatt lesen draufgehen, 5 Minuten fürs Rechnen, 15 Minuten für Experimente und 5 Minuten fürs eigentliche Programm)
Sinus ? 8 Bit oder mehr ? Tabelle anlegen, z.B. Sinus (in Exel oder Qbasic oder VBA erstellen und als TXT speichern) in C importieren und Zeilenende Datentrenner setzen, R 2 R Netzwerk an Ports , fertig und sauber, den Timer nur für die zeitgerechte Ausgabe ;-)
>in C importieren und Zeilenende Datentrenner setzen
wie geht das?
Also erstmal vielen dank. naja als anfänger isses echt nicht einfach. da ich so was wie töne erzeugen noch nie gemacht habe. ich weiß halt nich wie ich das so richtig anstellen soll. also was ist CTC und OCR ? hab davon noch nie was gehört. P.S. Programmiere zur zeit noch in assembler
Auch einer wrote: >>in C importieren und Zeilenende Datentrenner setzen > > wie geht das? neue C öffnen, copy & paste, oder sinus.txt als sinus.c oder .h speichern und die benötigten Zeichen eintippen a= ; b= ; oder unsigned int sin[]= { 0 , ......, 2^16-1 }; oder wie war die Frage ?
Martin K. wrote: > Also erstmal vielen dank. naja als anfänger isses echt nicht einfach. da > ich so was wie töne erzeugen noch nie gemacht habe. ich weiß halt nich > wie ich das so richtig anstellen soll. > > also was ist CTC und OCR ? > hab davon noch nie was gehört. CTC continius timer counter also ein Timer im CTC mode OCR overflow counter register ? Atmel Datenblätter lesen, ja ich weiss ich frag auch immer so .... aber ich lese auch ab und an :-)))
Martin K. wrote: > Also erstmal vielen dank. naja als anfänger isses echt nicht einfach. da > ich so was wie töne erzeugen noch nie gemacht habe. ich weiß halt nich > wie ich das so richtig anstellen soll. Im einfachsten Fall ist ein Ton eine Rechteckschwingung. Also einfach nur Pin ein - Pin aus - Pin ein - Pin aus. Da (über eine kleine Verstärkerschaltung) einen Lautsprecher drann und du hast deinen Ton. Die Zeitabstände in denen du ein und ausschaltest sind die Tonfrequenz. -> Im Grunde ist 'einen Ton erzeugen' auch nichts anderes als 'eine LED blinken lassen'. Nur dass ein klein wenig schneller geschaltet wird. > > also was ist CTC und OCR ? > hab davon noch nie was gehört. Steht im Datenblatt beim Timer 1 dabei CTC Clear Timer on compare Der Timer wird bei erreichen eines bestimmten Zählerstandes automatisch auf 0 zurückgesetzt, wobei dieses Zurücksetzen als 'Overflow' gilt. OCR Output compare register Der Timer Wert wird mit dem Inhalt dieses Registers verglichen. Bei Gleichheit kann eine Aktion an einem bestimmten Pin ausgelöst werden. Wie oben schon gesagt: Die meiste Zeit wird für dich mit dem Studium des Datenblattes draufgehen.
In Assembler kannst du die sinustabelle natürlich mit db einfügen. Die Werte gibst du dann nacheinander auf einem Port aus an welchem ein R2R Widerstands Netzwerk hängt. Damit hast du einen Sinus, die Frequenz des Sinus bestimmst du über die Wartezeit zwischen den Ausgaben.
Da steht eigentlich alles was man zum Timer wissen muss: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr#Der_CTC_Modus_des_Timers
>Wartezeit
Sag sowas nicht, nachher baut Martin noch ne Warteschleife ;)
Einfach die daten in nem Interrupt aus dem Flash lesen (sinustabelle)
und dann auf einem Port ausgeben. So kann der µC nebenbei wenigstens
noch was anderes erledigen.
Mit nem tiefpass dahinter kann man schon relativ hochfrequente
Sinus"töne" erzeugen.
Wenn ich mich recht erinnere, gings doch im Original darum, dass ein Gerät eine Warnung in Form einer 'Sprachausgabe' ausgibt. Klingt natürlich cool, hat dich aber anscheinend überfordert. Die abgespeckte Variante lautet jetzt: Ein Ton tut es auch. Dass du diesen Ton (mit 30kHz) nicht hören kannst, spricht schon Bände über das Verständnis von Tönen, aber vielleicht ist die Warnung ja auch für einen Hund oder eine Fledermaus gedacht. Da es offenbar an Grundlagen sowohl im Bereich Audio als auch im Bereich AVR-Programmierung mangelt, schlage ich noch eine weitere Vereinfachung vor: Kauf dir einen Summer und häng ihn (mglw. über einen Transistor) an einen Portpin. Der Summer summt ganz von alleine, du musst ihn nur einschalten. Ist zwar nicht so cool, wie die ursprünglich angedachte Lösung, dafür aber auch mit kleinem Wissen machbar.
Karl heinz Buchegger wrote: > Wenn ich mich recht erinnere, gings doch im Original darum, > dass ein Gerät eine Warnung in Form einer 'Sprachausgabe' > ausgibt. Klingt natürlich cool, hat dich aber anscheinend > überfordert. > Die abgespeckte Variante lautet jetzt: Ein Ton tut es auch. > Dass du diesen Ton (mit 30kHz) nicht hören kannst, spricht > schon Bände über das Verständnis von Tönen, aber vielleicht > ist die Warnung ja auch für einen Hund oder eine Fledermaus > gedacht. > Da es offenbar an Grundlagen sowohl im Bereich Audio als > auch im Bereich AVR-Programmierung mangelt, schlage ich > noch eine weitere Vereinfachung vor: Kauf dir einen > Summer und häng ihn (mglw. über einen Transistor) > an einen Portpin. Der Summer summt ganz von alleine, du > musst ihn nur einschalten. > Ist zwar nicht so cool, wie die ursprünglich angedachte > Lösung, dafür aber auch mit kleinem Wissen machbar. Jo, hunde hast recht. ich werd aber versuchen es so zu machen. das will ich schon hinbekommen. Also wenn ich das mit der sinustabelle mache, bräuchte ich auch keinen timer, verstehe ich das jetzt richtig? Jetzt müsste ich nur noch wissen was in diese sinustablle muss. und wo bekomme ich einen tiefpass her / kann ihn bauen? müsste ich bei der tabelle vor jeder zeile/spalte ein db einfügen?
> Mit nem tiefpass dahinter kann man schon relativ hochfrequente > Sinus"töne" erzeugen. Auch irgendwie paradox .... hohe Töne mit nem Tiefpass ..... SCNR
Martin K. wrote: > Also wenn ich das mit der sinustabelle mache, bräuchte ich auch keinen > timer, verstehe ich das jetzt richtig? > Jetzt müsste ich nur noch wissen was in diese sinustablle muss. > > und wo bekomme ich einen tiefpass her / kann ihn bauen? > > müsste ich bei der tabelle vor jeder zeile/spalte ein db einfügen? @Hauke @Christian Ich geh schon mal Popcorn holen. Bin schon gespannt wie ihr ihn da durchbringt :-)
Naja n Tiefpass besagt ja nur, dass vergleichsweise tiefe frequenzen durchgelassen werden. Hier geht es eben darum, dass wenn man nur Wenige stützstellen für die Sinuskurve hat (z.b. 16) man immer noch einen schönen Sinus dabei rausbekommt, indem man eben nahe der Frequenz des Sinustons filtert um nicht irgend ein stufiges irgendwas sondern einen schönen Sinus zu bekommen. Aber wenn du Hunde "ärgern" willst dann tuts ein Rechteck vielleicht sogar noch besser da der durch die Oberwellenanteile (steilen Flanken) sehr viel "nerviger" ist. Aber hier mal ein Rezept: Für Eine Sinusausgabe nehme man: - Einen (am besten CTC fähigen) Timer - eine Sinustabelle (mit gewünschter auflösung) - Einen Pointer auf die Sinustabelle - Ein R2R netzwerk an einem Port Ich gehe jetzt mal von 16 MHz Takt aus und 16 Werten in der Sinustabelle, ist nicht viel sollte aber hierfür ausreichend sein) Jetzt stellt man den Timer so ein, dass man einen Interrupt mit sagen wir mal 500kHz frequenz bekommt ( Bei nem CTC timer: CTC wert auf 31 stellen, Prescaler = 1) Man Initialisiert den Pointer auf den Anfangspunkt der Sinustabelle. Im interrupt läd man jetzt aus der Sinustabelle einen Wert und gibt ihn auf dem Port aus, an dem das R2R netzwerk angeschlossen ist. Danach erhöht man den Counter um eins und prüft ob er größer als Startadresse der Sinustabelle +16 ist, wenn ja setzt man den Pointer wieder auf die Startadresse. Jetzt noch was zum Tiefpass: Ein Tiefpass ist im einfachsten Fall eine Kombination aus einem Widerstand und einem Kondensator. Eine Seite vom Widerstand an die quelle, die andere Seite an den "Ausgang" und am ausgang noch einen Kondensator. http://de.wikipedia.org/wiki/Tiefpass#Tiefpass_1._Ordnung Da du nach einem R2R netzwerk aber sowieso einen Opamp brauchst, da der Widerstand des Netzwerks viel zu hoch ist um damit einen Lautsprecher zu treiben kannst du den Tiefpass direkt mit dem Opamp erledigen: http://de.wikipedia.org/wiki/Tiefpass#Tiefpass_2._Ordnung Bild: Aktiver Tiefpass 2. Ordnung Da Opamps aber selten mit Induktiven Lasten wie Lautsprechern zurechtkommen brauchst du danach noch eine "Endstufe", im einfachsten Fall wider mal nur ein Transistor. Jetzt das ganze noch schön mit nem Kondensator entkoppeln (lautsprecher mögen nicht so gerne DC)und fertig ist das ganze. Aber ob sich der Aufwand lohnt nur um ein paar Hunde zu nerven? Einfacher gehts wohl so: Timer auf 60kHz stellen und einen Pin bei jedem interrupt toggeln, dann damit auf das Gate von einem logic level fet (ja ja ok vielleicht noch nen widerstand von 10 Ohm daziwischen zur sicherheit), Source an Masse, Drain über Kondensator an Lautsprecher, Lautsprecher an Spannungsquelle. Wenn du jedoch ein großes gebiet beschallen möchtest reicht diese einfache methode nicht mehr aus, da muss man sich dann was passendes überlegen. PS: Wie erstelle ich eine Sinustabelle: Bei 16 Werten kann man das zur not noch manuell machen: Man nehme Sinusfähigen taschenrechner und tippe nacheinander ein: sin( x/15*360 )*127 +127 Wobei x bei jedem schritt um eins erhöht wird. (Bei Fragen zur Sinusfunktion Ihres Taschenrechners sehen Sie im Handbuch nach oder fragen Sie ihren Taschenrechnerfachverkäufer) nachher könnte das ganze so aussehen: .db 127, 179, 221 , 248, ... Jetzt kommen sicher wieder die leute die einem erzählen, dass man nur einen Teil der Sinustabelle braucht da man durch spiegeln etc des ersten viertels die gesammte kurve rekonstruieren kann. Aber der Aufwand lohnt sich hier wohl nicht, da es so einfacher zu verstehen ist und was sind schon 16 Byte ;)
Martin K. wrote: > Karl heinz Buchegger wrote: >> ist die Warnung ja auch für einen Hund oder eine Fledermaus >> gedacht. > Jo, hunde hast recht. achso..... dann muss es natürlich nicht so sauber synthetisiert werden.... man soll auch jugendliche damit verschäuchen können, hab mal einen Bericht ge sehen/lesen mit High Power 20-25 kHz speaker vor dem Supermarkt, die "alten" hören das nicht mehr und die "jungen" haben keinen bock mehr vor dem Eingang rumzulümmeln :-))))
Ein Tiefpaß braucht man eigentlich immer wenn man eine D/A-Wandlung macht. Eine Abtastung im Zeitbereich bedeutet ja das sich das Spektrum im Frequenzbereich mit der Abtastfrequenz wiederholt. Zur Rekonstruktion muß man die 0. Wiederholung per "Tiefpaß" ausschneiden. Ist z.B. hier beschrieben: http://axes.informatik.uni-leipzig.de/~graichen/abtastungprint.pdf
Hauke Radtki wrote: > Einfacher gehts wohl so: Timer auf 60kHz stellen und einen Pin bei jedem > interrupt toggeln, dann damit auf das Gate von einem logic level fet (ja > ja ok vielleicht noch nen widerstand von 10 Ohm daziwischen zur > sicherheit), Source an Masse, Drain über Kondensator an Lautsprecher, > Lautsprecher an Spannungsquelle. Wenn du jedoch ein großes gebiet > beschallen möchtest reicht diese einfache methode nicht mehr aus, da > muss man sich dann was passendes überlegen. Vielen dank für die sehr ausführliche antwort. Also ich werde wohl die einfachere variante machen, obwohls och nicht gerade einfach klingt. also: was heißt toggeln? Gate von einem logic level fet??? Wie kann ich den Timer auf 30KHz stellen??? Das ist halt irgendwie so, das ich die zeitabstände so klein einstellen muss, wie groß müssten die dann sein?
>was heißt toggeln? Wechsel wwischen zwei (Schalt-)Zuständen >Gate von einem logic level fet??? Ein FET besitzt i.d.R. drei Anschlüsse, und einer davon heisst "Gate". >Wie kann ich den Timer auf 30KHz stellen??? Das ist halt irgendwie so, >das ich die zeitabstände so klein einstellen muss, wie groß müssten die >dann sein? Lerne Rechnen (1-durch ist schon sehr wichtig) und verstehe (lies), was oben geschrieben wurde.
toggeln --> ja, ok war ne dumme frage Fet --> ist ein Transistor, verstanden Timer --> Achso, den gibt man wohl in herz an/ kann man so einstellen. ok ich werde jetzt erstmal schauen, wie ich die timer einstellen kann.
Nö, den stellst du nicht in Herz ein, wenn nur in Hertz, aber nicht mal das. Du stellst nur einen Zähler ein mit einem Wert, den du für die gewünschte Frequenz berechnen musst.
Hallo, Vielleicht ist das eine gute Lektüre für Dich http://www.avr-asm-tutorial.net/avr_de/avr_dac.html Gruß Sebastian
Rüdiger Knörig wrote: > Ein Tiefpaß braucht man eigentlich immer wenn man eine D/A-Wandlung > macht. Eine Abtastung im Zeitbereich bedeutet ja das sich das Spektrum > im Frequenzbereich mit der Abtastfrequenz wiederholt. Zur Rekonstruktion > muß man die 0. Wiederholung per "Tiefpaß" ausschneiden. > Ist z.B. hier beschrieben: > http://axes.informatik.uni-leipzig.de/~graichen/abtastungprint.pdf Prinzipiell gebe ich dir Recht, aber manchmal kann man den auch wegen seiner Schlampigkeit weglassen. Zum Beispiel wenn man einen Lautsprecher dranhängt, der nur einen Warnton geben soll. Zumindest sehe ich das so :D @Martin: Beim Timer stellt man nicht die Frequenz ein. Zumindest nicht direkt. Geht ja auch garnicht denn: Willst du eine Frequenz erzeugen, so brauchst du erstmal eine Taktquelle. In unserem Fall ist die Taktquelle der Takt des Mikroprozessors (zB Quarz, oder interner RC Oszillator). Daraus lässt sich schonmal schließen, dass die erzeugte Frequenz nicht genauer sein kann, als die Mikroprozessorfrequenz. Weiter im Text: Der Timer-einheit gibst du nur einen Teilwert vor, nachdem sie ihre eigenen Register inkrementiert/dekrementiert/weißderkuckuckwasmacht. Abhängig von diesen Timer-registern lassen sich verschiedne Timermodi einstellen. Zum Beispiel der "normale" Overflow-modus: Ein Timerregister wird mit dem Mikrocontrollertakt geteilt durch den Teilerwert inkrementiert. Läuft dieses über, geschieht ein Interrupt. Stell dir vor, du würdest der Timer-einheit eine Frequenz vorgeben. Dann müsste diese Einheit erstmal herausfinden, durch was sie den Mikroprozessortakt teilen muss, um diese Frequenz zu erhalten -> Viel zu kompliziert für diese Einheit.
Wenn du z.b. einen Haupttakt von 16MHz hast, und du interrupt frequenz von 60kHz willst, müsste alle 266,66666.... Takte der Timer überlaufen. Der Timer geht aber nur bis 256. Naja auch nicht schlecht ist ja relativ nah dran. Kurz nachgerechnet: 16M/256 = 62500 62500/2 ergibt 31250 das ist doch schon ganz schön nah an den gewollten 30kHz. Also nimmst du einfach einen 8 bit timer (timer0 vom mega8 z.b.) und lässt ihn einfach mit dem systemtakt laufen (prescaler = 1) Jetzt schaltest du noch den overflow interrupt ein und du hast deinen interrupt mit ca 60kHz. Jetzt toggelst du einen Pin der am Gate vom Fet hängt und fertig ;) So jetzt bin ich erst ma Grillen, viel spass beim Grübeln ;)
Leute, Leute - erst Grundlagen aneignen, dann mit dem Basteln anfangen. Ich kann den Thread hier kaum ertragen :-) Man stelle sich mal vor, Ärzte würden so arbeiten: "Kann ich ein normales Küchenmesser nehmen oder doch ein Skalpell? ... Leute helft mir, der blutet so stark, was mach ich jetzt..." :-)))
OK, also vielen Dank an alle die mir hier weitergeholfen haben. Jetzt müsste ich es wirklich hinbekommen. Also vielen Dank!!!
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.