Forum: Mikrocontroller und Digitale Elektronik Ton mit ca 30.000 Herz mit atmega8 erzeugen


von Martin K. (spyro07)


Lesenswert?

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?

von Matthias (Gast)


Lesenswert?

ja, du dir selbst:

Du hörst auf, irgendwelchen fertigen Code zu suchen, und:

SCHREIBST IHN EINFACH SELBST ;-)

von Auch einer (Gast)


Lesenswert?

1,667µs high  1,667µs low dann sind es 30KHz
 Periodendauer 3,3333333µs

von Erik S. (erik_s)


Lesenswert?

30kHz und Ton.... ich weiß ja nicht wozu du diese Anwendung brauchst, 
aber hören wirst du diesen Ton wohl eher nicht.

von Auch einer (Gast)


Lesenswert?

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

von Auch einer (Gast)


Lesenswert?

Es ist eine Fledermaus.

von Karl H. (kbuchegg)


Lesenswert?

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)

von Joachim B. (jar)


Lesenswert?

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 ;-)

von Auch einer (Gast)


Lesenswert?

>in C importieren und Zeilenende Datentrenner setzen

wie geht das?

von Martin K. (spyro07)


Lesenswert?

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

von Joachim B. (jar)


Lesenswert?

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 ?

von Joachim B. (jar)


Lesenswert?

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 :-)))

von Karl H. (kbuchegg)


Lesenswert?

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.

von Christian U. (z0m3ie)


Lesenswert?

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.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Da steht eigentlich alles was man zum Timer wissen muss: 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Uhr#Der_CTC_Modus_des_Timers

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

>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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Martin K. (spyro07)


Lesenswert?

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?

von Michael K. (mmike) (Gast)


Lesenswert?

> Mit nem tiefpass dahinter kann man schon relativ hochfrequente
> Sinus"töne" erzeugen.

Auch irgendwie paradox .... hohe Töne mit nem Tiefpass .....

SCNR

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

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 ;)

von Joachim B. (jar)


Lesenswert?

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 :-))))

von Rüdiger K. (sleipnir)


Lesenswert?

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

von Martin K. (spyro07)


Lesenswert?

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?

von Rahul D. (rahul)


Lesenswert?

>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.

von Martin K. (spyro07)


Lesenswert?

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.

von Timo (Gast)


Lesenswert?

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.

von Sebastian M. (izaseba)


Lesenswert?

Hallo,
Vielleicht ist das eine gute Lektüre für Dich

http://www.avr-asm-tutorial.net/avr_de/avr_dac.html

Gruß Sebastian

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von Hauke R. (lafkaschar) Benutzerseite


Lesenswert?

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 ;)

von Winfried (Gast)


Lesenswert?

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..." :-)))

von Martin K. (spyro07)


Lesenswert?

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
Noch kein Account? Hier anmelden.