Hallo,
ich sitze gerade über dem Code für die Ansteuerung einer LED Matrix.
Deren Spalten hängen an 3 aufgereiten TPIC-6B595 Schieberegistern und 5
Zeilen werden jeweils über einen PNP Gen VCC gezogen.
Die Hardware funktioniert soweit ich es sagen kann. Das heißt wenn ich
gemütlich im Code ein Bit Ausgebe und es dann durchschiebe, kann ich
jede LED einzeln ansteuern.
Da nun aber das normale shiftOut der Arduino IDE recht langsem ist und
die LEDs dadurch stark flackern, habe ich versucht einen schnelleren
Coder zu verwenden und gleich auf die Matrix zu zuschneiden.
angelehnt an den Beitrag sus dem Arduinoforum
http://forum.arduino.cc/index.php?topic=181577.15
Fom Prinzip her scheint es zu funktionieren, es gibt nur ein mir
unerklärliches Phänomen. Egal welches Bit in der Matrix gesetzt werden
soll, augegeben wird immer dieses Bit und zusätzlich noch das gleiche
Bit in den nächsten 2 Byte. Das ganze nicht nur innerhald einer Zeile,
sondern auch Zeilenübergreifend.
Wenn ich mir jetzt mit dem Oszi die Daten und Clock Signale anschaue,
sehen die sehr gut aus. Das Bitmuster passt. die Pegel sind nicht
verwaschen.
Die Schieberegister geben auch glatte Pegel aus und die zusätzlich
leuchtenden werden auch wirklich vom Schieberegister angesteuert, dass
heißt, wenn ich an deren Ausgängen alles abziehe, zum Messen einen Pull
Up mit ran halte, kommen saubere Pegel raus.
Ich kann mir das einfach nicht erklären.
Also der Code mit normal shiftOut funktioniert:
1
constintTastH=17;//Taster für Stunden
2
constintTastM=16;//Taster für Minuten
3
constintTastS=15;//Taster für Set
4
constintUHRSCL=19;//SCL zur Realtime Clock
5
constintUHRSDA=18;//SDA zur Realtime Clock
6
constintBRT=14;//Analog A0 für Helligkeitssensor
7
constintCKCLK=2;//Clock eingang von der Realtime Clock
8
constintdataPin=11;//Serial Daten Pin
9
constintLEDOE=6;//Output Enable der Schieberegister
10
constintclockPin=13;//Clock für Schieberegister
11
constintlatchPin=5;//Letch enable für die Schieberegister
#define BitMaskCLK 0b00100000 //pin 13 = Clock Pin; Pin 13 ist bit 5 von Port B
2
#define BitMaskDAT 0b00001000 //pin 11 = Data Pin; Pin 11 ist bit 3 von Port B
3
#define BitMaskLAT 0b00100000 //pin 5 = Data Pin; Pin 5 ist bit 5 von Port D
4
#define BitMaskOE 0b01000000 //pin 6 = Data Pin; Pin 6 ist bit 6 von Port D
5
#define BitMaskR1 0b00010000 //pin 4 = Data Pin; Pin 4 ist bit 4 von Port D
6
#define BitMaskR2 0b10000000 //pin 7 = Data Pin; Pin 7 ist bit 7 von Port D
7
#define BitMaskR3 0b00000001 //pin 8 = Data Pin; Pin 8 ist bit 0 von Port B
8
#define BitMaskR4 0b00000010 //pin 9 = Data Pin; Pin 9 ist bit 1 von Port B
9
#define BitMaskR5 0b00000100 //pin 10 = Data Pin; Pin 10 ist bit 2 von Port B
10
11
12
constintTastH=17;//Taster für Stunden
13
constintTastM=16;//Taster für Minuten
14
constintTastS=15;//Taster für Set
15
constintUHRSCL=19;//SCL zur Realtime Clock
16
constintUHRSDA=18;//SDA zur Realtime Clock
17
constintBRT=14;//Analog A0 für Helligkeitssensor
18
constintCKCLK=2;//Clock eingang von der Realtime Clock
19
constintdataPin=11;//Serial Daten Pin
20
constintLEDOE=6;//Output Enable der Schieberegister
21
constintclockPin=13;//Clock für Schieberegister
22
constintlatchPin=5;//Letch enable für die Schieberegister
23
constintCSEL1=4;//Reihe 1
24
constintCSEL2=7;//Reihe 2
25
constintCSEL3=8;//Reihe 3
26
constintCSEL4=9;//Reihe 4
27
constintCSEL5=10;//Reihe 5
28
constintDCF=3;//Pin für DCF Signal
29
30
byteLEDArray[5][3]={
31
{
32
B00000000,
33
B0000000,
34
B10000000
35
},
36
{
37
B00000000,
38
B00000000,
39
B00000000
40
},
41
{
42
B00000000,
43
B00000000,
44
B00000000
45
},
46
{
47
B00000000,
48
B00000000,
49
B00000000
50
},
51
{
52
B00000000,
53
B00000000,
54
B00000000
55
}
56
};
57
voidsetup(){
58
59
pinMode(latchPin,OUTPUT);
60
pinMode(dataPin,OUTPUT);
61
pinMode(clockPin,OUTPUT);
62
pinMode(LEDOE,OUTPUT);
63
pinMode(CSEL1,OUTPUT);
64
pinMode(CSEL2,OUTPUT);
65
pinMode(CSEL3,OUTPUT);
66
pinMode(CSEL4,OUTPUT);
67
pinMode(CSEL5,OUTPUT);
68
}
69
70
voidloop(){
71
for(inti=0;i<5;i++){
72
for(intj=0;j<3;j++){
73
bytebitt=1;//Variable die speichert, welches Bit wir gerade rausschreiben. Wir fangen beim LSB an.
74
while(bitt)//Wenn wir die "1" 7 mal geschoben haben, ist sie vom LSB zum MSB gewandert. Beim 8. Mal ist das Bit dann links rausgeschoben und die Variable 0. Da 0 = false wird die Schleife abgebrochen
75
{
76
if(LEDArray[i][j]&bitt)//ist das aktuelle Bit des herauszuschiebenden Wertes gesetzt?
77
PORTB|=BitMaskDAT;//ja: Datenpin HIGH
78
else
79
PORTB=(PORTB&~BitMaskDAT);//nein: Datenpin LOW. "PORT &~BitMaskDAT" gibt alle Pins so zurück wie sie waren, außer der der in BitMaskDat gesetzt ist wird 0.
80
bitt<<=1;//Schiebe die Merkervariable um eins nach links, jetzt ist das nächste Bit dran.
81
PORTB|=BitMaskCLK;// Clockpin auf High
82
PORTB^=BitMaskCLK;//Toggle den Clockpin. Da er davor HIGH war, wird er jetzt wieder LOW.
83
84
}
85
PORTD|=BitMaskOE;// OE Pin auf High
86
PORTD|=BitMaskLAT;// Latchpin auf High
87
PORTD^=BitMaskLAT;//Toggle den Latchpin. Da er davor HIGH war, wird er jetzt wieder LOW.
Manchmal sieht man den Wald vor lauter Bäumen nicht, gerade als ich den
Code nocheinmal Jemandem erklären wollte ist es mir aufgefallen.
Ich habe die Freigabe an die Pins nach jedem Byte gemacht und nicht
aller drei Byte. Also die ganze Brühe mit OE und Latch innerhalb der
Schleife mit j und nicht außerhalb.
Für die Nachwelt, wenn Jemand ein Codebeispiel für eine schnelle
Serielle Ausgabe sucht:
1
voidloop(){
2
for(inti=0;i<5;i++){
3
for(intj=0;j<3;j++){
4
bytebitt=1;//Variable die speichert, welches Bit wir gerade rausschreiben. Wir fangen beim LSB an.
5
while(bitt)//Wenn wir die "1" 7 mal geschoben haben, ist sie vom LSB zum MSB gewandert. Beim 8. Mal ist das Bit dann links rausgeschoben und die Variable 0. Da 0 = false wird die Schleife abgebrochen
6
{
7
if(LEDArray[i][j]&bitt)//ist das aktuelle Bit des herauszuschiebenden Wertes gesetzt?
8
PORTB|=BitMaskDAT;//ja: Datenpin HIGH
9
else
10
PORTB=(PORTB&~BitMaskDAT);//nein: Datenpin LOW. "PORT &~BitMaskDAT" gibt alle Pins so zurück wie sie waren, außer der der in BitMaskDat gesetzt ist wird 0.
11
bitt<<=1;//Schiebe die Merkervariable um eins nach links, jetzt ist das nächste Bit dran.
12
PORTB^=BitMaskCLK;// Clockpin auf High
13
PORTB^=BitMaskCLK;//Toggle den Clockpin. Da er davor HIGH war, wird er jetzt wieder LOW.