Hallo,
ich versuche mit einem Tiny15 das PWM-Signal auf drei LED zu
multiplexen.
In der Simulation macht auch alles schön das, was es soll. Aber im
Controller passiert am Pin PB0 gar nichts.
Durch rumexperimentieren habe ich festgestellt, dass wenn ich den Code
isoliere (LED_MUX) wird es ausgeführt; im Gesamtkonstrukt aber nicht.
Eine echte Logik konnte ich aber nicht entdecken.
Also interessant ist die Subroutine LED_MUX, da stimmen Simulation und
Wirklichkeit nicht überein.
Haut es da irgend ein Register/Stack durcheinander??`
Kann mir jemand helfen??
Danke vorab!
Nachtrag: Ich habe gerade nochmal das Signal mit dem Scope angeschaut:
Der Pin hängt auf ca. UB/2 ?! (ist dabei herausgebogen, also mit nichts
verbunden). Andere Tiny machen das gleiche => HW-Fehler ausgeschlossen
Der Code
Du hast mehrere Interrupts freigegeben, für die kein Handler existiert.
Wenn z.B. der Timer 0 Overflow auftritt, gibts nen kompletten Reset,
weil hinter dem nop im Vektor nicht ausführbarer Code steht!
> sei> reti ;Rücksprung aus Interrupthandler
Das sei hat da nichts zu suchen, das steckt im reti schon mit drin!
EDIT:
sehe grad, dass die Interrupts nicht freigegeben sind. War durch die
(blödsinnige) Schreibweise mit dem "0 << TOIE0" durcheinander
gekommen...
Hier
> out OCR1B,WRegister> ldi WRegister,0xFF ;PWM-Frequenz
ist erst mal die Reihenfolge vertauscht. Könnte mitschuld
an deinem Problem haben.
Das hier
> .org $000>> rcall Init> rjmp Main
ist keine gute Idee. Das rjmp Main steht bereits an einer
Stelle, an der eigentlich ein Interrupt Vektor im Speicher
steht. Kein AHnung welcher. Das müsste man im Datenblatt
nachsehen. Gut. Momentan wird dieser Interrupt Vektor nicht
benutzt und ist somit kein Problem. Aber wie du eine rcall
ausführen willst, ohne zuvor den Stackpointer gesetzt zu haben
ist mir nicht klar. Oder hat der Tiny15 auch dieses besch...
3 Stackadressen Spezialfeature, wie es der Tiny12 hat?
(muss gleich mal nachsehen)
Das macht mich jetzt etwas stutzig
In der Init
> ;ADC> ldi
WRegister,(1<<ADEN)|(1<<ADSC)|(1<<ADFR)|(0<<MUX2)|(1<<MUX1)|(0<<MUX0)
> out ADCSR,WRegister
in der Helligkeit_einstellen:
> ldi WRegister,(0<<MUX2)|(1<<MUX1)|(1<<MUX0)|(1<<ADEN)|(1<<ADSC)|(1<<ADFR)> out ADMUX,WRegister ; ADC auf Potieingang stellen
Beides mal sind es dieselben Bits. Aber einmal schreibst du sie
ins ADCSR Register und das andere mal ins ADMUX. Was stimmt denn
nun?
> out ADMUX,WRegister ; ADC auf Potieingang stellen> in RDummy,ADCH
So schnell ist der ADC nun auch wieder nicht. Man sollte schon
auch abwarten, bis der ADC ein Wandlerergebnis fertig hat.
Stackpointer habe ich auch schon vermutet, aber wie funzt das...
Die OCR1B initialisierung habe ich angepasst, erwartungsgemäß hat sich
nichts geändert. Es wäre halt nur eine falsche Freqeunz eingestellt,
wobei dies zweitrangig ist.
@Johannes
was spricht gegen die "0 << TOIE0"-Schreibweise? Auf einen Blick sieht
man sofort, ob und wie das Bit gesetzt ist?!
Timo wrote:
> was spricht gegen die "0 << TOIE0"-Schreibweise? Auf einen Blick sieht> man sofort, ob und wie das Bit gesetzt ist?!
Die Zeilen werden so lang, dass du vor lauter Ausdrücken erst recht
nicht mehr siehst, welche denn jetzt zu einem 1 Bit führen.
ups, zu schnell...
;ADC
ldi WRegister,(1<<REFS1)|(1<<REFS0)|(1<<ADLAR) ;mit ADLAR links
reicht das HB zur Steuerung aus
out ADCSR,WRegister
so muß es heißen.
Aber der ADC ist momentan nicht in Gebrauch (kommt noch...) und sollte
doch auch ein anderes Schlachtfeld sein.
Timo wrote:
> ups, zu schnell...>> ;ADC>> ldi WRegister,(1<<REFS1)|(1<<REFS0)|(1<<ADLAR) ;mit ADLAR links> reicht das HB zur Steuerung aus> out ADCSR,WRegister>> so muß es heißen.> Aber der ADC ist momentan nicht in Gebrauch (kommt noch...) und sollte> doch auch ein anderes Schlachtfeld sein.
Ist schon klar.
Ist mir nur beim drüberlesen aufgefallen. Bis jetzt habe ich
das Programm nur noch formalen Gesichtspunkten untersucht ohne
gross auf die Funktionalität oder Logik zu achten.
Bist du sicher, dass dieser PWM Modus einen Overflow
Interrupt auslöst. Da das ganze doch auf den OCR Registern
basiert, sollte das doch eigentlich ein Compare Match Interrupt
sein.
Hilft nichts, muss ich mir doch mal das Datenblatt zum Tiny15
holen.
PS: Dem Simulator darfst du in solchen Dingen nicht unbedingt
trauen. Der hat gerade bei Timern und PWM so seine Eigenheiten.
Also mit der PWM-Erzeugung habe ich jetzt weniger Zweifel, das dies an
sich funktioniert - das Signal wird ja ausgegben. Nur eben PB0 macht mir
Sorgen...
Timo wrote:
> Also mit der PWM-Erzeugung habe ich jetzt weniger Zweifel, das dies an> sich funktioniert - das Signal wird ja ausgegben. Nur eben PB0 macht mir> Sorgen...
<Noch mal nachgelesen>
ooops. Da hab ich deine Frage misverstanden.
Timo wrote:
> ISP-Programmer ist abgezogen.
Gut.
> Wenn es einen HW-Stack gibt, dann brauche ich mich ja darum nicht zu> kümmern!?
Richtich! Allerdings schon isofern, als dass es nur drei Stack Level
gibt und dementsprechend geschachtelte Funktionen (inkl. Interrupt
Handler!) sehr wohl-überlegt eingesetzt werden sollten. Dürfte in Deinem
Fall allerdings noch problemlos gehen.
Um ehrlich zu sein: Ich bin mit meinem Latein am Ende.
Auch das Datenblatt gibt nicht mehr her.
Ohne einen Tiny15 hier zu haben, wird das wohl nichts mit
der weiteren Fehlersuche.
Einen hab ich noch: Schmeiss mal das ganze Gerödel mit dem ADC
raus. Ich weiss schon, an PB0 liegt eigentlich der Analog
Comperator, sollte daher nichts mit dem ADC zu tun haben.
Aber um Fehlersuche zu betreiben hilft wohl nur noch konsequentes
Abspecken des Codes.
Karl heinz Buchegger wrote:
> Um ehrlich zu sein: Ich bin mit meinem Latein am Ende.> Auch das Datenblatt gibt nicht mehr her.
Nicht nur Du...
@Timo:
Hast Du mal versucht, den Pin (ohne den ganzen Timer-Kram) mal
anzusprechen?
tja...
ich habe abgespeckt und alles was mit dem ADC zu tun hat
rausgeschmissen.
Damit funktioniert die Multiplexerfunktion.
Die Ursache hat wohl was mit dem ADC zu tun, was den Simulator aber
offensichtlich nicht stört.
Das "was" ist allerdings noch offen! Da muß doch noch irgend wo ein
Fehler sein?
Der Code ohne jegliche ADC-Unterstützung sieht damit jetzt so aus
Hallo,
sorry für's Bildformat - ich dachte ich tu was gutes....
Ich habe den "Fehler" gefunden.
Nachdem ich alle ADC-Anweisungen rausgeschmissen hatte, ging es ja. Da
habe ich mir die Registerwerte nochmal genauer angesehen und korrigiert
- und siehe da, es geht!
Ich finde es nur komisch, wie durch falsche Initialisierung ganz andere
Stellen des Controllers beeinflusst werden -zumal das eine mit dem
anderen scheinbar nichts zu tun hat.
Der Komplettcode nochmals im Anhang.
Gruß
Timo