Forum: Mikrocontroller und Digitale Elektronik Arduino Mega 2560 und 74HC595 per SPI


von Thomas H. (thomas_h519)


Lesenswert?

Hallo!

Schaffe es leider nicht über einen Arduino Mega Schieberegister per SPI 
anzusteuern. Per shiftOut, was aber in weiterer Folge keine Option ist, 
funktioniert alles wunderbar, heißt an der Schaltung sollte es nicht 
liegen.

Danke Thomas


1
#include <SPI.h>
2
3
4
#define latch_pin 4
5
#define blank_pin 5
6
7
////Pin connected to DS of 74HC595
8
#define data_pin 51
9
10
//Pin connected to SH_CP of 74HC595
11
#define clock_pin 52
12
13
14
15
16
void setup() {
17
18
SPI.setBitOrder(MSBFIRST);//Most Significant Bit First
19
SPI.setDataMode(SPI_MODE0);// Mode 0 Rising edge of data, keep clock low
20
SPI.setClockDivider(SPI_CLOCK_DIV2);//Run the data in at 16MHz/2 - 8MHz
21
22
Serial.begin(115200);// if you need it?
23
noInterrupts();// kill interrupts until everybody is set up
24
25
26
  //set pins to output because they are addressed in the main loop
27
  pinMode(latch_pin, OUTPUT);
28
  pinMode(clock_pin, OUTPUT);
29
  pinMode(data_pin, OUTPUT);
30
  pinMode(blank_pin, OUTPUT);
31
  SPI.begin();
32
  interrupts();//let the show begin, this lets the multiplexing start
33
34
}
35
36
void loop() {
37
38
 LEDTestSPI();
39
40
}
41
42
43
void LEDTestSPI() {
44
45
46
  
47
  PORTD |= 1<<blank_pin;
48
  Serial.println("Blank Pin HIGH");
49
50
  
51
int LED0 = B00000000;
52
int LED1 = B10000000;
53
int LED2 = B01000000;
54
int LED3 = B00100000;
55
int LED4 = B00010000;
56
int LED5 = B00001000;
57
int LED6 = B00000100;
58
int LED7 = B00000010;
59
int LED8 = B00000001;
60
int LED9 = B11111111;
61
int LED10= B10101010;
62
int LED11= B01010101;
63
64
/*
65
int test =000000001010101011111111;
66
SPI.transfer(test);
67
Serial.println(test);
68
*/
69
 
70
   
71
    SPI.transfer(LED0);
72
    SPI.transfer(LED0);
73
    SPI.transfer(LED0);
74
    SPI.transfer(LED0);
75
    SPI.transfer(LED0);
76
    SPI.transfer(LED0);
77
    SPI.transfer(LED0);
78
    SPI.transfer(LED11, BIN);
79
    SPI.transfer(LED9, BIN);  //Anoden
80
    Serial.print(LED11, BIN);
81
    Serial.println(LED9, BIN);
82
83
   
84
    //return the latch pin high to signal chip that it
85
    //no longer needs to listen for information
86
    PORTD |= 1<<latch_pin;//Latch pin HIGH
87
    Serial.println("Latch Pin HIGH");
88
    PORTD &= ~(1<<blank_pin);//Blank pin LOW to turn on the LEDs with the new dataO
89
    Serial.println("Latch Pin LOW");
90
91
   
92
 // delay(50);
93
94
}

von uff basse (Gast)


Lesenswert?

Beim Latch Pin vermisse ich den Zyklus.

Ein Zyklus besteht aus einmal 1 und dann einmal 0 setzen,
oder umgekehrt, je nach Bedarf.

von uff basse (Gast)


Lesenswert?

Thomas H. schrieb:
> PORTD &= ~(1<<blank_pin);//Blank pin LOW to turn on the LEDs

Vielleicht muss es hier statt blank_pin einfach latch_pin heissen.

von uff basse (Gast)


Lesenswert?

Thomas H. schrieb:
>     SPI.transfer(LED0);
>     SPI.transfer(LED0);
>     SPI.transfer(LED0);
>     SPI.transfer(LED0);
>     SPI.transfer(LED0);
>     SPI.transfer(LED0);
>     SPI.transfer(LED0);

Ist das nicht ein bisschen sehr langweilig?

Jedenfalls braucht man ein Delay zwischen den einzelnen
SPI Transfers, sonst werden die LED-Zustände so schnell
umgeschaltet dass man nichts sieht.

von Thomas H. (thomas_h519)


Lesenswert?

Danke mal für die Tipps! Habe noch weiter recherchiert und probiert, und 
bin draufgekommen, das PORTD ....... nicht funktioniert. Wenn ich es mit 
digitalWrite HIGH bzw. LOW probiere, funktioniert es. Stimmt, LED0 ist 
nicht spektakulär, ist aber rein zu Testzwecken. Am Ende soll es ein 
8x8x8 RGB LED Cube werden wie jener von Kevin Darrah den ich als Vorbild 
genommen habe.

Leider war ich bis jetzt über den PORTx Befehl nicht erfolgreich obwohl 
ich jetzt das passende Port Mapping Schema gefunden habe.

Grundsätzlich funktioniert der Würfel jetzt das erste mal, jedoch 
flackern mir im Moment LED's die nicht angesteuert werden.

Danke Thomas

von Veit D. (devil-elec)


Lesenswert?

Hallo,

es gibt verschiedene Hersteller mit abweichenden Bezeichnungen
pinClock //  SHCP .. shift register input clock
pinLatch //  STCP .. latch or storage register clock input
pinData  //  DS .... data serial input
pinReset //  /MR ... master reset, delete shift register

OUT ... Ausgang
OFF/ON ... low/high setzen

eine saubere Init nach Controller Reset o.ä. wäre
pinReset_ON;
pinReset_OUT;
pinClock_OUT;
pinLatch_OUT;
pinData_OUT;
pinReset_OFF;  // delete shift register
pinReset_ON;
pinLatch_ON;   // take over storage register
pinLatch_OFF;

und nach dem Daten schreiben mit pinData/pinClock bzw. der transfer 
Funktion muss ein Pegelwechsel an Latch zur Datenübernahme erfolgen.
pinLatch_ON;
pinLatch_OFF;

Der Latch Pegelwechsel auf High und zurück auf Low ist praktisch das 
Gegenstück bei dem IC zum sonst üblichen CS Signal. Man kann auch erst 
Latch auf High legen, Daten übertragen und dann zurück auf Low setzen. 
Spielt hierbei keine Rolle.

: Bearbeitet durch User
von Thomas H. (thomas_h519)


Lesenswert?

Hallo Veit,

danke für die ausführliche Erklärung. Werde mich damit beschäftigen und 
versuchen diese Abfolge einzuhalten!

Danke und Gruß
Thomas

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.