Seltsame Effekte am Attiny2313

J

Johannes Bauer

Guest
Hallo Gruppe,

ich habe gerade etwas merkwürdiges mit einem meiner ATtiny2313s
festgestellt: für eine Sekundenanzeige habe ich eine zweistellige
Siebensegmentanzeige verwandt. Da der Tiny (fast) nichts macht, ewig
viel Flash und Portpins verfügbar hatte und ich gerade keinen 7447 zur
Hand hatte, kam mir eine grandiose (?) Idee: ich habe alle Kathodenpins
über Vorwiderstände an sieben Portpins geschaltet. Die zwei Anodenpins
direkt an Portpins. Dann wollte ich die einzelnen Leuchtsegmente
multiplexen (also nicht nur die ganze Anzeige, sondern wirklich die
einzelnen Segmente). Dass ich dafür die Vorwiderstände auch an die
Anodenleitungen hängen hätte können ist mir erst später aufgefallen...
aber naja.

Das ganze funktioniert auch einigermaßen gut, aber wenn ich
beispielsweise so eine Verzögerungsschleife einbaue:

void delay(unsigned char how) {
unsigned char x, y, z;
for (x=0; x<=how; x++) {
for (y=0; y<=how; y++) {
for (z=0; z<=how; z++) {
asm volatile("nop");
}
}
}
}

Und die Aufrufe, geht das Display aus! Wenn ich die Zahlen von 0-9
hochzählen lasse, wird die 0, die 2 und die 8 korrekt dargestellt, der
Rest ist Murks (also ganz "merkwürdige" Zeichen). Alle Ziffern einzeln
stellen sich korrekt dar.

Außerdem habe ich bemerkt, dass wenn ich eine derartige Schleife mache:

Display_Left();
while (1) {
Display_Single(5);
}

Die "5" korrekt im linken Display angezeigt wird. Aber diese Schleife:

while (1) {
Display_Left();
Display_Single(5);
}

Zeigt die 5 in der linken Displayhälfte an und schwach - ca. 20%
Dutycycle - auch in der rechten!

Woran kann das liegen? Bin für alle Hinweise dankbar.

Viele Grüße,
Johannes
 
Johannes Bauer schrieb:

Zeigt die 5 in der linken Displayhälfte an und schwach - ca. 20%
Dutycycle - auch in der rechten!

Woran kann das liegen? Bin für alle Hinweise dankbar.
Es könnte daran liegen, dass du kein Konzept hast.

Viele Grüße,
Johannes
Dafür nich,
Jens
 
Display_Single(5);

Zeigt die 5 in der linken Displayhälfte an und schwach - ca. 20%
Dutycycle - auch in der rechten!

Woran kann das liegen? Bin für alle Hinweise dankbar.
Ich kann Dir zumindest sagen, weshalb Du keine vernünftigen Antworten
bekommen wirst (auch wenn mein Vorposter vielleicht lieber im
Heise-Forum spielen gehen sollte): Keiner kennt den Inhalt Deiner
ominösen "Display_Single"-Funktion, daher wird's schwer mit dem
Antworten. Dir sei verziehen, wenn Du irgendwelche fertigen Umgebungen
vewendest, die zufällig die 7-Segment-MPX-Funktion mitbringen, dann
müsstest Du das aber erwähnen. So gehe ich davon aus, dass Du Dir eine
Funktion gebastelt hast, uns nicht verrätst, wie sie aussieht und
fragst, warum sie nicht das tut, was Du willst.
Zu der Verzögerung: wo hast Du die Verzögerung eingebaut? An den
Anfang, hinter ne Endlosschleife, mitten in die Multiplexroutine? Ich
vermute Letzteres, vielleicht auch unbewusst. Sei Dir bitte im Klaren
darüber, dass auf Deinem AVR kein Multitasking-OS läuft, wenn Du das
Multiplexing nicht sauber mit Interrupts löst, wird jede Programmzeile
Einfluss auf das Displaytiming und damit auf Helligkeit (bis runter zu
ganz dunkel...) haben!
 
Stefan Huebner wrote:
Display_Single(5);

Zeigt die 5 in der linken Displayhälfte an und schwach - ca. 20%
Dutycycle - auch in der rechten!

Woran kann das liegen? Bin für alle Hinweise dankbar.

[...]
So gehe ich davon aus, dass Du Dir eine
Funktion gebastelt hast, uns nicht verrätst, wie sie aussieht und
fragst, warum sie nicht das tut, was Du willst.
Ja, du hast Recht. Tut mir leid, es war gestern... spät.

Die Funktion selber ist recht unspektakulär. Im Prinzip hängen an PD0
und PD1 die Anoden der 7-Segementanzeige (die ich als Stromsenke
benutze, DD ist Output) und an PB0-PB4 sowie PD5 und PD6 über
Widerstände die einzelnen Segemente. Pro aktivem Segment fließt ca. 1mA
Strom.

In der momentanen Programmvariante setzt Display_Left PD0 auf "1" und
PD1 auf "0":

PIND &= ~(1<<PD1);
PIND |= (1<<PD0);

Display_Right macht genau das umgekehrte (PD0 auf "0" und PD1 auf "1"
setzen).

Außerdem habe ich das Segmentmultiplexing noch nicht implementiert und
zeige momentan einfach alle Segmente (also nicht nacheinander an).
Display_Single(5) zieht also in dem Beispiel diejenigen 5 von 7
Segmenten auf "1", die in der fünf vorkommen (bei mir nenne ich diese
Segmente 1, 3, 4, 6, 7 und die hängen an PD5, PB3, PB0, PB1, PB2).

Also ziemlich primitiv bisher.

Was mich eben gewundert hat: ich habe noch gar kein Multiplexing
implementiert und schon funktioniert's nicht (zumindest bei der
Verzögerungsschleife).

Zu der Verzögerung: wo hast Du die Verzögerung eingebaut? An den
Anfang, hinter ne Endlosschleife, mitten in die Multiplexroutine? Ich
vermute Letzteres, vielleicht auch unbewusst.
Naja, wiegesagt, Multiplexen macht's noch nicht. Bisher sieht alles eben
so aus (Pseudocode jetzt):

PD1 = 0
PD0 = 1
while (1) {
// Die Segmente für die "5"
PD5 = 1
PB3 = 1
PB0 = 1
PB1 = 1
PB2 = 1

// Der Rest
PB4 = 0
PD6 = 0

// Jetzt verzögern
Delay(1 sec.)
}

Und im Delay fällt das Display aus. Mir ist's nur aufgefallen, weil ich
immer eine Sekunde verzögern wollte und dann eben die nächste Ziffer
anzeigen. Hat aber wie gesagt nicht geklappt.

Sei Dir bitte im Klaren
darüber, dass auf Deinem AVR kein Multitasking-OS läuft, wenn Du das
Multiplexing nicht sauber mit Interrupts löst, wird jede Programmzeile
Einfluss auf das Displaytiming und damit auf Helligkeit (bis runter zu
ganz dunkel...) haben!
Ja, ist mir schon klar. Entschuldigung nochmal wenn das gestern etwas
planlos rüber kam, ich sollte nicht kurz vorm schlafen gehen Postings
verfassen ;-)

Viele Grüße,
Johannes
 
In der momentanen Programmvariante setzt Display_Left PD0 auf "1" und
PD1 auf "0":

PIND &= ~(1<<PD1);
PIND |= (1<<PD0);
PIND sind doch die Eingänge. Um was rauszuschreiben müsstest du PORTD
verwenden. Hat das Schreiben auf PIND überhaupt einen Effekt?



--
Mfg
Thomas Pototschnig
www.oxed.de
 
Thomas Pototschnig wrote:
In der momentanen Programmvariante setzt Display_Left PD0 auf "1" und
PD1 auf "0":

PIND &= ~(1<<PD1);
PIND |= (1<<PD0);

PIND sind doch die Eingänge. Um was rauszuschreiben müsstest du PORTD
verwenden. Hat das Schreiben auf PIND überhaupt einen Effekt?
Argh, verdammt!

Ja, es hat einen Effekt. Aber einen sehr, sehr, seltsamen...

Viele Grüße und vielen Dank,
Johannes
 
Am Sat, 31 Dec 2005 13:03:43 +0100 schrieb Johannes Bauer
<dfnsonfsduifb@gmx.de>:

Thomas Pototschnig wrote:
In der momentanen Programmvariante setzt Display_Left PD0 auf "1" und
PD1 auf "0":

PIND &= ~(1<<PD1);
PIND |= (1<<PD0);

PIND sind doch die Eingänge. Um was rauszuschreiben müsstest du PORTD
verwenden. Hat das Schreiben auf PIND überhaupt einen Effekt?

Argh, verdammt!

Ja, es hat einen Effekt. Aber einen sehr, sehr, seltsamen...

Ich habe schonmal sehr seltsame Effekte beim schreiben auf Eingangspins
(Tri-State, Datenrichtung falsch gesetzt) gehabt: bei kleiner Last reicht
die Koppelkapazität im Chip, daß man abklingende RC-Pulse
(Hochpaßverhalten) am Oszi sehen konnte. Bei meinen ersten Display
Multiplex-Versuchen hatte ich auch Geisterbilder auf der Nachbarstelle.
Die kurze Zeut zw. Umschalten der Anode (Stelle) und der Segmente hat
trotz Assemblerprogramm gereicht, ein wahrnehmbares Bild zu erzeugen,
obwohl ich die Segmentmuster immer als ganzes Byte und nicht bitweise
geschrieben hatte. Die Lösung war: Zuerst die Segmentausgänge ausschalten,
dann die Stelle umschalten, dann die Segmente mit dem neuen Muster
einschalten. Braucht halt ein zwei Takt-/Maschinenzyklen mehr.
--
Martin
 
Vielleicht noch eine Erfahrung dazu:

Wenn Pins als Eingang programmiert sind, kann man durch das Beschreiben
desselben mit einer 1 eine Stromquelle aktivieren. Diese zieht den Port
dann langsam aber sicher hoch (je nach Beschaltung).
Gedacht ist das zum einsparen von Pull Up Widerständen, kann einen aber
gehörig narren.
Ganz informativ dazu sind die Datenblätter, die beschreiben die
einzelnen Pins als Blockschaltbilder.

Guten Rutsch!

Gruß
Hans
 
Hans Müller wrote:
Vielleicht noch eine Erfahrung dazu:

Wenn Pins als Eingang programmiert sind, kann man durch das Beschreiben
desselben mit einer 1 eine Stromquelle aktivieren. Diese zieht den Port
dann langsam aber sicher hoch (je nach Beschaltung).
Gedacht ist das zum einsparen von Pull Up Widerständen, kann einen aber
gehörig narren.
Das passiert aber durch beschreiben des PORTx-Registers - nicht durch
PINx. Schreiben auf PINx ist laut Datenblatt nicht definiert.


--
Mfg
Thomas Pototschnig
www.oxed.de
 
Hallo nochmal,

wollte mich nur nochmal für die freundliche Hilfe bedanken, hab jetzt
mein Gerät fertiggestellt: ist übrigens ein selbergebautes
Belichtungsgerät (im Scannergehäuse), mit coolen "deluxe" Features: kein
Stromverbrauch im Standby-Betrieb (Primärseitige Trennung), Letzte
Belichtungsvorwahl wird gespeichert, Messung der Belichtungsstärke (weil
die Röhren der Höhensonne nicht immer gleich anspringen -> immer gleiche
Belichtungsstärke) und eben die Restzeitanzeige auf den
7-Segmentanzeigen. Geht alles hervorragend! :)) Hatte eben nur mit dem
PORT/PIN ein Brett vorm Kopf.

Viele Grüße,
Johannes
 

Welcome to EDABoard.com

Sponsor

Back
Top