Hoi zämä
Ich arbeite zur Zeit an einem Projekt, bei welchem ich ein LED Matrix
von gut 110 weissen LEDs ansteuern will. Die Steuerung übernimmt ein PIC
16F688 uP und das Treiben der LEDs MBI5026CN Bausteine, die als
Schieberegister und LED Treiber funktionieren. Die ganze Schaltung läuft
ab einem Netzteil mit 5V.
Ich habe bis jetzt drei der insgesamt sieben IC's (MBI5026CN) verbaut.
Nachdem das erste IC eingebaut war, testete ich die Schaltung und
stellte fest, dass der LED Treiber das Testmuster auf den ersten 16 LEDs
Problemlos darstellen konnte.
Als dann das zweite und dritte IC eingebaut war, stellte ich mit
erstaunen fest, dass nur jeweils das zweite IC das Testmuster
darstellte. Alle anderen LEDs blieben dunkel.
Die IC's können untereinander auf den Sockets rotiert werden, sogar wenn
ich nur auf Socket 2 und 3 ein IC platziere und die Datenverbindung vom
PIC direkt auf Nr. 2 übertrage, ist es Nr. 2, welche die LEDs zum
leuchten bringt.
Ich hab erst fehlerhafte Signalpegel oder fehlende Pullups/Pulldowns für
mögliche Ursachen gehalten. Aber nach x-fachen Kontrollen und muss ich
diese Option wohl aussschliessen. Ich hab die Signalpegel und -Zeiten
sogar mit einem KO abgelichtet und sie sehen nahezu perfekt aus.
Man sieht auf den KO Ausschnitten ebenfalls gut, dass die Daten welche
ich im ersten IC einspeise, über die Kaskadierung problemlos bis zum
letzten durchdringen. Die ICs, resp. ihre Schiebregister funktionieren
so wie sie sollten, was wiederum gegen deren Defekt und für einen
sauberen CLK spricht.
An den weissen LEDs fallen 2.6V ab. Ich hab die Eingänge der ICs auch
mal ohmisch gemessen, doch es geschieht gar nichts daran. Es macht den
Eindruck, wie wenn die ICs an Position 1 und 3 an ihren Ausgängen keinen
Wank machen. Auch habe ich mit verschiedenen Werten am externen
Einstellwiderstand Rext gespielt, doch von 500 bis 2k zeigt auch dieser
keine Wirkung auf die nicht-funktionierenden ICs (bei Nr. werden die
LEDs entsprechend der höheren Stromstärke heller).
Langsam aber sicher bin ich Ratlos, was die Ursache dieses äusserst
kuriosen Verhaltens ist. Hat evtl. jemand hier noch eine Idee, was ich
noch ausprobieren könnte?
Vielen herzlichen Dank!
Richy
Ja, der IC verfügt über Stromregler welche mit dem Rext eingestellt
werden können. Deshalb hat auch keine der LEDs Vorwiderstände.
Könnte es vielleicht auch ein Problem der Spannungen sein? An den LEDs
fallen 2.6V ab, die ganze Schaltung wird mit 5V betrieben. Der IC sollte
ja eigentlich den Rest übernehmen können, oder?
Die Software generiert eigentlich nur die Pulse, welche meines erachtens
gut aussehen (siehe KO Bilder). Aber hier der Vollständigkeitshalber
noch der Code des PICs welcher die Testmuster generiert:
DDRA=0xFF;// IIII IIII (O = Output / I = Input) SW1>Bit1 TSW>Bit4
63
DDRC=0x28;// OOIO IOOO (O = Output / I = Input) ASW>Bit4 CDL>Bit1-3
64
PORTC=0x00;
65
port_a_pullups(TRUE);
66
67
//Analog-Digital Konverter initialisieren und starten
68
// SETUP_ADC(ADC_CLOCK_DIV_4);
69
// SET_ADC_CHANNEL(7);
70
// READ_ADC(ADC_START_AND_READ);
71
72
//Clockfrequenz auf 8MHZ -> 125ns
73
setup_oscillator(OSC_8MHZ);
74
// jeden 4. Zyklus wird im Program fortgefahren + Timer inkrementiert
75
// -> 0.5us
76
77
SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1);
78
// zählt alle 0.5us eins weiter
79
80
}
81
82
83
// Gibt 16 Werte (Bit) ans Register des LED-Drivers weiter (von max 112)
84
voidset_out(int16row){
85
86
int16x;//Bit Maske
87
x=1;//Bit-Index startet bei 0000 0000 0000 0001
88
89
//Lädt die mitgegebene Reihe seriell ins Register
90
do{
91
92
//Wenn Bit an der Stelle x 0 ist:
93
if((row&x)==0){
94
D_0;//Setzt Data auf LOW
95
C_1;// und macht einen
96
C_0;// Clock Zyklus
97
}
98
//Wenn Bit an der Stelle x 1 ist:
99
else{
100
D_1;//Setzt Data auf HIGH
101
C_1;// macht einen
102
C_0;// Clock Zyklus,
103
// D_0; // und setzt Data wieder auf LOW (neutralisiert, da nicht nötig)
104
}
105
106
//Um einen Overflow zu verhindern, wird vermieden, Zahlen grösser als die Hälfte des Maximalwerts zu dublizieren.
107
if(x>0x7FFF){
108
x=0;
109
}
110
else{
111
x=x<<1;//Schiebt die Bits in x um 1 nach links
112
//x = x + x; //Verdoppelt Index-Bit 1 (wandert ein Bit höher)
113
}
114
115
}while(x!=0);
116
117
}
118
119
120
//--
121
// ClockTwo Hauptprogramm
122
//--
123
124
voidmain(){
125
126
int16s,ms,speed,timestep,d1,d2,d3;//Double
127
int8h,min;//Byte
128
129
130
sysinit();//Systeminitialisierung
131
132
133
//Data + Clock werden auf Null gesetzt, Latch auf 0 (default)
134
D_0;
135
L_0;
136
C_0;
137
138
139
// ***** Konstanten *****
140
timestep=2;//Zeitinterval [s] (min 2)
141
speed=1000;//Wieviele [ms] eine [s] hat: je kleiner, umso schneller läuft das Program ab -> Testfunktion
142
143
// ***** Variablen *****
144
h=0;//Zähler für Stunden
145
min=0;//Zähler für Minuten
146
s=0;//Zähler für Sekunden
147
ms=0;//Zähler für Millisekunden
148
d1=0xFF00;//Testdaten
149
d2=0b0011001100110011;//Testdaten
150
d3=0b0101010101010101;//Testdaten
151
152
//Setzt das Register auf Null und latched es auf die Ausgänge
153
set_out(0);
154
L_1;
155
L_0;
156
157
set_timer1(0);//Timer initialisierung
158
159
160
//bleibt in der Schleife wenn der Schalter (SW1) nicht gedrückt wird
161
while(SW1){
162
163
//*** Zeitzählmodul ***
164
165
if(get_timer1()>=2000){
166
ms++;
167
set_timer1(0);
168
//Ist Anzahl <ms> in <speed> erreicht, werden <s> inkrementiert
169
if(ms>=speed){
170
s++;
171
ms=0;
172
if(s>=60){
173
min++;
174
s=0;
175
if(min>=60){
176
h++;
177
min=0;
178
if(h>=24){
179
h=0;
180
}
181
}
182
}
183
}
184
}
185
186
187
//Wird jeden timestep ausgeführt (nach 2s)
188
if(s>=timestep){
189
s=0;
190
191
//Setzt die Werte im Register auf den aktuellen Wert und latched sie auf die Ausgänge
192
set_out(d1);
193
set_out(d2);// Sendet so 32 Bit zum testen eines weiteren Registers
194
set_out(d3);// Sendet so 48 Bit zum testen eines weiteren Registers
195
L_1;
196
L_0;
197
198
d1=~d1;//Invertiert das Testmuster
199
d2=~d2;
200
d3=~d3;
201
}
202
}
203
204
205
//Endschlaufe. Wenn 'SW1' gedrückt wird, bricht das Program ab und verweilt bis auf alle Ewigkeit hier...
206
while(1){
207
208
//Schaltet die Uhr auf dunkel
209
set_out(0);
210
L_1;
211
L_0;
212
213
}
214
215
}
Nebenbei bemerkt. Ich habe festgestellt, dasss die Einschaltungspannung
beim direkten Einstecken des 5V Netzteils bis auf 8V steigt. Unter der
Annahme, dass diese die ICs beschädigt hat, habe ich ein neue Serie
unberührter ICs eingebaut und die Schaltung mit Zuschalten der
AC-Versorgung des Netzteils "sanft" auf 5V hochgefahren.
Das Resultat ist noch verwirrender. Nun scheint das 3. IC einigermassen
(!) das Testmuster wiederzuspiegeln, während das 2. willkürlich LEDs
antreibt und das 1. ganz dunkel bleibt.
> Ich habe festgestellt, dasss die Einschaltungspannung> beim direkten Einstecken des 5V Netzteils bis auf 8V steigt.
Aus welchem Schrotthaufen stammt denn dieser Sondermuell?
Bau dir erstmal ein ordentliches Netzteil.
Das kann auch ein LM317 sein.
Bei 8 V geht sogar 74er TTL kaputt.
Nungut, damit wäre wohl ein Problemfaktor identifiziert.
Aber selbst mit einem anderen Netzteil, bei welchem ich nie mehr als 5V
beim Einschalten erhalte, habe ich selbst mit neuen IC's das oben
erwähnte, willkürliche Verhalten.
Richy schrieb:> ... selbst mit neuen IC's das oben> erwähnte, willkürliche Verhalten.
Gem. DB reagiert der IC beim Clk auf die steigende Flanke. Und das macht
mein PIC auch so (siehe Anhänge im ersten Post).
Was wäre denn am SPI falsch? Gibt es etwas was ich vielleicht falsch
interpretiere?
Richy schrieb:> //Wenn Bit an der Stelle x 0 ist:> if((row & x) == 0){> D_0; //Setzt Data auf LOW> C_1; // und macht einen> C_0; // Clock Zyklus> }> //Wenn Bit an der Stelle x 1 ist:> else{> D_1; //Setzt Data auf HIGH> C_1; // macht einen> C_0; // Clock Zyklus,> // D_0; // und setzt Data wieder auf LOW (neutralisiert, da nicht> nötig)> }
Da wird das Timing nicht passen. Mach mal nach "//Setzt Data auf"
jeweils ein, zwei NOPs.
Wie erwähnt hab' ich das Timing schon x-fach geprüft. Anbei die
ursprüngliche Ansicht des Clocks mit dem SDI am ersten IC und zus. dein
umgesetzter Vorschlag mit 2 NOP Anweisungen im Code.
Leider hat es keine Besserung im Verhalten der ICs gebracht. Aber Danke
für den Vorschlag!
Wäre es nicht möglich, dass das unstabile Netzteil einen oder mehrere
brownouts im Pic zulässt, wenn die zwei MBI5026 die Led's ein-und
ausschalten?
Brownout deaktiviere ich immer, wenns nicht gebraucht wird.
Vielleicht hilft das Probieren mit einem Akku anstatt ein schlechtes
Netzteil.
Richy schrieb:> Langsam aber sicher bin ich Ratlos, was die Ursache dieses äusserst> kuriosen Verhaltens ist. Hat evtl. jemand hier noch eine Idee, was ich> noch ausprobieren könnte?
\LE oszilloskopieren. Und zwar an jedem einzelnen 5026, jeweils direkt
am Pin. Und mit hoher Zeitauflösung, so dass man tatsächlich etwas sehen
kann.
Teo D. schrieb:> Wo her kommen den dies üblen Überschwinger in deinem CLK-Signal?
Das war wohl auf einen Messfehler meinerseits zurückzuführen. Ich habe
die GND-Verbindung der zweiten KO-Sonde vergessen. Anbei eine erneute
Clk Messung. Es sind keine Überschwinger feststellbar.
Ebenfalls habe ich das LE Signal an allen ICs inklusive im ersten
Oszillogramm die Versorungsspannung am PIC gemessen. Die Spannung sieht
bei allen ICs genau so aus. Man erkennt den Schaltvorgang, die
Pegelveränderungen sind aber noch innerhalb der Spezifikationen. Ich
bezweifle daher, dass diese schwachen veränderungen zu einem Brownout
des PIC führen können.
Ich habe den Code jetzt mal so angepasst, dass Clk und LE invertiert
ausgegeben werden (bei einer Dateneingabe wird Clk erst 0 dann wieder 1,
dasselbe bei einem Latch).
Die Schaltung zeigt aber genau das gleiche Verhalten wie oben
beschrieben: Während mit normalen Ausgängen nur das mittlere der drei
ICs scheinbar seine Aufgabe erfüllt, ist dies mit invertierten Ausgängen
genau so.
Sorry, auch das führte nicht zur erhofften Lösung des Problems. Aber
danke für den Input!
Richy schrieb:> Ich habe den Code jetzt mal so angepasst, dass Clk und LE invertiert> ausgegeben werden (bei einer Dateneingabe wird Clk erst 0 dann wieder 1,> dasselbe bei einem Latch).
Hallo,
ich habe nicht CLK oder LE gemeint, sondern nur die Dateneingabe (SDI):
anstatt 0.....15 , 15.....0 oder weil du in 3 IC's schiebst 0....47 bzw.
47....0 , einfach das Gegenteil von dem jetztigen, vielleicht hilft's
weiter, Gruss J.P.S
Richy schrieb:> Ebenfalls habe ich das LE Signal an allen ICs inklusive im ersten> Oszillogramm die Versorungsspannung am PIC gemessen. Die Spannung sieht> bei allen ICs genau so aus. Man erkennt den Schaltvorgang, die> Pegelveränderungen sind aber noch innerhalb der Spezifikationen.
Hähä. Guck mal deutlich "schneller".
Die Schulter des Pulses sieht so dermaßen Scheisse aus, dass man
ziemlich sicher davon ausgehen kann, dass da bei genauerem Hinsehen sehr
üble Sachen an der vorderen Flanke des Pulses zum Vorschein kommen
werden.
Ich würde ganz stark auf eine völlig unzureichend abgeblockte oder sogar
grundlegend unterdimensionierte Versorgung tippen.
Also, ich habe mittlerweile das Problem identifiziert und behoben.
Es ist nix kaputt gegangen und die Pulse sind auch i.O.
Meine Fehlinterpretation des Datenblattes lag darin, dass ich davon
ausging, dass der IC den Strom für die LEDs anhand einer
Referenzspannung (welche am Rext abfällt) steuert.
Offenbar scheint dieser aber die Stromregelung anhand eines
Referenzstroms (durch Rext) einzustellen. Und da ich versuchte - wie im
Schema ersichtlich - alle ICs mit einem gemeinsamen Rext zu verbinden,
führte dass dazu, dass winzige Variationen beim Rext-Ausgang des ICs
dazu führten, dass Strom von einem IC zum anderen floss, statt über den
Referenzwiderstand. Und somit war auch die Stromregelung ausser kraft
gesetzt, was zu dem von mir festgestellten merkwürdigen Verhalten
führte.
Ich habe nun für jeden IC einen eigenen Rext installiert und voila. Es
funktioniert jetzt wie geschmiert!
Aber trotzdem Danke für die Unterstützung!