Guten Tag,
mein Programm(siehe unten) sollte mit einen an Port P2.0 angeschlossenen
Lautsprecher Töne erzeugen. Allerdings besitzte der "Ton" in allen
Fällen nur eine niedrige, nicht als Ton definierbare Frequenz. Nach
ausprobieren müsste der Fehler in der ISR von T0 liegen. Könnt ihr mir
weiterhelfen?
Earth S. schrieb:> mein Programm(siehe unten) sollte mit einen an Port P2.0 angeschlossenen> Lautsprecher Töne erzeugen. Allerdings besitzte der "Ton" in allen> Fällen nur eine niedrige, nicht als Ton definierbare Frequenz. Nach> ausprobieren müsste der Fehler in der ISR von T0 liegen. Könnt ihr mir> weiterhelfen?
Marc V. schrieb:> mov A,R0 ;* R0 ist 255 beim ersten Einsprung
Du rufst erst zweimal den inc Befehl im Ext. Interrupt auf, bevor du den
Timer startest dann ist dieser beim Einsprung 1
Earth S. schrieb:> Du rufst erst zweimal den inc Befehl im Ext. Interrupt auf, bevor du den> Timer startest dann ist dieser beim Einsprung 1
Sorry, übersehen, dachte Timer startet von alleine.
Du weisst aber, dass die Werte als Big Endian gelesen werden und
erster Wert nur 0xFF ist ?
Marc V. schrieb:> Sorry, übersehen, dachte Timer startet von alleine.> Du weisst aber, dass die Werte als Big Endian gelesen werden und> erster Wert nur 0xFF ist ?
Und jetzt bitte noch für einen dummen Schüler erklärt?
Marc V. schrieb:> Wo habe ich das behauptet ?> Egal, ich bin raus.
ich bin ein Schüler, ich hab mich selbst als dumm bezeichnet.
Was wolltest du mit deiner Aussage erklären? Ich verstehe das nämlich
nicht so ganz
Earth S. schrieb:> ich bin ein Schüler, ich hab mich selbst als dumm bezeichnet.>> Was wolltest du mit deiner Aussage erklären? Ich verstehe das nämlich> nicht so ganz
Hab es aber anders verstanden, deswegen.
Big Endian in deinem Fall heisst, dass zuerst Wert für TH steht und
dann der Wert für TL.
Little Endian heisst, es steht zuerst der Wert für TL und erst dann
der Wert für TH.
Da du zuerst TH lädst, wird der mit 0 geladen und TL dann mit 255.
ein paar Kommentare hätten der Lesbarkeit deines Codes nicht geschadet.
Was machst du mit Timer 1? Du lädst ihn vor auf seinen Maximalwert, so
dass er sofort überläuft und in seine ISR springt. Das passiert 40 mal,
und danach hältst du in der ISR_T1 deinen Timer 0 an, so dass beide
Timer stoppen und damit auch der Lautsprecher nicht mehr angeseteuert
wird (bis zum nächsten Tastendruck).
Ist das Absicht oder lese ich den Code falsch?
Achim S. schrieb:> ein paar Kommentare hätten der Lesbarkeit deines Codes nicht geschadet.>> Was machst du mit Timer 1? Du lädst ihn vor auf seinen Maximalwert, so> dass er sofort überläuft und in seine ISR springt. Das passiert 40 mal,> und danach hältst du in der ISR_T1 deinen Timer 0 an, so dass beide> Timer stoppen und damit auch der Lautsprecher nicht mehr angeseteuert> wird (bis zum nächsten Tastendruck).>> Ist das Absicht oder lese ich den Code falsch?
Eigentlich war genau das Gegenteil Erwünscht, Dankeschön
Jetzt habe ich das geändert, die Ausgabezeit stimmt jetzt.
aber das, was ausgegeben wird ist mehr oder weniger ein knacken;
Hilft es wenn ich die Timer(0)reloadwerte in 2 register schiebe und
diese dann immer daraus lade?
Earth S. schrieb:> Guten Tag,> mein Programm(siehe unten) sollte mit einen an Port P2.0 angeschlossenen> Lautsprecher Töne erzeugen.
Was für ein Lautsprecher? Gewöhnlich kann so ein Port keinen
Lautsprecher
treiben.
Earth S. schrieb:> Ich verstehe das nämlich> nicht so ganz
Du hättest dich schon in deinem Eingangsthread als Schüler outen sollen.
Einem Schüler erklärt man einen Sachverhalt ganz anders, als einem,
sagen wir mal, Erfahrenen.
Earth S. schrieb:> Hilft es wenn ich die Timer(0)reloadwerte in 2 register schiebe und> diese dann immer daraus lade?
ob du die Reloadwerte aus 2 Registern lädst oder ob du sie vom dptr
liest ist egal. Wenn dein 8051 einen Timer 2 besitzt, kannst du den auch
im Auto-Reload laufen lassen.
Interessanter ist, ob die Reload-Werte richtig sind. Auch der Kommentar
von nemesis ist wichtig: ein normaler Portpin kann keinen Lautsprecher
treiben, und beim 8051 ist das erst recht der Fall, weil der
Higshside-Treiber (bis auf ein paar µs bei der Schaltflanke) hochohmig
ist. Also: wie sieht deine Hardware aus?
Zur Wahl deiner Reload-Werte: die ergeben alle recht seltsame
Frequenzen. Beispiel:
Earth S. schrieb:> DB 00001110b, 11101000b ;c3
Soll damit 0x0E in TH0 und 0XE8 in TL0 geladen werden? Falls ja, dann
erzeugt das den Timerüberlauf nach 61,7ms (sofern dein 8051 mit 12MHz
getaktet ist). Wenn du in den Zeitabständen den Portpin invertierst gibt
es einen Ton von ~8Hz - also nichts hörbares.
Wahrscheinlich wolltest du eher 260Hz treffen. Dann musst du den
Reloadwert aber auf 0x10000 - 0x0EE8 setzen, nicht auf 0x0EE8 (der Timer
zählt aufwärts, nicht abwärts).
Außerdem behandelst du den Index auf deine Notentabelle nicht richtig.
Warum initialisiert du R0 auf 255? Lass es bei 0 loslaufen, mit 255
zeigt es auf einen Speicher, der nicht definiert ist.
Auch das das dec R0 und inc R0 erscheinen mir falsch. Wenn du R0 als
Index verwenden willst, dann muss es entweder in Zweierschritten hoch-
und runterzählen. (weil jede Note zwei Byte belegt).
Oder du zählst R0 in Einserschritten und machst die Verdopplung des
Zeigerst beim Auslesen.
Also ungefähr so:
;index der Note (0..7) steht in R0
mov DPTR,#tcode
mov A,R0
rl A ;Offset für High-Byte ist 2*Index
movc A,@A+DPTR
mov TH0,A
mov A,R0
rl A
inc A ;Offset für Low-Byte ist 2*Index+1
movc A,@A+DPTR
mov TL0,A
Das nächste Problem ist, das der Timer ja genau nur eine Periode
durchläuft und dann schon der nächste Wert kommt. Das gibt aber keinen
Ton, selbst wenn die Reloadwerte richtig wären, denn dazu muss man mehr
als eine halbe Periode eines Tons spielen.
Bei einem z.B. 60er Beat ist die Tonlänge ohne Pause ja 1 Sekunde lang.
Du musst also für einen Ton mit 250 Hz den Timer 250 mal durchlaufen
lassen, um einen Ton von einer Sekunde Länge zu bekommen.
Achim S. schrieb:> Soll damit 0x0E in TH0 und 0XE8 in TL0 geladen werden? Falls ja, dann> erzeugt das den Timerüberlauf nach 61,7ms (sofern dein 8051 mit 12MHz> getaktet ist). Wenn du in den Zeitabständen den Portpin invertierst gibt> es einen Ton von ~8Hz - also nichts hörbares.>> Wahrscheinlich wolltest du eher 260Hz treffen. Dann musst du den> Reloadwert aber auf 0x10000 - 0x0EE8 setzen, nicht auf 0x0EE8 (der Timer> zählt aufwärts, nicht abwärts).
Das könnte das bereits erwähnte "knacken" erklären.
Danke dafür
ich probiere es morgen früh mal aus und kann mich ja dann nochmal melden
:)
Matthias S. schrieb:> Das nächste Problem ist, das der Timer ja genau nur eine Periode> durchläuft und dann schon der nächste Wert kommt.
ich glaube nicht: R0 (der Ton) wird zwar in der ISR_T0 decrementiert,
danach aber auch wieder incrementiert, so dass weiter der selbe Ton
kommt. Die Tonlänge soll wohl über Timer1 eingestellt werden, wobei sich
oben schon gezeigt hat, dass das falsch gelöst war.
Ein neuer Ton kommt imho nur als Reaktion auf einen externen Interrupt
zustande (also wohl bei Tastendruck). Dann wird sowohl in der Ext-ISR
als auch in der daraus aufgerufenen Routine zur Siebensegmentanzeige der
Wert von R0 (also die Note) verändert - was allerdings ebenfalls eine
ziemlich unübersichtliche Geschichte ist.
Reinhard D. schrieb:> ich probiere es morgen früh mal aus und kann mich ja dann nochmal melden
Bist du der Thread-Opener und jetzt unter anderem Namen unterwegs? Danke
für die Verwirrung.
Wie schauts mit der Frage nach der Hardware aus?
Reinhard D. muss wohl mein Projektpartner gewesen sein.
Entschuldigung für die Verwirrung
Aber durch setzen von Timer 1 auf 0 und umkehren der Frequenzen läuft
jetzt alles wie gewünscht.
Danke an meine Helfer Achim S., Matthias Sch.